详细过程ubuntu下面编译openJDK8,修改源码IDEA中调试

image

阅读JDK源码最好的方式,就是编译JDK源码!然后在开发工具中用源码的方式运行,网上有很多教程,但是只有自己亲身操作过,才会知道具体是怎么样的——>纸上得来终觉浅,绝知此事要躬行👍


环境准备

ubuntu 16.04

lich@lich-virtual-machine:~/workspace$ uname -a
Linux lich-virtual-machine 5.4.0-42-generic #46-Ubuntu SMP Fri Jul 10 00:24:02 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
lich@lich-virtual-machine:~/workspace/openjdk8$ cat /proc/version
Linux version 4.15.0-45-generic (buildd@lcy01-amd64-027) (gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.10)) #48~16.04.1-Ubuntu SMP Tue Jan 29 18:03:48 UTC 2019

最开始我是用 ubuntu 20.4 版本,但是编译过程中出现了许多奇怪的错误,所以选用的低版本的ubuntu

因为主要的目的是编译源码阅读源码,不是研究版本的兼容性问题。高版本的openJDK应该是可以的,没有测试,用openjdk8比较多,所以还是想编辑openjdk8。所以最终还是选用了低版本的ubuntu。


下载openJDK8源码

两种方式:==①利用Mercurial(hg)== ==②手动下载==

利用Mercurial(hg)

openJDK使用的代码管理工具为Mercurial(hg),下载并安装Mercurial后就可以通过hg clone命令获取openJDK8的源码了,相关的命令如下:

hg clone http://hg.openjdk.java.net/jdk8u/jdk8u openjdk8u
cd openjdk
./get_source.sh

没有hg命令需要先安装:如果失败的话可能是网络的问题,在执行一次

sudo apt-get install mercurial

实际上,执行了hg clone http://hg.openjdk.java.net/jdk8u/jdk8u openjdk8u 命令以后,执行到如下所示就卡死了,不动了~ 所以还是使用下面手动下载的方式

lich@lich-virtual-machine:~/workspace$ hg clone http://hg.openjdk.java.net/jdk8u/jdk8u openjdk8u
正在请求全部修改
正在增加修改集
正在增加清单                                                                                         
正在增加文件改变                                                                                     
files [================>                                                             ]  32/142 2m50s

手动下载

下载地址:http://jdk.java.net/ 选择需要的版本,下载即可

RI Source Code

The source code of the RI binaries is available under the [GPLv2](javascript:void(0)) in a single zip file (md5) 123 MB.

下载后得到文件:openjdk-8u41-src-b04-14_jan_2020.zip

解压文件,得到文件夹openjdk ,重命名为openjdk8

unzip openjdk-8u41-src-b04-14_jan_2020.zip

编译源代码

安装BootJDK

要编译JDK你的有个基础的JDK,所以先安装个JDK,版本小于等于我们要编译的JDK,作为引导JDK

方式一:

$ sudo add-apt-repository ppa:openjdk-r/ppa
$ sudo apt update
$ sudo apt install openjdk-7-jdk

方式二:

可以自己下载jdk然后自己配置环境变量就行了。

同样在 http://jdk.java.net/ 下载JDK7注意这次不是下载源码,是编译好的JDK7

openjdk-7u75-b13-linux-x64-18_dec_2014.tar.gz 解压后重命名为openjdk7

给JDK7配置系统环境变量,切换为root

vim /etc/profile

文件末尾追加如下:注意修改为自己JDK的路径

export JAVA_HOME=/home/lich/workspace/openjdk7
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH

切换成自己的用户,配置生效

source /etc/profile

测试

lich@lich-virtual-machine:~/workspace$ java -version
java version "1.7.0_95"
OpenJDK Runtime Environment (IcedTea 2.6.4) (7u95-2.6.4-3)
OpenJDK 64-Bit Server VM (build 24.95-b01, mixed mode)

安装编译相关的依赖

看其他教程都已经把需要的依赖给列出来了,所以我们就直接安装就好了

