Classpath ordering in container dependent on host filesystem
See original GitHub issueEnvironment:
- Jib version: 1.6.1
- Build tool: maven, 3.5.4
- OS: Ubuntu 18.04.5
Description of the issue: The use of /app/libs/* in the classpath argument for java means that ordering of jars on the classpath is dependent on the host system. We had conflicting jars in our application, but it worked fine on our dev servers, however another set of servers had the jars ordered differently on the classpath and the jar conflict resulted in our application not starting.
Expected behavior: We expect the containers to be as portable as possible between environments so we hoped the classpath would be ordered identically between environments which would occur if for example the jars were listed explicitly on the classpath rather than as /app/libs/*
Steps to reproduce:
- Build image with Google jib
- Run on one host and print the classpath
- Run on another host with an alternative filesystem and print the classpath
- See classpath order differs
jib-maven-plugin
Configuration:
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>1.6.1</version>
</plugin>
Additional Information:
Classpath wildcard iteration on a Linux host is shown here in the openjdk source: https://github.com/openjdk/jdk/blob/6bab0f539fba8fb441697846347597b4a0ade428/src/java.base/share/native/libjli/wildcard.c#L209
Which points to the use of readdir (https://www.man7.org/linux/man-pages/man3/readdir.3.html) which indicates:
The order in which filenames are read by successive calls to readdir() depends on the filesystem implementation; it is unlikely that the names will be sorted in any fashion.
which is exactly what we ran into when the option for mounting the host filesystem differed.
Issue Analytics
- State:
- Created 3 years ago
- Reactions:2
- Comments:8 (5 by maintainers)
Top GitHub Comments
@loosebazooka in our case the issue was multiple slf4j logging implementations (log4j and logback) that conflicted and not actually duplicate classes. It dynamically chose the implementation based on which it encountered first, and the application bailed with an error when one was used but worked fine with the other. And yes, of course we should not have both on the classpath and have since fixed it since we encountered this issue messing up a planned deploy to the next environment.
@saturnism @cpopp 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.