您的位置:首页 > 编程语言 > Java开发

如何在Eclipse下编译JDK源代码,以及JDK源码调试

2017-08-20 15:27 225 查看

作为一名JAVA程序员,在日常工作中必然会涉及到对代码进行调试跟踪。例如调试跟踪Spring 框架,第三方提供的API(如支付宝API,推送API等等)。我们在跟踪这些框架的源代码的时候,可以看到调试信息,用于帮助我们解决问题,或者帮助我们理解框架。

但是JDK源码的调试跟踪就没有那么的方便了,Oracle在对JDK进行编译的时候,去掉了调试信息(javac -g:none),所以我们在调试JDK源码的时候,根本就看不到局部变量以及变量的值,所以即使调试也只能看一下语句的执行过程而已,并不能提供太多的帮助。如下图所示:

图1:无法查看调试信息


那么怎样才能看到调度信息呢,那就需要对JDK源码进行重新编译了。下面是具体的操作步骤以及一些注意事项。

 

1、rt.jar与src.zip对比

首先找到我们的JDK安装目录下的src.zip以及jre/lib下的rt.jar,我的JDK安装在D盘,大家找到自己的实际安装目录。我们先对这两个文件进行一下比较,可以把这两个文件复制到一个临时目录,并解压缩,可以用7zip或者rar 打开。我们暂时挑选几个目录,根目录,com目录以及com\sun目录,下面是对比结果:



 

 

 

左则是rt.jar包含的内容,右则是src.zip包含的内容。通过对比我们可以看出,实际上我们安装完JDK后,安装目录下的源代码实际上只是包含了部分代码,当然我们在日常开发中,也只需要用到这一部分代码。rt.jar 中其它多出来的那部分代码是JDK的依赖库。在接下来的编译中,会涉及相关的代码。

 

2、修改Eclipse默认的JRE

对比完src.zip和rt.jar,我们就来正式开始我们的编译工作。首先大家先检查一下Eclipse的默认已安装的JRE配置,我本机的JDK和JRE是安装在D:\JAVA目录,那么默认情况下Eclipse会引用JRE,如下图所示:



 我们先将这个JRE Remove,然后添加JDK,JRE Home 选择JDK的安装目录



 这时候我们可以看到,JRE已经是使用的JDK1.8.0_144\jre\lib下的jar文件了。

 

 

3、创建Java项目:JDK1.8

 接下来我们新建一个普通的JAVA 项目,我这里命名为JDK1.8,我们检查一下项目的JRE,如下图所示:



然后我们导入src.zip文件到src目录下边,import->Archive File->选择JDK安装目录下的src.zip。


 

4、编译错误处理

Eclipse导入后,会自动进行编译。不出意外,编译一般出现问题,我们可以看到问题列表里出现了超过1万个错误。难道我们安装的是假的JDK吗,怎么会有如此多的错误?

大家不要着急,我们先点开一个错误看一看,Access restriction ,访问限制,意思是这些API是限制访问的。简单来说,这些API是非常底层的,可以理解为核心,只有在编写JDK这样的程序的时候才会使用上,一般我们自己写的JAVA应用程序肯定是不会用到这么底层的API

这时候我们需要修改一下Eclipse的设置,右键我们的项目->properities->Java Compiler->Errors/Warnings,然后我们选中Enable Project specific settings, 找到Deprecated and restricted API ->Forbidden reference (access rules) ,设置为Ignore,然后Apply,使设置生效,这时Eclipse会重新对项目进行编译。

编译完成后,你会发面错误一下子减少到50多个,从万减少到100以内,区别还是蛮大的。



接下来再解决其它的问题,

首先是 The import com.sun.tools cannot be resolved,

我们查看JRE,确实没找到这个包在哪里,其实这个包在jdk\lib\tools.jar中,引入这个包,重新编译,又减少一部分error.

然后UNIXToolkit和FontConfigManager找不到,所有的jar包都检查了,就是找不到这两个文件。既然jar包中没有,那我们就只好创建这两个文件了,

源文件可以在OpenJDK网站下载

http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/a06412e13bf7/src/solaris/classes/sun/font

http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/a06412e13bf7/src/solaris/classes/sun/awt

这两个文件创建后,再进行编译。错误继续减少,最终只有一个错误存在了

The method flatten(Node<T>, IntFunction<T[]>) in the type Nodes is not applicable for the arguments (Node, IntFunction)

在网上查找了相关问题,最后发现这个是Eclipse的一个BUG,在编译时不能识别泛型参数,具体见下面这个链接:

https://bugs.eclipse.org/bugs/show_bug.cgi?id=506664

 

5导出JAR文件

所有的准备工作都已经完成,接下来,我们只需要将项目导出为jar文件,我本地导出为rt_debug.jar,在导出时,会提示有一些警告信息,我们可以忽略。

最后我们将导出的rt_debug.jar文件复制到jdk1.8.0\jre\lib\ endorsed目录下边。一般来说,endorsed目录是不存的,所以我们自己创建一下,然后将rt_debug.jar复制到该目录即可。

这里我们使用 1c6f3 的是JAVA提供的endorsed技术,大家有兴趣可以上网了解一下,这里简单的说明一下。意思就是自己对JDK的系统API进行扩展,覆盖原系统API的功能,当然我们这里只是对原API进行了编译,不没有进行扩展。可以通过-Djava.endorsed.dirs指定目录,也可以直接在lib\下新建endorsed目录,个人觉得后都更方便一些。

最后,我们再对JDK进行调试跟踪,我们就能够看到调试信息了,如下所示:


 

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: