Java 在不同的jar中加载两个类

Java 在不同的jar中加载两个类,java,classpath,classloader,websphere-6.1,Java,Classpath,Classloader,Websphere 6.1,我得到了两个不同罐子里有相同包的类。在上一个版本之前,这两个类都是相同的,所以我在加载它们时没有任何问题。现在,其中一个已经添加了一个新方法,如果我想访问它,我不仅应该导入带有该包的类,还需要确保带有正确类的jar首先出现在类路径中 i、 e.javac-classpath“%classpath%;a.jar;b.jar”MyClasses.. 其中a.jar具有使用我的新方法的类 现在,当我的应用程序投入生产时,我该如何确保这一点呢?它作为EAR文件部署,所有库都在WEB-INF/lib下 我

我得到了两个不同罐子里有相同包的类。在上一个版本之前,这两个类都是相同的,所以我在加载它们时没有任何问题。现在,其中一个已经添加了一个新方法,如果我想访问它,我不仅应该导入带有该包的类,还需要确保带有正确类的jar首先出现在类路径中

i、 e.
javac-classpath“%classpath%;a.jar;b.jar”MyClasses..

其中
a.jar
具有使用我的新方法的类

现在,当我的应用程序投入生产时,我该如何确保这一点呢?它作为EAR文件部署,所有库都在WEB-INF/lib下

我怎么知道哪个罐子比另一个更受欢迎?它的字母顺序是否像a.jar优先于b.jar一样

我读过这篇文章,了解了如何编写自定义类加载器,但有没有更好更简单的解决方案?因为我要在当前项目的整个JAR中访问这个方法,编写一个类加载器似乎有点过分了

请不要问我“为什么同一个班级用不同的罐子装同一个包裹?”这完全超出了我的控制范围,需要一些时间才能纠正

环境细节:IBM在其1.5Java上的版本是6.1


如果我说不通的话,请多问我几个问题。提前谢谢

据我所知,从WEB-INF/lib加载JAR的顺序是任意的——我问了一个关于JBOSS的类似问题,得到的回答(来自RedHat)是,它取决于
java.io.File.listFiles()
返回JAR的顺序(这不是保证的顺序)


自定义类加载器是一种选择,但您是否考虑过重新打包JAR-删除重复的类?

一个应用程序中JAR的顺序可能是字母顺序,但应用程序的顺序可能不是字母顺序。此外,这取决于服务器处理类加载的方式,即它是替换现有类还是跳过新类


尽管您已经说过了,但我还是想给出建议:在一个应用程序中部署多个jar中的同一个类(例如,可能发生在版本化jar中)始终是一个坏主意。您最好花点时间来解决这个问题,而不是试图搞乱类加载。

您可以尝试更改服务器的启动脚本,并使用
java-Xbootclasspath
在bootclasspath中指定具有正确类的jar。。。。否则,无法保证这两个JAR中的哪一个将首先加载。

这可能会变得非常模糊,但我记得很久以前解决这个问题的方法是,为给定的应用程序摆弄WAS管理控制台,并使用其web UI重新排列相关JAR文件。不确定这在您的情况下是否是一个可接受的步骤,但在其他所有操作都失败的情况下值得一试。

Websphere允许您指定在搜索类时查询特定应用程序的类加载器的顺序(类加载器是分层结构的,从加载JRE类的最顶层到WAR中加载类的类加载器)

在应用程序部署期间,您可以指定在搜索类时查询类加载器的顺序。有两种模式-父级优先(即首先查询最顶端的类加载器)和父级最后(首先查询应用程序类加载器)。这可以在EAR和WAR级别上指定


将复制的JAR打包到应用程序中的不同位置(例如,一个到EAR的类路径,另一个到WAR的WEB-INF/lib)并适当设置类加载器顺序可能会解决您的问题。但是,如果两个JAR必须位于同一级别(例如WEB-INF/lib),则无法指定加载复制类时将使用哪个类。

假设您可以控制部署,请自行修复类加载。以反向加载顺序将有问题的jar解压缩到同一目录中,然后重新压缩到新的jar中,然后使用他有一个新的组合罐。没有重复的类,问题解决了


或者,在部署之前,只需从JAR中删除重复类。

@DaveHowes谢谢,但正如我所说的,删除重复类需要一些时间,因为它需要经过一些级别的批准。另外,你可以发布问题的链接吗?这可能会有帮助。实现这一点的黑客方法可能是将“正确”放在应用服务器类路径上的jar,并使用“父级优先”类加载。虽然这是一种脆弱的方法。没错,这是一种黑客行为,而且很脆弱。但是,很可能没有更好的办法了。@DavesHowes我是在他的帮助下写这篇文章的,它试图加载我指定的类,并使用反射打印出它的方法。但是当它在类路径中第一个出现时,它会加载我的另一个jar类。我在做什么吗ng错了?我觉得如果我正确的jar在类路径中排名第二,即使是自定义类加载器也不会有任何帮助。没错,它们都是应用程序级的:(将一个放在EAR的类路径上,或者放在appserver的ext类路径上。在我看来,没有其他机会这样做了。@asgs,这对你来说基本上是一个糟糕的情况。唯一的“真实”解决方案是修复JAR以澄清依赖性,除非你能做一些真正有趣的事情,比如在你的web应用程序中嵌入OSGi。这会起作用,但考虑到问题所在,治疗比疾病更糟糕。@Andreas我读过这篇文章,但如前所述,我不认为在类加载上乱来是值得的。这可能是spe的一个理由编辑:asgs并没有说完全没有办法解决它,只是似乎需要一段时间。呵呵,你说得对,但如果我被允许的话,我会非常愿意这么做。@jtalhborn,我实际上除了检查之外没有任何该死的控制权