作 Java 开发的你,有编译过本身的 JDK 玩玩儿吗

我是风筝,公众号「古时的风筝」,一个不仅有技术的技术公众号,一个在程序圈混迹多年,主业 Java,另外 Python、React 也玩儿的 6 的斜杠开发者。 Spring Cloud 系列文章已经完成,能够到 个人github 上查看系列完整内容。也能够在公众号内回复「pdf」获取我精心制做的 pdf 版完整教程。html

你天天写的 Java 代码都须要 JDK 的支持,都要跑在 JVM 上,难道你就很差奇 JDK 长什么样子吗。好奇,就来编译并实现一个本身的 JDK 吧。java

本次编译环境 macOS 10.12,编译的是 JDK 11 版本。git

安装 OpenJDK 11

编译 OpenJDK 须要先在机器上安装 OpenJDK 10 或者 OpenJDK 11,做为 Boot JDK。 先安装 openJDK 11 编译须要,能够到 adoptopenjdk 网站去下载。github

pkg 格式安装spring

进入页面 https://adoptopenjdk.net/index.html?variant=openjdk11&jvmVariant=hotspot 直接下载下载,而后双击就能够完成安装了。shell

tar.gz 格式安装macos

一、进入页面 https://adoptopenjdk.net/installation.html?variant=openjdk11&jvmVariant=hotspot#x64_mac-jdk 下载 tar.gz 包xcode

二、解压bash

tar -xf OpenJDK11U-jdk_x64_mac_hotspot_11.0.5_10.tar.gz

解压后是一个 macOS 包,可经过右键->显示包内容查看里面的文件。微信

三、加入环境变量 PATH 中,固然若是你使用其余版本的 JDK 做为开发使用,请忽略这一步。

export PATH=$PWD/jdk-11.0.5+10/Contents/Home/bin:$PATH

四、macOS JDK 默认目录在/Library/Java/JavaVirtualMachines,把第 2 步解压的内容放到此目录下,以后编译的过程当中会在这个目录下查找 JDK 10 或 JDK 11。

下面是我本地的目录结构,有 7 、八、11 这三个版本,开发时候仍是默认使用 8 的。

安装 xcode

实际上咱们须要的不是 xcode,而是 LLVM 的编译命令 clang。固然你能够单独安装 LLVM,但限于此篇是写给 Java 开发者的,安装 xcode 是最简单的版本。

我本地是很早以前安装的 xcode 8.1,编译起来是没问题的,若是你用的是比较新的版本,应该也不会出现什么问题,能够亲自试一试。

开始编译

一、下载 OpenJDK 11 源码

OpenJDK 的源码放在了网站 http://hg.openjdk.java.net/ 上,咱们要下载的 JDK11 目录在 http://hg.openjdk.java.net/jdk-updates/jdk11u/。

进入页面后,先点击左侧的 browse,再选择一种压缩格式下载。

固然还能够用 hg 命令 clone 到本地,使用 hg 须要安装 mercurial,若是网速很差或者不稳定,建议不要使用这种方式。

hg clone https://hg.openjdk.java.net/jdk/jdk11/

二、解压源码包

将你刚刚下载的压缩包解压,请解压到一个全英文目录下,不要使用中文,减小编译时带来的麻烦。

三、configure

进入上一步解压后的目录,执行以下命令。

sh configure --with-target-bits=64 --enable-ccache --with-jvm-variants=server  --with-boot-jdk-jvmargs="-Xlint:deprecation -Xlint:unchecked" --disable-warnings-as-errors --with-debug-level=slowdebug 2>&1 | tee configure_mac_x64.log

执行这个命令的前提是我已经将 OpenJDK 11 放到了 /Library/Java/JavaVirtualMachines目录下。

若是不放到这个目录下,也是能够的,须要额外指定参数

--with-boot-jdk=OpenJDK 目录

若是出现以下输出,说明这一步就正常了。

四、make

正式开始编译了,使用 make 命令便可。

make

首次编译会比较慢,个人是 MacBook Pro i5 8G 的那款,大概编译了 10 几分钟吧。当出现以下输出的时候,说明编译成功。

