Skip to content

IllegalStateException when extracting using layers a module with no code of its own #45385

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
matthew-js-porter opened this issue May 7, 2025 · 3 comments
Assignees
Labels
type: bug A general bug
Milestone

Comments

@matthew-js-porter
Copy link

When using Spring Boot's Layering feature to extract a jar file that only has dependencies and does not directly have classes an IllegalStateException is thrown.

java.lang.IllegalStateException: java.lang.IllegalStateException: No layer defined in index for file 'BOOT-INF/classes/'
        at org.springframework.boot.jarmode.tools.ToolsJarMode.run(ToolsJarMode.java:56)
        at org.springframework.boot.loader.launch.JarModeRunner.runJarMode(JarModeRunner.java:64)
        at org.springframework.boot.loader.launch.JarModeRunner.main(JarModeRunner.java:44)
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
        at java.base/java.lang.reflect.Method.invoke(Method.java:580)
        at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:102)
        at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:64)
        at org.springframework.boot.loader.launch.JarLauncher.main(JarLauncher.java:40)
Caused by: java.lang.IllegalStateException: No layer defined in index for file 'BOOT-INF/classes/'
        at org.springframework.boot.jarmode.tools.IndexedLayers.getLayer(IndexedLayers.java:92)
        at org.springframework.boot.jarmode.tools.IndexedLayers.getApplicationLayerName(IndexedLayers.java:75)
        at org.springframework.boot.jarmode.tools.ExtractCommand$LayersFileResolver.resolveApplication(ExtractCommand.java:467)
        at org.springframework.boot.jarmode.tools.ExtractCommand.createApplication(ExtractCommand.java:235)
        at org.springframework.boot.jarmode.tools.ExtractCommand.run(ExtractCommand.java:115)
        at org.springframework.boot.jarmode.tools.Command.run(Command.java:112)
        at org.springframework.boot.jarmode.tools.Runner.runCommand(Runner.java:68)
        at org.springframework.boot.jarmode.tools.Runner.run(Runner.java:55)
        at org.springframework.boot.jarmode.tools.Runner.run(Runner.java:47)
        at org.springframework.boot.jarmode.tools.ToolsJarMode.run(ToolsJarMode.java:53)
        ... 7 more

Reproducing the Issue

The issue can be reproduced using this sample project
https://github.com/matthew-js-porter/spring-boot-layers-issue/tree/main

  • clone the repository
  • build the project mvn package
  • extract the jar java -Djarmode=tools -jar demo-app/target/demo-app-0.0.1-SNAPSHOT.jar extract --layers --destination extracted
  • Observe the exception
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label May 7, 2025
@wilkinsona wilkinsona changed the title IllegalStateException when extracting Multi Module Project with Layers IllegalStateException when extracting using layers a module with no code of its own May 7, 2025
@mhalbritter mhalbritter added type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged labels May 8, 2025
@mhalbritter mhalbritter added this to the 3.3.x milestone May 8, 2025
@mhalbritter
Copy link
Contributor

The layers file looks like this:

- "dependencies":
  - "BOOT-INF/lib/jackson-annotations-2.18.3.jar"
  - "BOOT-INF/lib/jackson-core-2.18.3.jar"
  - ...
- "spring-boot-loader":
  - "org/"
- "snapshot-dependencies":
- "application":
  - "BOOT-INF/classpath.idx"
  - "BOOT-INF/layers.idx"
  - "BOOT-INF/lib/demo-rest-0.0.1-SNAPSHOT.jar"
  - "BOOT-INF/lib/demo-web-0.0.1-SNAPSHOT.jar"
  - "META-INF/"

When we try to get the application layer name, we look up org.springframework.boot.jarmode.tools.IndexedLayers#classesLocation. The value of that field is coming from the manifest from the Spring-Boot-Classes attribute, which is BOOT-INF/classes/.

BOOT-INF/classes/ isn't in the application layer, as it's empty.

Maybe we could use some other value to look up the application layer name which is always there, e.g. BOOT-INF/classpath.idx or META-INF/?

@mhalbritter
Copy link
Contributor

We're now using BOOT-INF/layers.idx (read from Spring-Boot-Layers-Index from the manifest) to determine the application layer.

@matthew-js-porter
Copy link
Author

@mhalbritter thanks addressing the is so quickly!

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
type: bug A general bug
Projects
None yet
Development

No branches or pull requests

3 participants