前言
这是一段相当痛苦的过程。逐次记录如下。
因为有时候排查问题如果更深层次, 不可避免的需要从JDK源码入手。此时如果能从源码动点手脚那是极好的。但是在mac环境build远远要比linux环境预想的要麻烦。
HG(Mercurial)
hg clone http://hg.openjdk.java.net/jdk9/jdk9
sh get_source.sh
使用HG从openjdk去下载源码。这是万事的第一步。但是这里就遇到了问题。下载速度实在是太鸡儿慢了。家庭网络速度下载大概在5kb/s。公司内外下载速度能到100kb/s, 但是经常会出现莫名其妙的错误。
你可能会看到这样的报错:
jaxp: transaction abort!
jaxp: rollback completed
jaxp: abort: stream ended unexpectedly (got 33981 bytes, expected 44934)
或者这样
jaxws: transaction abort!
jaxws: rollback completed
jaxws: abort: HTTP request error (incomplete response)
jaxws: (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
所以此时不建议使用mercurial去下载(其实本身速度并不慢, 我尝试用洛杉矶的vps去下载速度可到1M/s)。网上早有人有类似的需求, 将不同版本的源码放在了github。可参考如下两个地址。
https://github.com/unofficial-openjdk/openjdk/
https://github.com/dmlloyd/openjdk
当然git获取也有可能失败。那只能多尝试几次碰碰运气了。
$ git clone https://github.com/dmlloyd/openjdk.git
Cloning into 'openjdk'...
remote: Counting objects: 1205936, done.
remote: Compressing objects: 100% (4192/4192), done.
error: RPC failed; curl 56 LibreSSL SSL_read: SSL_ERROR_SYSCALL, errno
54
fatal: The remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed
$ git clone https://github.com/dmlloyd/openjdk.git
Cloning into 'openjdk'...
remote: Counting objects: 1205936, done.
remote: Compressing objects: 100% (4192/4192), done.
error: RPC failed; curl 18 transfer closed with outstanding read data remaining
fatal: The remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed
$ git clone https://github.com/dmlloyd/openjdk.git
Cloning into 'openjdk'...
remote: Counting objects: 1205936, done.
remote: Compressing objects: 100% (4192/4192), done.
error: RPC failed; curl 56 LibreSSL SSL_read: SSL_ERROR_SYSCALL, errno 60
fatal: The remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed
freetype
brew install freetype
参见维基百科: FreeType是一个用C语言实现的一个字体光栅化库。它可以用来将字符栅格化并映射成位图以及提供其他字体相关业务的支持。
X11
[https://www.xquartz.org/](https://www.xquartz.org/)
和UI界面有关, build需要引入, 不做赘述。
configure阶段
这里开始configure。
sh configure --with-debug-level=slowdebug --disable-warnings-as-errors --with-freetype-include=/usr/local/Cellar/freetype/2.9.1/include/freetype2 --with-freetype-lib=/usr/local/Cellar/freetype/2.9.1/lib --with-boot-jdk=/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home --with-target-bits=64
这里稍微解释下:
--disable-warnings-as-errors: 不认为告警是错误
--with-freetype***:指定字体库相关地址
--with-boot-jdk: 指定bootjdk。鸡生蛋蛋生鸡。
一切顺利的话这里会生成:
OK。看到这里configure阶段完成。下一步准备make。
语法
JDK9的build需要稍微需改下源文件的三处地方, 这里不多说了, 参考前人趟的坑即可。 点我点我点我
Make
先描述下本机的一些配置。
BOOT-JDK: 1.8.0_161
XCode: 9.4
OS: Mojave(10.14)
第一个坑。不要乱升级XCode。下载地址
对于非Apple Developer来说, XCode有个很坑爹的事情, 就是他升级到高版本后, 无法回退到低版本。如果要重新安装低版本, 需要Apple Developer账号去下载。而且XCode的安装包要5G, 解压后分分钟10个G。
第二个坑。XCode升级到10之后, 删除了底层目录下的libstdc++文件。导致在JDK的Make时会报错, 无法识别<new>类似这样的C++语法。而在XCode9时对应文件还是存在的。官方给出的意思是libstdc++已经被标记为过期5年了, 现在统一使用自己libc++。这个问题最简单的问题就是XCode版本回退到9之前即可。
第三个坑。OpenJDK的build的官方README说建议XCode版本为8.3.2。我按照要求回退到该版本, 却发现该版本和 Mojave(10.14) 不兼容。XCode打开一闪而过。同时在安装目录下发现了不兼容导致的crash文件。无奈重新把版本拉到XCode9。
OK, 搞定了3个坑货。现在开始Make:
make all
正常来讲这里经过15分钟左右就好了, 但是我在这里遇到了迄今为止最头痛的bug, JVM...crash了???
问题截图如下:
更细节的错误描述如下:
siginfo: si_signo: 4 (SIGILL), si_code: 1 (ILL_ILLOPC), si_addr: 0x000000010c14b458
在这里困了很久。搜到了有人给官方 提交的bug, 但是官方和客气啊说我们不管这种slowdebug的问题的, 有疑问你去openjdk的mailinglist去问问? 没搜到之后, 我去stackoverflow发了个贴。 无人响应。这特么就很尴尬了啊。
一番猜测后我们有了以下结论和尝试:
- 代码最后停留在native栈的 V [libjvm.dylib+0xd4b458] PerfData::~PerfData()+0x8。和PerfData有关, 而PerfData是存储jvm的一些采样监控数据的, 比如jstat。
- 最后停留的函数是析构函数, 属于资源释放环节。
- 打开PerfDataManager看到这部分的源码长这样:
考虑到本身PerfDataManager就是个采样环节, 所以这里直接尝试把该处代码注释掉, 就像这样。
再次重新make, 老泪纵横, 终于通过了。
----- Build times -------
Start 2019-03-02 00:53:13
End 2019-03-02 01:00:44
00:07:31 TOTAL
-------------------------
Finished building target 'all' in configuration 'macosx-x86_64-normal-server-
slowdebug'
新build出来的jdk在images/jdk目录下, 尝试配置到ide下试试看:
OK。希望此文对于在macos下的各位有帮助。