I'm using Spring Boot 2.3.3.
I've got a project where I'm building a fat JAR using the spring-boot-maven-plugin
. I've configured the JAR to be executable and I've explicitly enabled layers. This is my configuration of the spring-boot-maven-plugin
:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
<layers>
<enabled>true</enabled>
</layers>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
After building the project with mvn package
, I try to extract the layers java -Djarmode=layertools -jar target/my-project-0.1.0-SNAPSHOT.jar extract --destination dest
as described in this blog post on spring.io.
This gives me an empty directory for each of the layers:
$ ls -R dest
dest:
application dependencies snapshot-dependencies spring-boot-loader
dest/application:
dest/dependencies:
dest/snapshot-dependencies:
dest/spring-boot-loader:
I would expect the directories to contain the class files of the different layers instead.
I noticed that this is caused by the JAR file being executable. I debugged through ExtractCommand.java and ZipInputStream#getNextEntry()
will always return null for an executable JAR.
I think the options are to either improve the ExtractCommand
(and possibly other commands) to work with executable JARs or to give a disclaimer in the documentation that the layertools don't work with executable JARs.
A fix could involve the following steps:
* Call mark(2)
on the FileInputStream
to be able to later reset it in case the file is not executable.
* Read the first two bytes from the FileInputStream
and check if they match the "shebang" (#!
) magic number (0x23 0x21
).
* In case the file doesn't start with a shebang, reset the input stream.
* In case the file starts with a shebang, read bytes until the characters \necho 0
are read.
* Wrap the input stream in a ZipInputStream
and read the entries like before.
I know that this implementation won't be that easy, so I'd totally understand if you chose not to support executable JARs.
Comment From: scottfrederick
This is similar to #22223.
For Spring Boot 2.3.x, we should detect this condition in layertools
and give a warning or error like we do for the bootBuildImage
task.
For Spring Boot 2.4.x, we're hoping to be able to fix up the jar file properly in #22336.
Comment From: snicoll
I've switched this issue to documentation
as keeping it as described made me think we've actually fixed that limitation.