参考原文html
JAVA 11 是 JAVA 8 以后的第一个 LTS 版本,为了了解下一代 JAVA 版本更新的内容,也为了能调试到 JAVA 的内部代码,因此笔者决定源码安装试试。java
官方给出的安装教程[1]是这样的:shell
hg clone http://hg.openjdk.java.net/jdk/jdk
bash configure
。缺失依赖会致使 configure 失败,但错误日志都会给出操做建议,根据建议安装依赖便可make images
./build/*/images/jdk/bin/java -version
make run-test-tier1
这个安装步骤大致上没问题,可是有些差别须要指出,所以我也给出个人安装步骤。macos
安装 jre 11 运行时,这个能够经过 brew 来安装,或者直接下载 oracle 或 openjdk。xcode
由于编译的是比较新的 jdk 11,直接用 xcode 最新版便可(官方推荐的是 9.4,我用的是最新版 10.3 没问题)。bash
经过 brew 安装 autoconf 和 freetype。oracle
从 jdk 10 开始,源码再也不分散在不一样的仓库中,因此只须要 clone 单独的 repository 便可[1:1]。我选择是 jdk11u,并且不是经过 hg clone 的方式(比较慢,常常出错须要重试),而是直接下载整个源码包,以下图示。jvm
执行 configure,为了 debug,须要加上对应的参数。ide
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
复制代码
通常第一次执行老是会遇到些小问题,但编译 jdk 11 的问题比 jdk8,9少多了,根据提示很容易就能够解决。当看到以下返回即代表配置成功。模块化
====================================================
A new configuration has been successfully created in
/Users/haidao/Downloads/openjdk11/build/macosx-x86_64-normal-server-slowdebug
using configure arguments '--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'.
Configuration summary:
* Debug level: slowdebug
* HS debug level: debug
* JVM variants: server
* JVM features: server: 'aot cds cmsgc compiler1 compiler2 dtrace epsilongc g1gc graal jfr jni-check jvmci jvmti management nmt parallelgc serialgc services vm-structs'
* OpenJDK target: OS: macosx, CPU architecture: x86, address length: 64
* Version string: 11-internal+0-adhoc.haidao.openjdk11 (11-internal)
Tools summary:
* Boot JDK: openjdk version "11.0.2" 2019-01-15 OpenJDK Runtime Environment 18.9 (build 11.0.2+9) OpenJDK 64-Bit Server VM 18.9 (build 11.0.2+9, mixed mode) (at /Library/Java/JavaVirtualMachines/openjdk-11.0.2.jdk/Contents/Home)
* Toolchain: clang (clang/LLVM from Xcode 10.3)
* C Compiler: Version 10.0.1 (at /usr/bin/clang)
* C++ Compiler: Version 10.0.1 (at /usr/bin/clang++)
Build performance summary:
* Cores to use: 4
* Memory limit: 8192 MB
* ccache status: Active (3.7.2)
复制代码
而后执行 make 便可。根据 build 文档[1:2],执行 make 不带任何参数等同于make default
和make jdk
,这会 build 出一个较小的编译结果,并提供一个 exploded image。不知道怎么翻译 exploded image,大概意思是,这是一个分解开的镜像,能够直接使用,各个模块都是解压好的,不包含源码。这种设计是为了方便 jdk 的开发者渐进式开发,每次 make 只会 recompile 变化的部分。
其余 make 的经常使用 target 以下:
hotspot
- Build all of hotspot (but only hotspot)hotspot-<variant>
- Build just the specified jvm variantimages
or product-images
- Build the JDK imagedocs
or docs-image
- Build the documentation imagetest-image
- Build the test imageall
or all-images
- Build all images (product, docs and test)bootcycle-images
- Build images twice, second time with newly built JDK (good for testing)clean
- Remove all files generated by make, but not those generated by configuredist-clean
- Remove all files, including configuration咱们以 $BUILD 表示构建结果目录[2],构建结果目录以下[1:3]:
jdk
: 这就是以前所说的 exploded image 的目录。执行make jdk
以后,你能够经过运行$BUILD/jdk/bin/java
直接启动新构建的 JDK。images
: 这个目录是 make *-image 的输出位置。例如,make jdk-image
会构建出 jdk image, 目录是images/jdk
。test-results
: 测试结果目录。support
: 这个目录保存的是 build 过程当中的中间文件,好比源码,对象文件,类文件等。support
中比较重要的是gensrc
,它包含生成的源码;modules_*
包含了按模块层级分布的文件,它会在以后合并到 jdk 目录下。因为咱们执行的是最简构建,咱们主要看下 $BUILD/jdk 和 $BUILD/images/jdk 的差别:
$BUILD/images/jdk $BUILD/jdk
├── bin ├── _packages_attribute.done
├── conf ├── bin
├── demo ├── conf
├── include ├── include
├── jmods ├── lib
├── legal ├── modules
├── lib └── release
├── man
└── release
复制代码
和 $BUILD/jdk 不同,$BUILD/images/jdk 这个目录下没有解压好的 modules 目录,而是以压缩包的形式放在 jmods 下。这是自 JAVA 9 引入的模块化打包设计,旨在减少 JAVA 应用的包体积,使得部署更加轻量。
$BUILD/jdk 下的 lib 目录是动态库文件和调试信息文件,不包含源码。而 $BUILD/images/jdk 下的 lib 目录下的动态库文件没有可执行权限,但包含源码 src.zip。
$BUILD/jdk 做为 exploded image,不像 product-image 那样须要包含法律文件和 demo。
除了这些区别以外,两者在使用上没啥差异。
如今,能够直接经过 $BUILD/jdk/bin/java 来使用编译出来的 JAVA11。你也能够配置 jenv:jenv add $BUILD/jdk
。关于 jenv 的使用请参看 Mac OS 使用 jenv 管理 java 版本。
增长 SDK,配置 classpath 和 sourcepath。配置好 sourcepath 即可以正常查看代码了。
若是使用的是 $BUILD/images/jdk,直接将该目录加入到 classpath 便可,IDE 会自动识别 src.zip 并放在 sourcepath 中;
若是使用的是 $BUILD/jdk,因为这是 exploded image jdk,不包含源码,因此须要分别加入 classpath 和 sourcepath,sourcepath 即下载的 openjdk 下的 src 目录。
其余须要修改的配置不在赘述,以下图示。
在 IDE sdk 中配置好 jdk 11 以后即可以正常调试 JAVA 代码了。若是咱们想调试 jdk/jvm 源码的 C 代码怎么办呢?咱们已经 build 一个能够 debug 的 java11 运行环境,下面就是配置 IDE 来 debug。
首先导入源码。使用 New Cmake Project from Sources,这样能够自动建立 CMakeLists.txt 文件。而后按照引导便可导入源码。你能够导入 src/hotspot,也能够整个导入 src。
导入以后,具体的 cpp 文件会报错,可是不影响调试,能够暂时忽略。
导入成功,reload CMakeLists.txt 以后,会自动生成一个 debug configuration。下面配置 debug configuration。如图所示,将 executable 改成你的 java 二进制文件,而后在 program arguments 里设置程序参数。咱们先设置为 -version。
此时咱们在share/prims/jni.cpp
文件上打一个断点,而后执行 debug,就能够看到效果了。