GoogleContainerTools / GoogleContainerTools/jib

JIB-CLI uses outdated classname in entrypoint when dockerzing a Spring-Boot-3.2 executable JAR.

Open
#4,175 3 comments 0 reactions 0 assignees View on GitHub
enhancement priority:p3
Dominant language
Java
Stars
14.5k
Forks
1.5k
PR merge metrics
No merged PRs in 30d

Description

**Environment**:

- *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](https://github.com/GoogleContainerTools/jib/blob/master/jib-cli/src/main/java/com/google/cloud/tools/jib/cli/jar/SpringBootExplodedProcessor.java#L144)

_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**:
1. 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

2. Download the generated project's code and build it with the command `mvn package`
3. 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).
4. 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`.
5. 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`
6. 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.:
```
"Entrypoint": [
"java",
"-cp",
"/app",
"org.springframework.boot.loader.JarLauncher"
],
```

**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.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.