用于隔离jar的类加载器(类标识危机)

时间:2014-01-09 22:27:59

标签: java jar classloader conflict

我正在使用嵌入了与我自己的依赖项冲突的依赖项的jarX,因此我正在创建一个类加载器来将jarX的依赖项与我的主类加载器隔离开来。

jarX在我的应用程序的类路径之外,但是我的类使用jarX的类在我的类路径中,所以当我实例化通过自定义类加载器加载的类时,我以ClassCastException的形式遇到类标识危机,作为JVM的版本我的类被认为与我的自定义类加载器加载的类不同。

我发现this blog post他们只通过反射与自定义类加载器类交互来解决类似的问题,这似乎解决了这个问题。

感觉它应该比这更容易。有谁知道更好的方法来处理这个问题?

2 个答案:

答案 0 :(得分:0)

最简单的方法是打开jarX,删除有问题的类,然后完成。在JAR中嵌入依赖项是一种不好的做法,除非JAR仅用作独立的可运行的fat-jar。用作库的JAR不应嵌入依赖项。

当你注意到人们在他们的JAR中打包第三方课程时,我建议他们指出这通常不是一个好主意,并鼓励他们不要这样做。如果一个项目提供了一个包含所有依赖项的可运行的fat-jar,那很好。但是,它不应该是他们提供的唯一JAR。还应提供没有任何第三方代码的普通JAR或JAR集。在极少数情况下,第三方代码被修改并且必须包含在内,它应该在提供者的包命名空间下完成,而不是在原始第三方的包名称下。

最后,要获得构建模块化Java应用程序和处理类加载器隔离的真正解决方案,请查看几个OSGi实现之一或项目Jigsaw

答案 1 :(得分:0)

你能用完整的堆栈跟踪发布哪个jar和它重叠的类是什么?看看我编写的这个tool生成WAR中重复类的列表,有一个选项可以排除相同大小的重复项。

这些措施可以解决这个问题:

  • 尝试通过逐案分析重叠的原因来减少重复次数。为完全重复的罐子添加maven排除。
  • 检查是否有相同jar的版本没有你可以使用的依赖项,它是jar,xerces等?
  • 如果没有没有依赖关系的jar,你可以排除与jarX重叠的另一个jar,看看应用程序是否仍然有效。这意味着需要jar的所有组件都具有jarX库的兼容版本
  • 将应用程序分成两个WAR,每个WAR都有您需要的库版本。这将减少
  • 中的库数量

这些措施可以长期维持得更有可能

如果之前的措施不起作用:

  • 打开jar,删除重复的类并使用其他名称jarX-patched在maven存储库中发布
  • 您可以将nexus配置为透明地提供修补的jar而不是未修补的jar

  • 如果您的容器支持更好的OSGI,但如果您不使用OSGI容器进行开发,那么该应用程序将无法在开发中使用。