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