Open stefan-prange opened 7 months ago
Thanks for bringing this up! However, as a workaround, I believe the jib cli command has a way to customize the entrypoint through this parameter.
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 classorg.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 classSpringBootExplodedProcessor
, 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 beorg.springframework.boot.loader.launch.JarLauncher
. But it'sorg.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.