AOT编译是个在Java世界已经讨论了很久的一个话题,但是在GraalVM出现之前,一直没有一个工具能够实现较完善的AOT编译,更别说带动整个生态环境。 虽然GraalVM提供了native-image工具,能够有效地帮助开发者进行AOT编译,但是由于Java生态的复杂多样,特别是反射、代理这些技术在各种常用的框架中都广泛应用,因此想要实现一个Java应用开箱即用的AOT编译仍旧是十分困难的。
Spring Native 项目
感谢Spring团队的Spring Native项目,它们通过maven或者gradle插件,能够实现项目的一键AOT编译,当然目前还只仅于Spring Boot项目。
使用Sping Native生成AOT编译的Java程序
这里使用Spring Native官方例子来生成一个AOT编译的Java程序(测试环境:Ubuntu 20.04, Docker 20.10.6)
git clone https://github.com/spring-projects-experimental/spring-native.git
cd spring-native/sample/petclinic-jpa
./build.sh
经过一段比较漫长时间的编译,并且需要消耗大量的内存,我们可以在target目录得到了AOT编译后的Java程序,这是一个独立的二进制文件,不需要任何依赖即可独立运行
使用./petclinia-jpa即可运行这个程序
从二进制文件中提取Java类文件
过去Java代码保护一直是一个很困难的问题,AOT也被认为是一种Java代码保护的解决方案,但是不幸的是,现在的许多Java程序无法脱离框架,而由于框架的复杂性,即使是经过AOT编译的程序也不得不把类信息包含到最终生成二进制文件中,一个个class文件其实就整整齐齐地排列在二进制文件的resources区域。
下面这个工具能够从二进制文件中扫描并提取类信息
https://github.com/3-keys/binary-classfile-reader
git clone https://github.com/3-keys/binary-classfile-reader
cd binary-classfile-reader
./gradlew run --args='<path-of-the-binary-file> <output-folder>'
以上一个步骤获取到的petclinic-jpa 为例,从中提取到类信息,跟源码比对可以看到,Model信息,Controller信息,Service信息都可以获取到。