管理java类路径上的冲突

时间:2011-11-18 12:13:32

标签: java dependencies classpath classloader

我暴露了我的背景:

我有两个在独特的Weblogic Server上运行的Java程序:程序A和程序B. 这些是由两个ksh发起的:

programA.ksh和programB.ksh

两者都需要C.jar但是在不同的版本中(但具有完全相同的包和类):

  • 程序A需要C-1.0.jar
  • 程序B需要C-2.0.jar

我确切地说两个程序共享相同的weblogic类路径。

所以,我的classpath按顺序包含:

.....

C-1.0.jar

C-2.0.jar

.....

我怎样才能让每个程序找到好的库?

例如,根据我的实际配置,程序B将始终使用C-1.0.jar而不是C-2.0.jar,因为类路径上的优先级位置。

4 个答案:

答案 0 :(得分:5)

基本上你不能这样做(简单地说)。看看http://en.wikipedia.org/wiki/Java_Classloader#JAR_hell,他们解释说标准Java类加载器不能这样做。

你可以在不同的虚拟机上运行这两个进程,或者进入很多类加载器地狱......

答案 1 :(得分:5)

如果为两个程序启动两个单独的JVM实例,则不要使用相同的类路径!不是很明显吗?

您是否正在使用CLASSPATH环境变量?这是一个非常古老,过时的做法,你不应该这样做。使用-classpath命令行参数,这样您就可以轻松地为这两个程序使用不同的类路径。

旧答案: 假设你在讨论线程而不是进程:

最好的解决方案是修复A,B或C,以便A和B都可以使用相同版本的C.

或者,如果C的两个版本实际上有不同的行为,请为它们使用不同的包或类名。

如果你不能改变A,B或C,你应该考虑编写一个使用different classloaders用于A和B的包装器的技术解决方案,这样他们就会看到不同版本的C。

答案 2 :(得分:1)

您必须确保类路径中只有一个库。

最简单的方法是创建2个具有正确依赖关系的lib目录,并在启动脚本中为相应的进程引用所有jar文件。

这个简单的shell脚本会自动为您执行此操作:

MY_CLASSPATH=.

for i in /path/to/A/lib/*.jar
do
  MY_CLASSPATH=$MY_CLASSPATH:$i
done

java -cp $MY_CLASSPATH my.main

答案 3 :(得分:0)

我认为这些是Java Web应用程序,如果它们在WebLogic上运行,它们应该在WAR文件中。如果每个JAR版本都在其WAR文件的WEB-INF / lib中放置,则不会发生任何冲突。