Extracting Java class information from AOT-compiled binary files
AOT compilation in the Java world has been a long-discussed topic, but until GraalVM came along, there were no tools that could achieve efficient AOT compilation, let alone drive the entire ecosystem. Although GraalVM provides the native-image tool that effectively assists developers in AOT compilation, achieving out-of-the-box AOT compilation for Java applications is still very challenging due to the complexity and diversity of the Java ecosystem, especially with widespread use of reflection and proxy technologies in various common frameworks.
Thanks to the Spring framework team for their Spring Native project, which allows one-click AOT compilation of projects through Maven or Gradle plugins. Of course, currently it is only applicable to Spring Boot projects.
Please use Sping Native to generate AOT-compiled Java programs.
Here is the official Spring Native example for generating Java applications with AOT compilation (Testing environment: 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
After relatively long compilation time and significant memory consumption, we can obtain an AOT-compiled Java program in the target directory. This is a standalone binary file that can run independently without any dependencies.
petclinic-jpa is a program compiled with AOT and can be run directly
Java code protection has always been a very difficult problem in the past. AOT is also considered as a solution for Java code protection. Unfortunately, many Java programs cannot be separated from the framework now. Due to the complexity of the framework, even programs compiled by AOT must include class information in the final generated binary file. In fact, the class files are neatly arranged in the resource area of the binary file.
The following tool can scan and extract class information from AOT-compiled binary files.
git clone https://github.com/3-keys/binary-classfile-reader cd binary-classfile-reader ./gradlew run --args='<path-of-the-binary-file> <output-folder>'
Using the petclinic-jpa obtained in the previous step as an example, extract the class information from it and compare it with the source code. You can see that model information, controller information, and service information can all be obtained.