You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Jib version: 0.12.1-SNAPSHOT (code base from Jan 24, 2024)
Build tool: jib-cli, in JAR mode, with a Spring-Boot-3.2 executable "fat" jar
OS: Linux and Windows, error occurs on both
Description of the issue:
Our backend is Spring Boot based. We're building executable JAR files with the "spring-boot-maven-plugin" and its "repackage" goal.
Afterwards, we're dockerizing these JARs with jib-cli.
Example command: jib jar --target ${TARGET_IMAGE} ${APP_JAR} --from ${BASE_IMAGE} ...
After upgrading from Spring Boot 3.1 to Spring Boot 3.2 we encountered the following problem with the Docker images created by jib-cli: Their entrypoint statements refer to an outdated Java class name.
Current, wrong entrypoint: "java", "-cp", "/app", "org.springframework.boot.loader.JarLauncher"
Running the Docker image fails with a very short error output, that contains a ClassNotFoundException.
The launcher class org.springframework.boot.loader.JarLauncher is not found in the JAR.
Problem analysis:
With Spring Boot 3.2, the "JarLauncher" class moved to a different package. Its fully-qualified class name is now org.springframework.boot.loader.launch.JarLauncher (Please note the new .launch. naming part).
In Jib cli's class SpringBootExplodedProcessor, the old Launcher class name is hard-coded in its method computeEntrypoint. See here
Solution proposal:
The "SpringBootExplodedProcessor" should read the class to use in the image's entrypoint from the JAR file's MANIFEST.MF file (attribute main-class).
That is, it should work like Jib's class "StandardExplodedProcessor" already does. Its method "computeEntrypoint" already evaluates the JAR's manifest.
Expected behavior:
We expected Jib to use the same class in the Docker image's entrypoint as defined in the Main-Class attribute in the file META-INF/MANIFEST.MF, which is located inside the to-be-dockerized JAR file.
As we built our JAR based on Spring Boot 3.2.2 and used Spring Boot's Maven Plugin (goal 'repackage') we expected that class to be org.springframework.boot.loader.launch.JarLauncher.
But it's org.springframework.boot.loader.JarLauncher instead.
Steps to reproduce:
Create a minimal Spring Boot application. Go to https://start.spring.io, let an app be created with
Build tool: Maven
Build tool: Java
Spring Boot version: 3.2.2
Packaging: JAR
Java: 17
Dependencies: none
Download the generated project's code and build it with the command mvn package
Navigate to the generated fat-jar. Its path might be demo/target/demo-0.0.1-SNAPSHOT.jar (depending on the app name you chose in step 1).
Unpack the JAR, navigate to its META-INF/MANIFEST.MF file, open that file and look at its Main-Class attribute. Its value is org.springframework.boot.loader.launch.JarLauncher.
Use jib-cli to dockerize that JAR. Example command: jib jar --target target-image-tag:v0.1 demo-0.0.1-SNAPSHOT.jar --from base-image-tag:v0.1
Inspect the generated Docker image with "docker inspect". You'll find the image's entrypoint to contain a different class name than the one detected in step 4.:
Additional Information:
I already fixed the problem in my local version of jib's code base and the fix solves the problem described above. I'll send a PR soon.
It turned out that Jib-cli's class StandardExplodedProcessor already uses the Main-Class from the JAR's manifest. So basically, I just had to copy its computeEntrypoint logic to the SpringBootExplodedProcessor class. Of course, I also extended SpringBootExplodedProcessor's unit test.
The text was updated successfully, but these errors were encountered:
Thanks @mpeddada1 for pointing out the workaround again.
I was using the --entrypoint parameter wrong and tried it again now.
Now I learned how to use it and it works fine for me :-) .
We'll start using that parameter in our build process.
By using the workaround, this issue is solved for me, but nonetheless adapting JIB to new Spring Boot versions would be a good idea.
Environment:
Description of the issue:
Our backend is Spring Boot based. We're building executable JAR files with the "spring-boot-maven-plugin" and its "repackage" goal.
Afterwards, we're dockerizing these JARs with jib-cli.
Example command:
jib jar --target ${TARGET_IMAGE} ${APP_JAR} --from ${BASE_IMAGE} ...
After upgrading from Spring Boot 3.1 to Spring Boot 3.2 we encountered the following problem with the Docker images created by jib-cli: Their entrypoint statements refer to an outdated Java class name.
Current, wrong entrypoint:
"java", "-cp", "/app", "org.springframework.boot.loader.JarLauncher"
Running the Docker image fails with a very short error output, that contains a
ClassNotFoundException
.The launcher class
org.springframework.boot.loader.JarLauncher
is not found in the JAR.Problem analysis:
With Spring Boot 3.2, the "JarLauncher" class moved to a different package. Its fully-qualified class name is now
org.springframework.boot.loader.launch.JarLauncher
(Please note the new.launch.
naming part).In Jib cli's class
SpringBootExplodedProcessor
, the old Launcher class name is hard-coded in its methodcomputeEntrypoint
. See hereSolution proposal:
The "SpringBootExplodedProcessor" should read the class to use in the image's entrypoint from the JAR file's MANIFEST.MF file (attribute main-class).
That is, it should work like Jib's class "StandardExplodedProcessor" already does. Its method "computeEntrypoint" already evaluates the JAR's manifest.
Expected behavior:
We expected Jib to use the same class in the Docker image's entrypoint as defined in the
Main-Class
attribute in the fileMETA-INF/MANIFEST.MF
, which is located inside the to-be-dockerized JAR file.As we built our JAR based on Spring Boot 3.2.2 and used Spring Boot's Maven Plugin (goal 'repackage') we expected that class to be
org.springframework.boot.loader.launch.JarLauncher
.But it's
org.springframework.boot.loader.JarLauncher
instead.Steps to reproduce:
Create a minimal Spring Boot application. Go to https://start.spring.io, let an app be created with
Download the generated project's code and build it with the command
mvn package
Navigate to the generated fat-jar. Its path might be demo/target/demo-0.0.1-SNAPSHOT.jar (depending on the app name you chose in step 1).
Unpack the JAR, navigate to its
META-INF/MANIFEST.MF
file, open that file and look at itsMain-Class
attribute. Its value isorg.springframework.boot.loader.launch.JarLauncher
.Use jib-cli to dockerize that JAR. Example command:
jib jar --target target-image-tag:v0.1 demo-0.0.1-SNAPSHOT.jar --from base-image-tag:v0.1
Inspect the generated Docker image with "docker inspect". You'll find the image's entrypoint to contain a different class name than the one detected in step 4.:
Additional Information:
I already fixed the problem in my local version of jib's code base and the fix solves the problem described above. I'll send a PR soon.
It turned out that Jib-cli's class
StandardExplodedProcessor
already uses the Main-Class from the JAR's manifest. So basically, I just had to copy itscomputeEntrypoint
logic to theSpringBootExplodedProcessor
class. Of course, I also extended SpringBootExplodedProcessor's unit test.The text was updated successfully, but these errors were encountered: