考虑java程序从jar文件导入类的场景。如果同一个类驻留在两个或更多jar文件中,则可能存在问题。
在这种情况下,程序导入的类是什么?是班级吗? 与旧的时间戳??
- 醇>
我们可以采取哪些措施来避免此类并发症。
编辑:这是一个例子。我有2个jar文件my1.jar和my2.jar。这两个文件都包含com.mycompany.CrazyWriter
答案 0 :(得分:2)
默认情况下,ClassLoader使用按顺序搜索的类路径加载类。
如果你有两个相同类的实现,那么将首先加载类加载器首先找到的那个。
如果类实际上不是同一个类(相同名称但方法不同),则在尝试使用它时会出现异常。
您可以使用多个类加载器在一个VM中加载两个具有相同名称的类。 OSGI框架可以为您管理许多复杂的数据,确保加载正确的版本等。
答案 1 :(得分:0)
首先,我假设您的意思是同一个类位于另外两个 jar 文件中...
现在,回答你的问题:
-bootclasspath
。编辑:解决有关此答案的其中一条评论。我原本认为sealing the jar会产生影响,因为理论上它不应该从不同的jar文件中加载来自同一个包的两个类。但是,经过一些实验,我发现这个假设不成立,至少对于默认的安全提供程序。
答案 2 :(得分:0)
ClassLoader负责加载类。 它扫描ClassPath并加载它首先找到的类。 如果您在ClassPath上有两次相同的Jar,或者如果您有两个包含同一个类的两个不同版本的Jars(即com.packagename.Classname),则会加载首先找到的那个。
尽量避免在类路径上使用相同的jar两次。
答案 3 :(得分:0)
不确定你的意思是“同一个班级还有两个班级”
如果你的意思是内部/嵌套类,那么应该没有问题,因为它们位于不同的名称空间中 如果你的意思是另外两个JAR,正如已经回答的那样,则使用类路径中的顺序。
如何避免?
一个包应该只在一个JAR中以避免重复的类。如果两个类具有相同的简单名称,例如java.util.Date
和java.sql.Date
,但它们位于不同的包中,则它们实际上是不同的类。您必须使用来自其中一个类的完全限定名称来区分它们。
答案 4 :(得分:0)
如果您在查找正在使用哪个版本的类时遇到问题,那么jwhich可能会有用: http://www.fullspan.com/proj/jwhich/index.html
答案 5 :(得分:0)
如果同一个班级居住在另外两个罐子里,那就应该有问题。
你到底是什么意思?为什么应该这是一个问题?
在这种情况下,程序导入的类是什么? (具有较旧时间戳的类?)
如果一个类存在于两个JAR中,则该类将从找到它的类路径上的第一个JAR加载。引用Setting the class path(引用的部分也适用于存档文件):
指定多个类路径条目的顺序非常重要。 Java解释器将在类路径变量中按照它们出现的顺序查找目录中的类。在上面的示例中,Java解释器将首先在目录
C:\java\MyClasses
中查找所需的类。只有在该目录中找不到具有正确名称的类时,解释器才会查找C:\java\OtherClasses
目录。
换句话说,如果需要特定的顺序,那么只需在类路径中显式枚举JAR文件。这是应用程序服务器供应商常用的东西:为了修补产品的特定类,在主JAR之前将包含修补类的JAR(例如CR1234.jar
)放在类路径上(比如说{ {1}})。
我们可以采取哪些措施来避免此类并发症。
嗯,显而易见的答案是不要这样做(或者只是出于上面给出的样本中的目的)。