Description
The reference guide has a section on unpacking the executable jar to get extra boost. It also has an additional hint for bypassing the bootlader with the impact on losing classpath ordering.
Our work on AppCDS (see spring-projects/spring-framework#31497) has shown that a predicable classpath has an impact on how effective the cache is going to be. Investigating a bit more, it looks doable to provide the above as a first class concept.
Here is a proposal that is hacking layertools
with an additional extract2
(sic) command: https://github.com/snicoll/spring-boot/tree/gh-38276
Ignoring the fact that this does use layertools for convenience, you can execute the following on any repackaged archive:
java -Djarmode=layertools -jar target/my-app-1.0.0-SNAPSHOT.jar extract2 --destination target/app
This creates a directory with the following structure:
target/app/
├── application
│ └── my-app-1.0.0-SNAPSHOT.jar
├── dependencies
│ ├── ...
│ ├── spring-context-6.1.0-RC2.jar
│ ├── spring-context-support-6.1.0-RC2.jar
│ ├── ...
└── run-app.jar
You can then run the app as follows (assuming you're in the same directory as the previous command):
java -jar target/app/run-app.jar
The run-app.jar
has the following characteristics:
- It starts the application class directly (no bootlader used)
- The manifest defines a classpath with the same order as
classpath.idx
, withapplication/my-app-1.0.0-SNAPSHOT.jar
being in front
my-app-1.0.0-SNAPSHOT.jar
has some manifest entries of the original jar so that package.getImplementationVersion()
continues to work.
The work on this prototype has led to a number of questions:
- Layertools provide a
Command
infrastructure and several utilities related to extracting/copying that are not specific to layers. If we want to go the same route with a different jar mode, a significant number of classes should be copied/reimplemented. Perhaps a single jar with a public API and sub-packages for layertools and this new mode could be an option? - This work could potentially apply to layers themselves. Rather than having
dependencies/BOOT-INF/lib
and a layer for the bootloader, we could use the same exact structure. Or perhaps the structure above could become a layer configuration (where all libs go todependencies
). - It's hard for
run-app.jar
to have sensible File attributes. The command tries to respect the file attributes of files it extracts from the repackaged archive, butrun-jar.jar
is created on the spot.
We have confirmed that with the prototype, AppCDS is effective (close to 95% classes loaded from the cache).