sudo apt install \
        libx11-dev \
        libxext-dev \
        libxrender-dev \
        libxtst-dev \
        libxt-dev \
        libcups2-dev \
        libfreetype6-dev \
        libasound2-dev \
        libfontconfig1-dev

依赖检查

在源码根路径下执行如下命令,检查是否还缺少其他的依赖

bash ./configure 

比如我执行完毕后,后面会有提示,按照提示安装相关依赖即可

......
Build performance summary:
* Cores to use:   4
* Memory limit:   7934 MB
* ccache status:  not installed (consider installing)

Build performance tip: ccache gives a tremendous speedup for C++ recompilations.
You do not have ccache installed. Try installing it.
You might be able to fix this by running 'sudo apt-get install ccache'.

安装了ccache 后出现问题: ccache status: installed, but disabled (version older than 3.1.4) 。没事不影响

Build performance summary:
* Cores to use:   4
* Memory limit:   7934 MB
* ccache status:  installed, but disabled (version older than 3.1.4)

WARNING: The result of this configuration has overridden an older
configuration. You *should* run 'make clean' to make sure you get a
proper build. Failure to do so might result in strange build problems.

编译

编译前检查下

(1)设定语言选项,如果不是C那么就修改下

lich@lich-virtual-machine:~/workspace/openjdk8$ echo $LANG
zh_CN.UTF-8
修改命令:
export LANG=C

(2)执行echo $PATH

看下输出,如果没有boot JDK,则执行(注意修改为自己的路径,如果用上面打命令安装后,路径大概和我打一样)
export PATH="/usr/lib/jvm/java-7-openjdk-amd64/bin:${PATH}"

(3)检查JAVA_HOME ,可先执行echo $JAVA_HOME,看下输出,如果有值则需要unset JAVA_HOME

检查完毕后,编译使用的命令如下:

make all

相关报错:

1》编译内核问题

*** This OS is not supported: Linux lich-virtual-machine 4.15.0-45-generic #48~16.04.1-Ubuntu SMP Tue Jan 29 18:03:48 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
/home/lich/workspace/openjdk8/hotspot/make/linux/Makefile:238: recipe for target 'check_os_version' failed
make[5]: *** [check_os_version] Error 1
/home/lich/workspace/openjdk8/hotspot/make/linux/Makefile:259: recipe for target 'linux_amd64_compiler2/debug' failed

查看内核版本

lich@lich-virtual-machine:~/workspace/openjdk8$ uname -a
Linux lich-virtual-machine 4.15.0-45-generic #48~16.04.1-Ubuntu SMP Tue Jan 29 18:03:48 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

查看ubuntu版本

lich@lich-virtual-machine:~/workspace/openjdk8$ cat /proc/version
Linux version 4.15.0-45-generic (buildd@lcy01-amd64-027) (gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.10)) #48~16.04.1-Ubuntu SMP Tue Jan 29 18:03:48 UTC 2019

解决办法:

修改....../openjdk8/hotspot/make/linux/Makefile,找到SUPPORTED_OS_VERSION变量定义的地方,在后面追加4%,如下所示

SUPPORTED_OS_VERSION = 2.4% 2.5% 2.6% 3% 4%

解决完报错后,再次执行make all ,听电脑风扇一顿爆转就行了,最终如下所示:

----- Build times -------
Start 2020-07-25 10:57:00
End   2020-07-25 11:04:10
00:00:16 corba
00:00:12 demos
00:01:25 docs
00:02:48 hotspot
00:00:14 images
00:00:10 jaxp
00:00:15 jaxws
00:01:40 jdk
00:00:00 langtools
00:00:10 nashorn
00:07:10 TOTAL
-------------------------
Finished building OpenJDK for target 'all'

验证下,进入编译好的路径下 执行熟悉的 java -version

....../openjdk8/build/linux-x86_64-normal-server-release/jdk/bin

