Skip to content

Document that extracting layers with layertools doesn't work with executable JAR files #22993

@pvorb

Description

@pvorb

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.

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions