JAVA 11 MAC 源码安装与调试

参考原文html

JAVA 11 是 JAVA 8 以后的第一个 LTS 版本,为了了解下一代 JAVA 版本更新的内容,也为了能调试到 JAVA 的内部代码,因此笔者决定源码安装试试。java

安装

官方给出的安装教程[1]是这样的:shell

  1. 下载源码:hg clone http://hg.openjdk.java.net/jdk/jdk
  2. 执行configure:bash configure。缺失依赖会致使 configure 失败,但错误日志都会给出操做建议,根据建议安装依赖便可
  3. 执行 make:make images
  4. 验证新构建的 java 可用:./build/*/images/jdk/bin/java -version
  5. 测试:make run-test-tier1

这个安装步骤大致上没问题,可是有些差别须要指出,所以我也给出个人安装步骤。macos

安装依赖

安装 jre 11 运行时,这个能够经过 brew 来安装,或者直接下载 oracleopenjdkxcode

由于编译的是比较新的 jdk 11,直接用 xcode 最新版便可(官方推荐的是 9.4,我用的是最新版 10.3 没问题)。bash

经过 brew 安装 autoconf 和 freetype。oracle

获取源码

从 jdk 10 开始,源码再也不分散在不一样的仓库中,因此只须要 clone 单独的 repository 便可[1:1]。我选择是 jdk11u,并且不是经过 hg clone 的方式(比较慢,常常出错须要重试),而是直接下载整个源码包,以下图示。jvm

jdk11 download
jdk11 download

编译

执行 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 defaultmake 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 variant
  • images or product-images - Build the JDK image
  • docs or docs-image - Build the documentation image
  • test-image - Build the test image
  • all 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 configure
  • dist-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 版本

配置 IDEA

增长 SDK,配置 classpath 和 sourcepath。配置好 sourcepath 即可以正常查看代码了。

jdk11 classpath
jdk11 classpath

若是使用的是 $BUILD/images/jdk,直接将该目录加入到 classpath 便可,IDE 会自动识别 src.zip 并放在 sourcepath 中;

若是使用的是 $BUILD/jdk,因为这是 exploded image jdk,不包含源码,因此须要分别加入 classpath 和 sourcepath,sourcepath 即下载的 openjdk 下的 src 目录。

jdk11 sourcepath
jdk11 sourcepath

其余须要修改的配置不在赘述,以下图示。

jdk11 ide conf
jdk11 ide conf

配置调试

在 IDE sdk 中配置好 jdk 11 以后即可以正常调试 JAVA 代码了。若是咱们想调试 jdk/jvm 源码的 C 代码怎么办呢?咱们已经 build 一个能够 debug 的 java11 运行环境,下面就是配置 IDE 来 debug。

clion 调试 jvm 代码

首先导入源码。使用 New Cmake Project from Sources,这样能够自动建立 CMakeLists.txt 文件。而后按照引导便可导入源码。你能够导入 src/hotspot,也能够整个导入 src。

clion debug jvm
clion debug jvm

导入以后,具体的 cpp 文件会报错,可是不影响调试,能够暂时忽略。

导入成功,reload CMakeLists.txt 以后,会自动生成一个 debug configuration。下面配置 debug configuration。如图所示,将 executable 改成你的 java 二进制文件,而后在 program arguments 里设置程序参数。咱们先设置为 -version。

jdk11 debug1
jdk11 debug1

此时咱们在share/prims/jni.cpp文件上打一个断点,而后执行 debug,就能够看到效果了。

jdk11 debug2
jdk11 debug2


  1. 每一个下载的 jdk 中都有一个 build 文档,通常在 doc 目录下。这是编译安装该 jdk 的最权威的参考文档。jdk11 的在线 build 文档是:Building the JDK 11 ↩︎ ↩︎ ↩︎ ↩︎

  2. $BUILD 表示你构建出来的结果的目录,通常是你下载的 openjdk11 下的 build/xxx,xxx 是一个动态的名称,和你的开发机类型、编译参数有关,在个人机器上是 ./openjdk11/build/macosx-x86_64-normal-server-slowdebug。 ↩︎

相关文章
相关标签/搜索