question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Jar loading order error causes spring-boot startup to fail

See original GitHub issue

Environment:

  • Jib version: 1.4.0
  • Build tool: maven 3.3.9
  • OS: windows 10 1903
  • *Server OS [use to run Docker imange]: Linux version 5.1.14-1.el7.elrepo.x86_64 *
  • Spring-boot: 2.0.6.RELEASE

Description of the issue:

Sorry, my English is not good, but I will try to explain the problems I have encountered.

In my project, there are two jars with different names, we call A.jar and B.jar. A rewrites and overwrites a Class with the same name in B. In order to work properly, I introduce A in pom.xml in order higher than B, which works fine in Spring-boot’s Fatjar.

But when I use Jib, B always loads before A, causing the coverage of the Class to not take effect, so when the application starts, the JDK prompts “XXXX method not found in XXX.class”. finally, application start failed

Expected behavior:

A.jar can be loaded earlier than B.jar, just like working in Spring-boot’s Fatjar.

Steps to reproduce:

  1. add Jib maven plugin to pom.xml
  2. run command: mvn compile jib:build -Dregistry_url={my server ip}:4000 -Dregistry_username={username} -Dregistry_password={password} -Dimage_tag=v1.2.0-dev-2019072101 -DsendCredentialsOverHttp=true
  3. try to run docker image, spring-boot startup failed

jib-maven-plugin Configuration:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
    <groupId>com.google.cloud.tools</groupId>
    <artifactId>jib-maven-plugin</artifactId>
    <version>1.4.0</version>
    <configuration>
        <container>
            <jvmFlags>
                <jvmFlag>-Xms512m</jvmFlag>
            </jvmFlags>
            <ports>
                <port>8080</port>
            </ports>
            <useCurrentTimestamp>true</useCurrentTimestamp>
        </container>
        <from>
            <image>registry.cn-hangzhou.aliyuncs.com/choerodon-tools/javabase:0.7.1</image>
        </from>
        <to>
            <image>${registry_url}/${docker.image.prefix}/${project.artifactId}:${maven.build.timestamp}</image>
            <auth>
                <username>${registry_username}</username>
                <password>${registry_password}</password>
            </auth>
        </to>
        <allowInsecureRegistries>true</allowInsecureRegistries>
        <jvmFlags>
            <jvmFlag>-Djava.security.edg=file:/dev/./urandom</jvmFlag>
        </jvmFlags>
        <
    </configuration>
</plugin>

Log output:

this is maven log:

[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building {my-cpplication-name} 0.9.0.RELEASE
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-resources-plugin:3.0.2:resources (default-resources) @ hcbm-iam ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 0 resource
[INFO] Copying 2 resources
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.7.0:compile (default-compile) @ hcbm-iam ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- jib-maven-plugin:1.4.0:build (default-cli) @ hcbm-iam ---
[WARNING] Authentication over HTTP is enabled. It is strongly recommended that you do not enable this on a public network!
[WARNING] Setting image creation time to current time; your image may not be reproducible.
[INFO]
[INFO] Containerizing application to ?[{my server ip}:4000/contract/{my-application-name}:20190728?[0m...
[INFO] ?[1m[                              ] 0.0% complete?[0m
[INFO] ?[1m> building image to registry?[0m
[INFO] ?[1A?[1A?[1A?[0J
[INFO] ?[1A?[1mExecuting tasks:?[0m
[INFO] ?[1m[                              ] 0.0% complete?[0m
[INFO] ?[1m> pulling base image manifest?[0m
.......
[INFO] ?[1m> authenticating push to {my server ip}:4000?[0m
[INFO] ?[1m> preparing base image layer pullers?[0m
[INFO] ?[1A?[1A?[1A?[1A?[0J
[INFO] ?[1A?[1mExecuting tasks:?[0m

...// skip loading log , all success and 100%

 [INFO] ?[1A?[1mExecuting tasks:?[0m
[INFO] ?[1mExecuting tasks:?[0m
[INFO] ?[1m[==============================] 100.0% complete?[0m
[INFO] ?[1A?[1A?[0J
[INFO] ?[1m[==============================] 100.0% complete?[0m
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 02:21 min
[INFO] Finished at: 2019-07-29T00:31:05+08:00
[INFO] Final Memory: 50M/313M
[INFO] ------------------------------------------------------------------------

when application running, this is error log of spring-boot:

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled. 
2019-07-28 22:44:06.793   --- [           main]  : 
*************************** 
APPLICATION FAILED TO START 
*************************** 
 
Description: 
 
An attempt was made to call the method 

io.choerodon.mybatis.common.BaseMapper.selectOptional(Ljava/lang/Object;Lorg/hzero/mybatis/common/Criteria;)Ljava/util/List; 

but it does not exist. 

Its class, io.choerodon.mybatis.common.BaseMapper, is available from the following locations: 
 
    jar:file:/app/libs/choerodon-starter-mybatis-mapper-0.10.0.RELEASE.jar!/io/choerodon/mybatis/common/BaseMapper.class 
    jar:file:/app/libs/hzero-starter-mybatis-mapper-0.9.0.RELEASE.jar!/io/choerodon/mybatis/common/BaseMapper.class 
 
It was loaded from the following location: 
 
    file:/app/libs/choerodon-starter-mybatis-mapper-0.10.0.RELEASE.jar 
 
 
Action: 
 
Correct the classpath of your application so that it contains a single, compatible version of io.choerodon.mybatis.common.BaseMapper 
 

Additional Information:

If you need additional information, I can always provide the party.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:11 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
chanseokohcommented, Jun 14, 2021

@xiaopihai7256 @luxingxiao Jib 3.1.1 is released, which creates two JVM argument files inside an image. One of them is the Java runtime classpath where all the dependencies are explicitly enumerated, which enables Jib to preseve the depending loading order by using this file for Java 9+. (For Java 8, you have to continue to set expandClasspathDependencies to true.)

For those interested, see here for more details.

0reactions
chanseokohcommented, Dec 7, 2020

Will leave this issue open to add better support for Java 9+.

https://github.com/GoogleContainerTools/jib/pull/2866#discussion_r512790086

But ideally, for Java 9+, I think we should really use the @-argument file feature; we can always preserve the classpath order while never hitting the system argument length limit. This is going to be a lot bigger change.

In sum, perhaps

  • Java 9+: always use a @-argument file. (expandClasspathDependencies is irrelevant.)
  • Java <=8: expand or not based on expandClasspathDependencies. Not decisive on if it should be true by default.
Read more comments on GitHub >

github_iconTop Results From Across the Web

Spring Boot Jar created. Runs but fails `DataSourceProperties ...
This is why trying to build a Spring Boot app/jar with the maven-assembly-plugin doesn't ... Main-Class: org.springframework.boot.loader.
Read more >
Core Features - Spring
This section dives into the details of Spring Boot. Here you can learn about the key features that you may want to use...
Read more >
Spring Boot: Configuring a Main Class - Baeldung
Spring Boot expects the artifact's Main-Class metadata property to be set to org.springframework.boot.loader.JarLauncher (or WarLauncher) ...
Read more >
Error: Could not find or load main class in Java [Solved]
In order to solve this error, you must know how Java find and loads the classes, that's a little bit complex topic for...
Read more >
How to Fix ClassNotFoundException in Java - Rollbar
If that JAR is already present in the classpath, make sure the classpath is not overridden (e.g. by a start-up script). After finding...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found