问题
Consider a scenario that a java program imports the classes from jar files. If the same class resides in two or more jar files there could be a problem.
In such scenarios what is the class that imported by the program? Is it the class with the older timestamp??
What are the practices we can follow to avoid such complications.
Edit : This is an example. I have 2 jar files my1.jar and my2.jar. Both the files contain com.mycompany.CrazyWriter
回答1:
First, I assume that you mean that the same class resides in two more jar files...
Now, answering your questions:
- Which class is imported is dependent on your classloader and JVM. You cannot guarantee which class it will be, but in the normal classloader it will be the class from the first jar file on your classpath.
- Don't put the same class into multiple jar files, or if you are trying to override system classes, use
-bootclasspath
.
Edit: To address one of the comments on this answer. I originally thought that sealing the jar would make a difference, since in theory it should not load two classes from the same package from different jar files. However, after some experimentation, I see that this assumption does not hold true, at least with the default security provider.
回答2:
By default, classes are loaded by the ClassLoader using the classpath which is searched in order.
If you have two implementations of the same class, the one the class loader finds first will be loaded.
If the classes are not actually the same class (same names but different methods), you'll get an exception when you try to use it.
You can load two classes with the same names in a single VM by using multiple class loaders. The OSGI framework can manage lots of the complexitites for you, making sure the correct version is loaded, etc.
回答3:
The ClassLoader is responsible for loading the Classes. It scanns the ClassPath and loads the class that it found first. If you have the same Jar twice on the ClassPath or if you have two Jars that contain two different versions of the same Class (that is com.packagename.Classname), the one that is found first is loaded.
Try to avoid having the same jar on the classpath twice.
回答4:
Not sure what you meant by "the same class resides in two more classes"
if you meant inner/nested classes, there should be no problem since they are in different namespaces.
If you meant in two more JARs, as already answered, the order in the classpath is used.How to avoid?
A package should be in only one JAR to avoid duplicated classes. If two classes have the same simple name, likejava.util.Date
andjava.sql.Date
, but are in different packages, they actually are different classes. You must use the fully qualified name, at aleast from one of the classes, to distinguish them.
回答5:
If you have a problem finding out which version of a class is being used, then jwhich might be of use: http://www.fullspan.com/proj/jwhich/index.html
回答6:
If the same class resides in two more jars there should be a problem.
What do you mean exactly? Why should this be a problem?
In such scenarios what is the class that imported by the program? (Class with older timestamp??)
If a class exists in two JARs, the class will be loaded from the first JAR on the class path where it is found. Quoting Setting the class path (the quoted part applies to archive files too):
The order in which you specify multiple class path entries is important. The Java interpreter will look for classes in the directories in the order they appear in the class path variable. In the example above, the Java interpreter will first look for a needed class in the directory
C:\java\MyClasses
. Only if it doesn't find a class with the proper name in that directory will the interpreter look in theC:\java\OtherClasses
directory.
In other words, if a specific order is required then just enumerate the JAR files explicitly in the class path. This is something commonly used by application server vendors: to patch specific class(es) of a product, you put a JAR (e.g. CR1234.jar
) containing patched class(es) on the class path before the main JAR (say weblogic.jar
).
What are the practices we can follow to avoid such complications.
Well, the obvious answer is don't do it (or only on purpose like in the sample given above).
来源:https://stackoverflow.com/questions/2107911/safe-class-imports-from-jar-files