做 Java 这么久了,你编译过 JDK 源码吗(转)

你每天写的 Java 代码都需要 JDK 的支持,都要跑在 JVM 上,难道你就不好奇 JDK 长什么样子吗。好奇,就来编译并实现一个自己的 JDK 吧。

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

安装 OpenJDK 11

编译 OpenJDK 需要先在机器上安装 OpenJDK 10 或者 OpenJDK 11,作为 Boot JDK。 先安装 openJDK 11 编译需要,可以到 adoptopenjdk 网站去下载。

pkg 格式安装

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

tar.gz 格式安装

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

2、解压

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

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

3、加入环境变量 PATH 中,当然如果你使用其他版本的 JDK 作为开发使用,请忽略这一步。

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

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

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

image

安装 xcode

实际上我们需要的不是 xcode,而是 LLVM 的编译命令 clang。当然你可以单独安装 LLVM,但限于此篇是写给 Java 开发者的,安装 xcode 是最简单的版本。

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

开始编译

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/

2、解压源码包

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

3、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 目录

如果出现如下输出,说明这一步就正常了。

image

4、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

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

image

2、添加一个 JDK

image

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

image

4、最后启动项目的时候指定这个 JDK 就可以了。

用 CLion 调试

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

image

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

Program arguments 设置为 -version,也可以设置其他的。设置为 -version 的意思是 java -version。

3、最后在源码中打个断点,比如 jni.cpp 或 thread.cpp 中,然后点击 debug ,就可以调试啦。

打造自己的 JDK

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

修改 JDK 代码

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

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

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

重新编译修改后的源码

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

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

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

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

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

当我们运行这个项目的时候,如果是平常的 JDK,会在控制台输出 hello jvm ,对不对。

可是,现在指定的不是平常的 JDK ,是被我加持过的 JDK 。

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

image

风筝说

真正能做到 JDK 定制开发的人并不多,我也完全没这个实力。但是每个 Java 开发者都编译一下 JDK 源码,翻一翻代码还是很有必要的。毕竟,我们每天写的代码都需要 JDK 的支持,都要跑在 JVM 上,我们就不好奇它们长成什么模样吗。

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

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

赶紧行动吧,编译一个你自己的 JDK。

参考引用:
[1]: https://zhuanlan.zhihu.com/p/101402297?from_voters_page=true

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342