How does java choose a .JAR library version
up vote
0
down vote
favorite
For various historical reasons, I have an old java application which shares a local lib/
directory of library .JARs with some other applications. In this directory is a number of versioned copies of the same library, for example:
...
log4j-1.2.16.jar
log4j-1.2.17.jar
slf4j-api-1.7.5.jar
slf4j-api-1.7.21.jar
slf4j-log4j12-1.7.5.jar
slf4j-log4j12-1.7.9.jar
...
When my java app starts, how does it decide which .jar file to load? As far as I know, the CLASSPATH is just set to ./lib/
. But it uses the Tanuki Service wrapper to start, so I'm not 100% sure of this.
I can't delete any of these existing .JARs, is there a way to specify exactly which .JARs my app will use ?
After this old application was patched, now I'm getting a NoClassDefFoundError, and I suspect the app is loading an older (or newer) version of a .JAR that conflicts with another library (BoneCP and slf4j).
java
add a comment |
up vote
0
down vote
favorite
For various historical reasons, I have an old java application which shares a local lib/
directory of library .JARs with some other applications. In this directory is a number of versioned copies of the same library, for example:
...
log4j-1.2.16.jar
log4j-1.2.17.jar
slf4j-api-1.7.5.jar
slf4j-api-1.7.21.jar
slf4j-log4j12-1.7.5.jar
slf4j-log4j12-1.7.9.jar
...
When my java app starts, how does it decide which .jar file to load? As far as I know, the CLASSPATH is just set to ./lib/
. But it uses the Tanuki Service wrapper to start, so I'm not 100% sure of this.
I can't delete any of these existing .JARs, is there a way to specify exactly which .JARs my app will use ?
After this old application was patched, now I'm getting a NoClassDefFoundError, and I suspect the app is loading an older (or newer) version of a .JAR that conflicts with another library (BoneCP and slf4j).
java
Having the same library in different versions in the classpath is always bad. Either only one version is used, then you could easily remove the other or both are used (because they do not contain exactly the same classes) but then you almost certainly get conflicts because one version uses the common classes from the other library.
– Henry
Nov 8 at 4:39
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
For various historical reasons, I have an old java application which shares a local lib/
directory of library .JARs with some other applications. In this directory is a number of versioned copies of the same library, for example:
...
log4j-1.2.16.jar
log4j-1.2.17.jar
slf4j-api-1.7.5.jar
slf4j-api-1.7.21.jar
slf4j-log4j12-1.7.5.jar
slf4j-log4j12-1.7.9.jar
...
When my java app starts, how does it decide which .jar file to load? As far as I know, the CLASSPATH is just set to ./lib/
. But it uses the Tanuki Service wrapper to start, so I'm not 100% sure of this.
I can't delete any of these existing .JARs, is there a way to specify exactly which .JARs my app will use ?
After this old application was patched, now I'm getting a NoClassDefFoundError, and I suspect the app is loading an older (or newer) version of a .JAR that conflicts with another library (BoneCP and slf4j).
java
For various historical reasons, I have an old java application which shares a local lib/
directory of library .JARs with some other applications. In this directory is a number of versioned copies of the same library, for example:
...
log4j-1.2.16.jar
log4j-1.2.17.jar
slf4j-api-1.7.5.jar
slf4j-api-1.7.21.jar
slf4j-log4j12-1.7.5.jar
slf4j-log4j12-1.7.9.jar
...
When my java app starts, how does it decide which .jar file to load? As far as I know, the CLASSPATH is just set to ./lib/
. But it uses the Tanuki Service wrapper to start, so I'm not 100% sure of this.
I can't delete any of these existing .JARs, is there a way to specify exactly which .JARs my app will use ?
After this old application was patched, now I'm getting a NoClassDefFoundError, and I suspect the app is loading an older (or newer) version of a .JAR that conflicts with another library (BoneCP and slf4j).
java
java
edited Nov 8 at 4:12
asked Nov 8 at 4:01
Kingsley
1,6951918
1,6951918
Having the same library in different versions in the classpath is always bad. Either only one version is used, then you could easily remove the other or both are used (because they do not contain exactly the same classes) but then you almost certainly get conflicts because one version uses the common classes from the other library.
– Henry
Nov 8 at 4:39
add a comment |
Having the same library in different versions in the classpath is always bad. Either only one version is used, then you could easily remove the other or both are used (because they do not contain exactly the same classes) but then you almost certainly get conflicts because one version uses the common classes from the other library.
– Henry
Nov 8 at 4:39
Having the same library in different versions in the classpath is always bad. Either only one version is used, then you could easily remove the other or both are used (because they do not contain exactly the same classes) but then you almost certainly get conflicts because one version uses the common classes from the other library.
– Henry
Nov 8 at 4:39
Having the same library in different versions in the classpath is always bad. Either only one version is used, then you could easily remove the other or both are used (because they do not contain exactly the same classes) but then you almost certainly get conflicts because one version uses the common classes from the other library.
– Henry
Nov 8 at 4:39
add a comment |
2 Answers
2
active
oldest
votes
up vote
1
down vote
accepted
If you are going to share lib directories like that, then each application needs to list the JAR files that it uses explicitly on the classpath. If you use a wildcard classpath entry (e.g. "lib/*"), then it is not specified which versions of the JARs will be used. The manual entry states:
Class Path Wild Cards
Class path entries can contain the base name wildcard character (), which is considered equivalent to specifying a list of all of the files in the directory with the extension .jar or .JAR. For example, the class path entry mydir/ specifies all JAR files in the directory named mydir. A class path entry consisting of * expands to a list of all the jar files in the current directory. Files are considered regardless of whether they are hidden (have names beginning with '.').
....
The order in which the JAR files in a directory are enumerated in the
expanded class path is not specified and may vary from platform to
platform and even from moment to moment on the same machine. A
well-constructed application should not depend upon any particular
order. If a specific order is required, then the JAR files can be
enumerated explicitly in the class path.
Thanks Stephen, this was exactly the solution -java -cp lib/jarfile1.jar;lib/jarfile2.jar;
etc etc. I had to do this for 11 jar libs.
– Kingsley
Nov 8 at 5:34
I guess .... you could also do it with symlinks. Create a "lib" directory for each application and populate it with symlinks to the appropriate versions of the JARs. But explicitly naming the JARs in your classpath via a wrapper script is more robust,
– Stephen C
Nov 8 at 5:41
add a comment |
up vote
2
down vote
Which jar first in classpath that is picked up when JVM classloader is looking for a class. So you can try to add those jars in different order to check which one breaks your application
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
accepted
If you are going to share lib directories like that, then each application needs to list the JAR files that it uses explicitly on the classpath. If you use a wildcard classpath entry (e.g. "lib/*"), then it is not specified which versions of the JARs will be used. The manual entry states:
Class Path Wild Cards
Class path entries can contain the base name wildcard character (), which is considered equivalent to specifying a list of all of the files in the directory with the extension .jar or .JAR. For example, the class path entry mydir/ specifies all JAR files in the directory named mydir. A class path entry consisting of * expands to a list of all the jar files in the current directory. Files are considered regardless of whether they are hidden (have names beginning with '.').
....
The order in which the JAR files in a directory are enumerated in the
expanded class path is not specified and may vary from platform to
platform and even from moment to moment on the same machine. A
well-constructed application should not depend upon any particular
order. If a specific order is required, then the JAR files can be
enumerated explicitly in the class path.
Thanks Stephen, this was exactly the solution -java -cp lib/jarfile1.jar;lib/jarfile2.jar;
etc etc. I had to do this for 11 jar libs.
– Kingsley
Nov 8 at 5:34
I guess .... you could also do it with symlinks. Create a "lib" directory for each application and populate it with symlinks to the appropriate versions of the JARs. But explicitly naming the JARs in your classpath via a wrapper script is more robust,
– Stephen C
Nov 8 at 5:41
add a comment |
up vote
1
down vote
accepted
If you are going to share lib directories like that, then each application needs to list the JAR files that it uses explicitly on the classpath. If you use a wildcard classpath entry (e.g. "lib/*"), then it is not specified which versions of the JARs will be used. The manual entry states:
Class Path Wild Cards
Class path entries can contain the base name wildcard character (), which is considered equivalent to specifying a list of all of the files in the directory with the extension .jar or .JAR. For example, the class path entry mydir/ specifies all JAR files in the directory named mydir. A class path entry consisting of * expands to a list of all the jar files in the current directory. Files are considered regardless of whether they are hidden (have names beginning with '.').
....
The order in which the JAR files in a directory are enumerated in the
expanded class path is not specified and may vary from platform to
platform and even from moment to moment on the same machine. A
well-constructed application should not depend upon any particular
order. If a specific order is required, then the JAR files can be
enumerated explicitly in the class path.
Thanks Stephen, this was exactly the solution -java -cp lib/jarfile1.jar;lib/jarfile2.jar;
etc etc. I had to do this for 11 jar libs.
– Kingsley
Nov 8 at 5:34
I guess .... you could also do it with symlinks. Create a "lib" directory for each application and populate it with symlinks to the appropriate versions of the JARs. But explicitly naming the JARs in your classpath via a wrapper script is more robust,
– Stephen C
Nov 8 at 5:41
add a comment |
up vote
1
down vote
accepted
up vote
1
down vote
accepted
If you are going to share lib directories like that, then each application needs to list the JAR files that it uses explicitly on the classpath. If you use a wildcard classpath entry (e.g. "lib/*"), then it is not specified which versions of the JARs will be used. The manual entry states:
Class Path Wild Cards
Class path entries can contain the base name wildcard character (), which is considered equivalent to specifying a list of all of the files in the directory with the extension .jar or .JAR. For example, the class path entry mydir/ specifies all JAR files in the directory named mydir. A class path entry consisting of * expands to a list of all the jar files in the current directory. Files are considered regardless of whether they are hidden (have names beginning with '.').
....
The order in which the JAR files in a directory are enumerated in the
expanded class path is not specified and may vary from platform to
platform and even from moment to moment on the same machine. A
well-constructed application should not depend upon any particular
order. If a specific order is required, then the JAR files can be
enumerated explicitly in the class path.
If you are going to share lib directories like that, then each application needs to list the JAR files that it uses explicitly on the classpath. If you use a wildcard classpath entry (e.g. "lib/*"), then it is not specified which versions of the JARs will be used. The manual entry states:
Class Path Wild Cards
Class path entries can contain the base name wildcard character (), which is considered equivalent to specifying a list of all of the files in the directory with the extension .jar or .JAR. For example, the class path entry mydir/ specifies all JAR files in the directory named mydir. A class path entry consisting of * expands to a list of all the jar files in the current directory. Files are considered regardless of whether they are hidden (have names beginning with '.').
....
The order in which the JAR files in a directory are enumerated in the
expanded class path is not specified and may vary from platform to
platform and even from moment to moment on the same machine. A
well-constructed application should not depend upon any particular
order. If a specific order is required, then the JAR files can be
enumerated explicitly in the class path.
answered Nov 8 at 4:34
Stephen C
509k69556909
509k69556909
Thanks Stephen, this was exactly the solution -java -cp lib/jarfile1.jar;lib/jarfile2.jar;
etc etc. I had to do this for 11 jar libs.
– Kingsley
Nov 8 at 5:34
I guess .... you could also do it with symlinks. Create a "lib" directory for each application and populate it with symlinks to the appropriate versions of the JARs. But explicitly naming the JARs in your classpath via a wrapper script is more robust,
– Stephen C
Nov 8 at 5:41
add a comment |
Thanks Stephen, this was exactly the solution -java -cp lib/jarfile1.jar;lib/jarfile2.jar;
etc etc. I had to do this for 11 jar libs.
– Kingsley
Nov 8 at 5:34
I guess .... you could also do it with symlinks. Create a "lib" directory for each application and populate it with symlinks to the appropriate versions of the JARs. But explicitly naming the JARs in your classpath via a wrapper script is more robust,
– Stephen C
Nov 8 at 5:41
Thanks Stephen, this was exactly the solution -
java -cp lib/jarfile1.jar;lib/jarfile2.jar;
etc etc. I had to do this for 11 jar libs.– Kingsley
Nov 8 at 5:34
Thanks Stephen, this was exactly the solution -
java -cp lib/jarfile1.jar;lib/jarfile2.jar;
etc etc. I had to do this for 11 jar libs.– Kingsley
Nov 8 at 5:34
I guess .... you could also do it with symlinks. Create a "lib" directory for each application and populate it with symlinks to the appropriate versions of the JARs. But explicitly naming the JARs in your classpath via a wrapper script is more robust,
– Stephen C
Nov 8 at 5:41
I guess .... you could also do it with symlinks. Create a "lib" directory for each application and populate it with symlinks to the appropriate versions of the JARs. But explicitly naming the JARs in your classpath via a wrapper script is more robust,
– Stephen C
Nov 8 at 5:41
add a comment |
up vote
2
down vote
Which jar first in classpath that is picked up when JVM classloader is looking for a class. So you can try to add those jars in different order to check which one breaks your application
add a comment |
up vote
2
down vote
Which jar first in classpath that is picked up when JVM classloader is looking for a class. So you can try to add those jars in different order to check which one breaks your application
add a comment |
up vote
2
down vote
up vote
2
down vote
Which jar first in classpath that is picked up when JVM classloader is looking for a class. So you can try to add those jars in different order to check which one breaks your application
Which jar first in classpath that is picked up when JVM classloader is looking for a class. So you can try to add those jars in different order to check which one breaks your application
answered Nov 8 at 4:04
Ivan
4,4891720
4,4891720
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53201380%2fhow-does-java-choose-a-jar-library-version%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Having the same library in different versions in the classpath is always bad. Either only one version is used, then you could easily remove the other or both are used (because they do not contain exactly the same classes) but then you almost certainly get conflicts because one version uses the common classes from the other library.
– Henry
Nov 8 at 4:39