управление конфликтом на Java classpath

Я раскрываю свой контекст:

У меня есть две Java-программы, которые работают на уникальном сервере Weblogic: программа A и программа B. Эти запускаются двумя ksh:

програмить.ksh и programB.КШ

оба нужны C.jar но в разных версиях (но с точно таким же пакетом и классами) :

  • запрограммировать потребность C-1.0.Джар
  • программа B нужна C-2.0.Джар

я уточняю, что обе программы разделяют одно и то же для WebLogic классов.

Итак, мой путь к классам содержит в этом порядке:

.....

C-1.0.Джар

C-2.0.Джар

.....

Как я могу сделать так, чтобы каждая программа находила свою хорошую библиотеку ?

например, с моей фактической конфигурацией программа B всегда будет использовать C-1.0.jar вместо C-2.0.jar из-за приоритетной позиции на classpath.

4 ответов


Если вы запускаете два отдельных экземпляра JVM для двух программ,тогда не используйте тот же путь к классам! разве это не очевидно?

возможно, вы используете переменную среды CLASSPATH? Это очень старая, устаревшая практика, и вы не должны делать это. используйте параметр командной строки-classpath, таким образом, вы можете легко использовать разные пути к классам для двух программ.

ответ: Предполагая, что вы говорите о потоках, а чем процессы:

лучшим решением было бы исправить A, B или C, чтобы оба A и B могли использовать одну и ту же версию C.

или, если две версии C действительно имеют намеренно различное поведение, используйте для них разные имена пакетов или классов.

только если вы не можете изменить A, B или C, вы должны рассмотреть техническое решение написания оболочки, которая использует разные загрузчики классов для A и B, чтобы они видели разные версии С.


в основном вы не можете этого сделать (просто). Взгляните на http://en.wikipedia.org/wiki/Java_Classloader#JAR_hell, где они объясняют, что стандартный загрузчик классов Java не может этого сделать.

вы можете либо запустить два процесса на разных VMs, либо пойти в ад загрузчика классов...


вам нужно будет убедиться, что на пути к классам присутствует только одна библиотека.

самый простой способ-создать 2 каталога lib с правильными зависимостями и ссылаться на все банки оттуда в сценарии запуска для соответствующего процесса.

этот простой скрипт будет делать это за вас автоматически:

MY_CLASSPATH=.

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

java -cp $MY_CLASSPATH my.main

Я бы предположил, что это веб-приложения Java, если они работают на WebLogic, они должны быть в файлах WAR. Не будет никакого столкновения, если каждый из них помещает свои соответствующие версии JAR в WEB-INF/lib своего файла WAR.