在不同的JAR中加载两个类

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

javac -classpath "%classpath%;a.jar;b.jar" MyClasses..

其中a.jar有我的新方法的类。

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

我怎么知道哪个jar子优先于另一个? 是a.jar的字母顺序是否优先于b.jar?

我已经阅读了这个safe-class-imports-from-jar-files线程,并且开始了解编写自定义类加载器,但有更简单的解决方案吗? 我只是要在当前项目中的整个JAR中访问此方法,编写类加载器似乎有点矫枉过正。

请不要问我“为什么在不同的JAR中同一个包有同样的地狱?” 这完全不受我的控制 ,需要一些时间来纠正这个问题。

环境详细信息:1.5 Java上的IBM WAS 6.1。

如果我没有多大意义,请问我更多问题。 提前致谢!

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

在部署应用程序期间,您可以指定在搜索类时是否查询类加载器的顺序。 有两种模式 – Parent first(即首先查询最顶层的类加载器)和parent last(首先查询app classloader)。 这可以在EAR和WAR级别指定。

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

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

据我所知,从WEB-INF / lib加载的jar的顺序是任意的 – 我问了一个关于JBOSS的类似问题并得到了回复(来自RedHat)它依赖于java.io.File.listFiles()的顺序java.io.File.listFiles()返回它们(这不是保证订单)。

自定义类加载器是一个选项,但您是否考虑过重新打包jar – 删除重复的类?

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

虽然你已经说过,我仍然想提出这样的建议:在一个应用程序中部署多个JAR中的相同类(例如,可能在版本化的jar中发生)总是一个坏主意。 你最好花时间来修复它,而不是试图搞乱类加载。

这可能会非常含糊,但我确实记得很长一段时间后通过弄乱该给定应用程序的WAS管理控制台并使用他们的Web UI重新排列相关的JAR文件来解决这个问题。 不确定这是否是您案件中可接受的步骤,但值得一试,万一其他一切都失败了。

假设您可以控制部署,请自行修复类加载。 通过将它们以反向加载顺序解压缩到同一目录中然后重新压缩到新的jar中来自己组合有问题的jar子。 然后使用新的组合jar部署应用程序。 没有重复的课程,问题解决了。

或者,只需在部署之前从jar中删除欺骗类。