阅读 184

CentOS7下编译JDK12

CentOS7下编译JDK12

CentOS7下编译JDK12

引言

想要探究JVM的内部实现原理,最直接的方式就是编译一套自己的JDK,这样我们可以通过阅读和跟踪JDK源码来了解它的运行机理


除此之外,JDK中很多方法都是本地方法(Native),因此也可以通过这样的方式知道这些方法的运行机理


编译前的环境配置

由于在Windows下编译稍微有些麻烦,因此选择在Liunx系统上编译

系统截图如下:



gcc/g++的升级

由于该系统自带的gcc/g++版本过低(4.8.5),因此需要升级gcc/g++

这里给出一个便捷的方法:


bash> yum install centos-release-scl

bash> yum install devtoolset-9-gcc* # 注:这里9是gcc的大版本号,可以换成其他版本

bash> scl enable devtoolset-9 bash

bash> mv /usr/bin/gcc /usr/bin/gcc-4.8.5

bash> ln -s /opt/rh/devtoolset-9/root/bin/gcc /usr/bin/gcc # 替换原来的gcc

bash> mv /usr/bin/g++ /usr/bin/g++-4.8.5

bash> ln -s /opt/rh/devtoolset-9/root/bin/g++ /usr/bin/g++ # 替换原来的g++

bash> gcc --version

bash> g++ --version

1

2

3

4

5

6

7

8

9



JDK的升级

注意:要编译大版本号为N的JDK,需要另外准备大版本号至少为N-1的已编译好的JDK

笔者的yum源更新之后,JDK版本也不过是1.8,因此,我们需要准备一个JDK11


JDK11也是LTS版本,使用率仅次于1.8,因此选择12作为编译目标是比较好的


要升级JDK,首先卸载自带的JDK


bash> rpm -qa | grep java # 查看已有jdk版本

bash> yum -y remove java-1.7.0-openjdk* # 删除1.7

bash> yum -y remove java-1.8.0-openjdk* # 删除1.8

bash> java -version # 检查是否删除干净

1

2

3

4

然后,去Oracle官网下载一个JDK11,压缩包版


下载需要Oracle账号,如果没有Oracle账号,注册一个或者网上搜一个,基本上网上搜的都能用


然后安装这个JDK,笔者选择在/usr/local下放置这个JDK


bash> cd /usr/local

bash> mkdir java

bash> mv 你的压缩包路径 /usr/local/java

bash> tar zvxf xxx.tar.gz #解压

bash> gedit .bashrc

bash> source .bashrc

1

2

3

4

5

6

会熟练使用vim的可以更换gedit为vim,但是相比之下,还是gedit更亲切一些(可视化界面中)

一般来说,服务器都是只有命令行的,熟练使用vim是必不可少的技能


这里有一个坑,就是网上的教程一般会把环境变量写在/etc/profile这个文件下,但是这并不是永久有效的,想要让它永久有效,就得写在.bashrc文件中


环境变量如下:


export JAVA_HOME=/usr/local/java/jdk-11.0.10 #注意更换为你自己的版本

export PATH=$JAVA_HOME/bin:$PATH

1

2

编译

首先需要获取源码,这里选择的是OpenJDK12,下面是笔者的百度网盘下载链接:


链接: https://pan.baidu.com/s/1LOT2VUgWK52gE00w1vDi0w 提取码: bwtx 复制这段内容后打开百度网盘手机App,操作更方便哦

1

注意:下载完解压的路径不要有中文,否则编译到一半会报错(笔者亲历)


cd到解压目录下,切换为root用户,就可以开始编译了


bash> bash configure

1

运行该命令,会检查你的环境是否配置好


笔者初次运行时有部分依赖没有安装,该命令会提示你去安装这些包,并且给出了具体的安装命令(还会根据Linux发行版的不同而给出不同的命令),需要多次运行该命令


最后,使用如下命令即可开始编译:


bash> make clean

bash> make images

1

2

但是,这样做会在编译期遇到错误:


/home/wzy/OpenJdk12/src/hotspot/share/runtime/arguments.cpp: In static member function ‘static jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs*, bool*, JVMFlag::Flags)’:

/home/wzy/OpenJdk12/src/hotspot/share/runtime/arguments.cpp:2472:29: error: ‘char* strncpy(char*, const char*, size_t)’ output truncated before terminating nul copying as many bytes from a string as its length [-Werror=stringop-truncation]

         char* name = strncpy(NEW_C_HEAP_ARRAY(char, len + 1, mtArguments), tail, len);

                      ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

/home/wzy/OpenJdk12/src/hotspot/share/runtime/arguments.cpp:2471:44: note: length computed here

         size_t len = (pos == NULL) ? strlen(tail) : pos - tail;

                                      ~~~~~~^~~~~~

cc1plus: all warnings being treated as errors

1

2

3

4

5

6

7

8

出现这种错误的原因是gcc版本太高,gcc对这些行为进行了警告,为了继续编译,需要重新指定configure选项,忽略这些警告


这种特性从gcc8开始,如果你是更早的符合要求的gcc,可能不会出现这样的问题


bash> make clean

bash> make dist-clean

bash> bash configure --disable-warnings-as-errors

bash> make images

1

2

3

4


当出现上图的情况时,说明已编译结束,编译的产物在build文件夹下,其名字在上图中已有提示,即’linux-x86_64-server-release’


在这个文件夹中,有名为jdk的文件夹,cd进去,结构如下:


这就是我们熟悉的jdk的目录,使用下面的命令查看该jdk的版本:


bash> ./bin/java -version

openjdk version "12.0.2-internal" 2019-07-16

OpenJDK Runtime Environment (build 12.0.2-internal+0-adhoc.wzy.OpenJDK12)

OpenJDK 64-Bit Server VM (build 12.0.2-internal+0-adhoc.wzy.OpenJDK12, mixed mode)

1

2

3

4

这样编译就结束了


使用CLion查看并调试源码

要使用CLion查看并调试,需要在编译之前的bash configure命令后加一个参数,完整命令如下:


bash> bash configure --enable-debug --with-jvm-variants=server --disable-warnings-as-errors

1

然后,在OpenJDK12,也就是根目录中,创建CMakeLists.txt:


cmake_minimum_required(VERSION 3.7)

project(hotspot)

include_directories(

src/hotspot/cpu

src/hotspot/os

src/hotspot/os_cpu

src/hotspot/share

src/hotspot/share/precompiled

src/hotspot/share/include

src/java.base/unix/native/include

src/java.base/share/native/include

src/java.base/share/native/libjli

)

file(GLOB_RECURSE SOURCE_FILES "*.cpp" "*.hpp" "*.c" "*.h")

add_executable(hotspot ${SOURCE_FILES})

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

在CLion中,选择OpenJDK12根目录下的CMakeList.txt,选择作为项目打开即可:


src/java.base/share/native/libjli/java.c的JavaMain函数就是HotSpot虚拟机的入口,我们可以设置一个断点:



在运行之前,还需要做一件事,就是写一个Java程序并编译成class文件在jdk的bin目录下:



public class Hello {

public static void main(String[] args) {

System.out.println("Hello World!");

}

}

1

2

3

4

5

然后,在CLion运行配置中选择CMake应用程序,配置如下:


点击确定后,选择调试启动,最后结果如下:



这里省略了几个断点的结果

————————————————

版权声明:本文为CSDN博主「半夏鸢尾丶」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/banxia__/article/details/114701748


文章分类
后端
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