Finished building target 'default (exploded-image)' in configuration 'macosx-x86_64-normal-server-slowdebug'

编译好以后,会在当前目录出现 build 目录,进去以后,看到有个 macosx-x86_64-normal-server-slowdebug 就是最终的目录。

IDEA 中配置使用编译好的 JDK

一、打开 IDEA ,找到 File->Project Structure。

二、添加一个 JDK

三、选择上面源码编译好的 jdk

四、最后启动项目的时候指定这个 JDK 就能够了。

用 CLion 调试

一、打开 CLion ,导入项目,选择下载的源码所在位置的 src 目录。

二、配置 Debug Configurations,选择 Executable 为编译好的 java 可执行程序,在 bin 目录下,而且移除 Build 设置。

Program arguments 设置为 -version,也能够设置其余的。设置为 -version 的意思是 java -version。

三、最后在源码中打个断点,好比 jni.cpp 或 thread.cpp 中,而后点击 debug ,就能够调试啦。

打造本身的 JDK

标题说的有点儿悬,打造本身的 JDK 哪儿有那么容易,何况还确实没那个实力。这里就是介绍一种思路,好比有些时候,咱们调试 Java 代码最后发现走到了 JVM 层,这种状况下,咱们就跟不进去了。执行到 JVM 层以后,里面的各类变量是怎么变换的咱们就不知道了。这时候,咱们找到 JVM 对应的代码稍微改一下,好比加个 printf 输出一下参数值就能够清晰的看出来了。

修改 JDK 代码

我在打开的 CLion 中找到了 java.c 文件的 JavaMain(void * _args) 方法,在里面加了一行打印代码,就勉强算实现了本身的 JDK 吧(微笑脸)。

万里长征第一步嘛,别的不重要,留下脚印儿才是关键。

printf("古时的风筝 JDK \n");

从新编译修改后的源码

修改以后,在终端中进入到源码目录的根目录,而后执行 make 命令。

由于以前已经编译过了,因此再次执行 make 是进行的增量编译,因此速度很快。

好了,见证奇迹的时刻到了

咱们以前已经在 IDEA 中添加了编译好的 JDK,而且指定给了一个项目。仅为测试,代码以下。

public static void main(String[] args){
    System.out.println("hello jvm");
}

当咱们运行这个项目的时候,若是是日常的 JDK,会在控制台输出 hello jvm ,对不对。

但是,如今指定的不是日常的 JDK ,是被我加持过的 JDK 。

开始运行,输出的结果以下,看到没,刚刚加上的那行代码起做用了。

风筝说

真正能作到 JDK 定制开发的人并很少,我也彻底没这个实力。可是每一个 Java 开发者都编译一下 JDK 源码,翻一翻代码仍是颇有必要的。毕竟,咱们天天写的代码都须要 JDK 的支持,都要跑在 JVM 上,咱们就很差奇它们长成什么模样吗。

另外,这也可能为咱们平常解决问题提供一种思路。有人说,最好的老师就是搜索引擎,大多数状况下是没错,但有的时候最好的方式每每就是看一眼源码。

为何有的人解决问题的速度快,有些看似不能解决的问题放到大牛手里就能很快解决。有时候就是解决问题的维度不同,人家是在三维的世界里,你却一直在二维的平面里转圈圈,比方说遇到程序问题,只能分析 Java 层面的问题这就是二维,进到 JDK、JVM 源码那就是进到的三维。维度高了,角度变了,解决问题的可能性和方式也就多了。这就比如三体里高等文明利用二向箔进行打击,彻底不在一个体量下。

赶忙行动吧,编译一个你本身的 JDK。

我是风筝,公众号「古时的风筝」,一个在程序圈混迹多年,主业 Java,另外 Python、React 也玩儿的很 6 的斜杠开发者。能够在公众号中加我好友,进群里小伙伴交流学习,好多大厂的同窗也在群内呦。

技术交流还能够加群或者直接加我微信。

相关文章
相关标签/搜索