首先,来说一下今天写这篇文章的目的。从JDK9开始,JDK安装包中就不再包含tools.jar包了,那么之前所使用的依赖方式就失效了,那么我们应该如何在新版本中去解决这个以来问题,从而不影响我们的项目正常编译呢?
在开发时,我们可能会在编译前或编译后通过一些手段去修改Java生成的字节码。比如使用JavaParser生成或修改源代码,使用Javapoet生成Java类,又或者通过Javassist修改class字节码文件。各种各样的方法层出不穷,我们可以根据自己的场景去选取合适工具。而在一些情况下,我们可能希望在编译前通过修改Java的抽象语法树来改变编译所生成的class字节码文件。这个时候我们就可以考虑使用JDK中的tools.jar来处理这个问题了。
那么,在项目中我们要怎么去依赖/引入tools.jar包呢?这里我会分别从JDK8/JDK11和Gradle项目和纯Java项目这几个维度去说明如何引入tools.jar依赖包,并且本文中使用的IDE是Intellij IDEA。毕竟买了正版软件,不用起来就浪费了。
JDK8 & Gradle
在项目的build.gradle中添加如下依赖。
1 | dependencies { |
如果你已经配置了环境变量,则可以使用以下方式进行依赖。
1 | dependencies { |
JDK8下的配置应该问题不大,身为开发者应该都知道怎么去依赖。
JDK8 & Java
修改项目根目录下的.iml文件,在原有文件的
1 | <orderEntry type="module-library"> |
当然,你也可以通过Intellij IDEA右上角的“Project Structure”或快捷键”Ctrl+Alt+Shift+S“打开Project Structure配置面板。选中”Project Settings“->”Modules“,然后选中你需要引入tools.jar的module,然后在右侧上方的tab选项卡中选中“Dependencies“->”Add”->“1 JARs or directories…”,然后选择JDK8安装目录下的tools.jar即完成依赖包的引入。如下图:
JDK11 & Gradle
修改项目下的build.gradle文件,添加sourceCompatibility和targetCompatibility。
1 | java { |
顺便提一嘴,Android Studio中的Java Module配置和此一样。
JDK11 & Java
将项目根目录下的.iml从<orderEntry type="inheritedJdk" />
修改成<orderEntry type="jdk" jdkName="8" jdkType="JavaSDK" />
。如下图:
或者通过Project Structure面板进行修改同样可行。
总结
综上所述,其实配置方式挺简单的。以上也是个人开发中遇到并寻求解决方案过程中得到的结果。JDK9之后,像tools.jar、dt.jar等JDK安装目录中lib下的jar包都被移除了。相应的,增加了jmods文件夹,文件夹下jdk.compiler.jmod对应着之前的tools.jar。使用解压软件打开jdk.compiler.jmod,可以发现jdk.compiler.jmod中的classes目录下的文件和tools.jar几乎是一样的,oracle将其分模块进行隔离,旨在提高其安全性等方面原因。而之所以使用JDK11时在项目中配置目标版本为8时,就可以使用其中的诸如tools.jar包里面的类,我想是为了兼容可能吧。
如有疑问/建议,可以给我留言,我们共同成长!