lich@lich-virtual-machine:~/workspace/openjdk8/build/linux-x86_64-normal-server-release/jdk/bin$ ./java -version
openjdk version "1.8.0-internal"
OpenJDK Runtime Environment (build 1.8.0-internal-lich_2020_07_25_10_27-b00)
OpenJDK 64-Bit Server VM (build 25.40-b25, mixed mode)

验证编译代码:

创建一个Test.java源文件,内容如下:

public class Test{   public static void main(String[] args){ System.out.println("Hello World!");}}

通过Javac编译器编译如上的源代码,得到Test.class文件,注意自己JDK的路径

/home/lich/workspace/openjdk8/build/linux-x86_64-normal-server-release/jdk/bin/javac Test.java

运行如上的Class文件,命令如下:

/home/lich/workspace/openjdk8/build/linux-x86_64-normal-server-release/jdk/bin/java Test

输出如下的信息:表示成功了

lich@lich-virtual-machine:~$ /home/lich/workspace/openjdk8/build/linux-x86_64-normal-server-release/jdk/bin/java Test

Hello World!

IDEA中使用JDK源码调试

安装IntelliJ IDEA

首先在ubuntu系统下,安装个idea

下载 https://www.jetbrains.com/idea/download/#section=linux idea

解压到opt目录

 sudo tar -zxvf ideaIU-2020.1.4.tar.gz -C /opt

然后进入bin下执行idea.sh 就行了,但是每次这么用比较麻烦,所以我们需要把idea添加到启动器

先进入到applications文件夹下

cd /usr/share/applications

添加

sudo vim idea.desktop

内容如下所示,修改为自己的idea路径

[Desktop Entry]
Encoding=UTF-8
Version=1.0
Name=IntelliJ IDEA
GenericName=Java IDE
Comment=IntelliJ IDEA is a code-centric IDE focused on developer
Exec=/opt/idea-IU-201.8743.12/bin/idea.sh
Icon=/opt/idea-IU-201.8743.12/bin/idea.png
Terminal=false
Type=Application
Categories=Development;IDE

赋予执行权限

sudo chmod +x idea.desktop

然后去软件列表找到启动器即可

使用JDK

然后在SDK中导入编译的JDK,debug配置中去掉 Before launch 中打build 然后执行测试代码

public class Main {

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

执行结果:显示用打我们编译好的JDK
/home/lich/ideaworkspace/openjdk8-normal-server-release/jdk/bin/java -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:47693,suspend=y,server=n -javaagent:/opt/idea-IU-201.8743.12/plugins/java/lib/rt/debugger-agent.jar -Dfile.encoding=UTF-8 -classpath /home/lich/ideaworkspace/openjdk8-normal-server-release/jdk/classes:/home/lich/ideaworkspace/test/out/production/test:/opt/idea-IU-201.8743.12/lib/idea_rt.jar com.org.Main
Connected to the target VM, address: '127.0.0.1:47693', transport: 'socket'
    
hello world

修改JDK源码

平时我们在查看源码打过程中,虽然可以通过DEBUG打断点来查看,但是有打时候不如加个打印输出更方便,所以我们可以修改源码,打造自己的JDK。

举个例子,比如我们要修改System.out.println增加个打印前缀

我们知道println在java.io包下,我们去修改下源码,进入我们下载打源码中,然后重新make就可以了。

我们在打印字符串打时候增加一个前缀:

 /**
     * Prints a String and then terminate the line.  This method behaves as
     * though it invokes <code>{@link #print(String)}</code> and then
     * <code>{@link #println()}</code>.
     *
     * @param x  The <code>String</code> to be printed.
     */
    public void println(String x) {
        synchronized (this) {
            print("lich:");
            print(x);
            newLine();
        }
    }

然后从新make下即可,有报错会提示,因为是增量编译,所以很快,然后再执行测试代码

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

结果:
lich:hello world

至此,入门的源码编译就结束了,纸上得来终觉浅,绝知此事要躬行👍
详细见:故事的程序员-ubuntu下面编译openJDK8,修改源码IDEA中调试

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念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