Какой файл класса java будет вызываться, если тот же класс упакован в два файла jar?

Я работаю над проектом с открытым исходным кодом. На данный момент у меня нет никакой настройки в любом классе. Поэтому, используя все файлы jars, предоставленные проектом opensource. Мой вопрос: если я модифицирую один файл java, скомпилирую его и упакую в новый файл jar с той же структурой папок, будет ли какая-либо проблема при запуске сервера или времени выполнения? Если не будет вызван файл класса (файл по умолчанию или мой файл класса java)?

Ответ 1

На самом деле это зависит от многих факторов:

  • Если оба jar файла находятся в одном и том же ClassLoader, например, Java classpath (опция -cp), обычно это должен быть первый файл, найденный в порядке списка jar файлов.

  • При развертывании в контейнере JavaEE, например, в файле EAR или в WEB-INF/lib или файле WAR, нет гарантии, что контейнер будет загружать один и тот же класс между двумя запусками. В этом контексте единственно верным является то, что WEB-INF/classes ищется до WEB-INF/lib

  • В сложной иерархии ClassLoader поведение по умолчанию - поиск в родительском режиме, но в реализациях JavaEE были введены такие механизмы, как политика родительского контроля (WebSphere) или фильтрация, благодаря дескрипторам развертывания (WebLogic, JBoss/WildFly)

Можно также объявить зависимости файла jar в файле META-INF/MANIFEST.MF благодаря атрибуту Class-Path. Он должен обеспечивать порядок загрузки на уровне ClassLoader, особенно при запуске с java -jar myapp.jar, но это может зависеть от реализаций в контексте JavaEE.

Примечание: при использовании проекта OpenSource может быть справедливым подать запрос на изменение и опубликовать ваши изменения или улучшения, чтобы сообщество получило от него выгоду. Тогда ваш проект может обновиться до основного потока без такой сложности диких патчей в вашем ClassPath.

Ответ 2

загрузчик классов ищет первое место, где находится необходимый ресурс. Это означает, что если класс с таким же именем и пакетом появится в 2 банок, будет найден первый найденный. Какой из них первый? В соответствии с classpath: если, например, класс A появляется в банках one.jar и two.jar, а ваша командная строка:

java -cp one.jar;two.jar MyMain`

будет использоваться версия из one.jar. Но если строка командной строки

java -cp two.jar;one.jar MyMain`

будет создан экземпляр класса из two.jar.