Подтвердить что ты не робот

Как работает JVM, когда в классpath

Это была ошибка моего коллеги: там была банка с именем test.jar, и он исправил ее ошибку. Затем он перекомпилирует код и построил новую банку с именем testnew.jar Проблема заключалась в том, что он поставил эти две банки в одну папку, которая в classpath. Поэтому, когда программа работала, поведение было своего рода беспорядком. Я не знал, что произошло, но после удаления test.jar все было в порядке.

Так что мне интересно, что такое поведение JVM. Использует ли он файл класса в первой банке, с которой он встречается? Или что-то другое?

Спасибо.

4b9b3361

Ответ 1

Да, по умолчанию он использует классы из первой банки. Вот почему вам нужно проверить библиотечный каталог для дубликатов. Так много раз для меня и моих коллег.

Ответ 2

Насколько я могу судить, он не определен.

Java имеет подключаемую систему загрузчика классов, и, таким образом, единственный способ узнать, что произойдет, - посмотреть документацию ClassLoader class, возможно, в частности метод ClassLoader#findClass, который не определяет поведение для этого, и посмотрите на соответствующие разделы JLS и спецификации JVM, ни один из которых не указывает ограничение на загрузчики классов в этом отношении. Таким образом, если поведение не документировано загрузчиком классов, используемым вашим веб-контейнером, вы не можете точно знать, какой класс будет загружен.

Скорее всего, первый найденный, который соответствует двоичному имени класса, будет загружен, но существует большая разница между поведением, которое, как мы полагаем, имеет место, и поведение, которое указанным и/или документированным.

Ответ 3

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

Edit Файл classpath вообще выглядит примерно так.

<classpath>
        <classpathentry kind="lib" path="C:/Temp/test.jar"/>
        <classpathentry kind="lib" path="C:/Temp/testnew.jar"/>
    <classpathentry kind="output" path="build/classes"/>
</classpath>

Если ваш путь к классам выглядит примерно так, ваш JVM сначала рассмотрит test.jar, так как он появится сначала в пути к классам. Если вы хотите протестировать его самостоятельно, попробуйте переместить classpathentry для testnew.jar над входом test.jar. Вы увидите, что теперь он ссылается на testnew.jar вместо test.jar.

Ссылка: FindingClasses

Ответ 4

JVM загружает все определенные JAR файлы в путь к классам. Так как java 6 также имеет подстановочный знак. Ниже приведены несколько примеров.

java -cp ".:lib/example.jar" Main

Вышеуказанное будет загружать только классы, найденные в текущем каталоге и внутри example.jar. Если следующий пример будет использовать любой jar для загрузки классов из.

java -cp ".:lib/*" Main

Я не думаю, что порядок, для которого jar в каталоге проверяется первым, чтобы найти класс, определен, который когда-либо заказывал ОС при перечислении файлов.

Скорее всего, ваша IDE (или что-то, что вы используете для запуска вашей программы) использует последнюю нотацию для запуска вашей программы. Вы можете изменить его так, чтобы он использовал первый, хотя он сломается, если вы когда-либо измените имя фляги или добавите новые.