Компиляция Java и JAR

Недавно я задал вопрос о распространении исполняемых JAR-файлов и их зависимостей, и это заставило меня понять, что мое понимание JAR-файлов может быть в корне ошибочным.

Таким образом, некоторые могут сказать: «Привет! Это дублирующийся вопрос!». Но я говорю «нет», этот вопрос является совершенно отдельным ответвлением этот исходный вопрос, касающийся основ Java!

Если у меня есть приложение, которое зависит, скажем, от CLI Apache Commons, а также от JODA Time, и я упаковываю это приложение в распространяемый JAR, мой первоначальный вопрос был таким: Без включения CLI и JODA JAR в мой JAR , как программа работает на стороне клиента???

Теперь я думаю, что, поскольку мой код, который использует CLI и JODA, компилируется в файлы классов, и этот байт-код - это то, что упаковывается, то нет необходимости включать CLI или JODA (или любой другой сторонний JAR) в мой JAR, так как теперь все это функционирующий байт-код.

Может ли кто-нибудь подтвердить или исправить меня? Это откровение, хотя и запоздалое, ошеломляет.


person IAmYourFaja    schedule 06.09.2011    source источник
comment
.jar в основном представляет собой .zip, поэтому я предлагаю вам поэкспериментировать самостоятельно, распаковав несколько файлов .jar и посмотреть, что внутри. Обратите внимание, что вы можете поместить банки в банку, но вам нужно либо написать свой собственный загрузчик классов (или использовать программу, которая сделает все это за вас). Другой способ - поместить .class (то есть байт-код), от которого вы зависите, в свой .jar (не рекомендуется, но это сработает).   -  person SyntaxT3rr0r    schedule 06.09.2011
comment
@Mara: кстати, ваши файлы .class НЕ содержат полные библиотеки CLI и JODA. Файлы .class имеют зависимости: вам понадобятся либо файлы .class из CLI и JODA в вашем .jar, либо CLI и JODA .jar где-нибудь. Эти зависимости будут разрешены (или будут пытаться быть разрешены) при запуске файла .jar. Загрузчик классов по умолчанию проверит в нескольких местах (в путях, внутри вашего .jar, в банках внутри jar, если у вас есть собственный загрузчик классов и т. д.) и посмотрите, может ли он разрешить ваши зависимости .   -  person SyntaxT3rr0r    schedule 06.09.2011
comment
@Mara, если вы думаете о классической «связке» C, этого не происходит во время компиляции Java. Что-то смутно похожее происходит во время выполнения.   -  person Dilum Ranatunga    schedule 06.09.2011


Ответы (2)


Нет, это не совсем так. Ключ ко всему — путь к классам. Находится ли весь скомпилированный код и/или другие ресурсы в пути к классам? Если вы упаковываете все в один jar, то да, он находится в пути к классам, и JVM найдет все ресурсы для запуска. В противном случае вам нужно указать (с файлом .bat или .sh или чем-то еще) все ресурсы, от которых зависит ваше приложение, чтобы JVM могла соответствующим образом искать эти ресурсы (будь то код Java или файлы свойств или что-то еще). ).

Кроме того, если я правильно понимаю ваш вопрос, предполагаете ли вы, что код CLI и JODA скомпилирован в ваш код? Если это так, то я ненавижу лопать ваш пузырь, но это не так. Когда ваш код компилируется, он не добавляет зависимостей (не в том смысле, в каком вы могли подумать). Что он делает на концептуальном уровне (поправьте меня, если я ошибаюсь, гуру JVM), так это ссылки на другие классы. Эти ссылки — это то, что вы создаете, когда кодируете класс и компилируете его. Во время выполнения JVM попытается найти скомпилированный класс за ссылкой, и именно здесь вам нужна банка с этими классами в пути к классам ИЛИ вам нужны эти классы в вашей исполняемой банке.

Есть смысл?

person Chris Aldrich    schedule 06.09.2011
comment
Крис Тиос имеет смысл - и спасибо! Но теперь я думаю, что я так запутался, что не знаю, что спросить... В Eclipse у меня есть все JAR-файлы в пути к классам, поэтому Eclipse знает, как ссылаться на все нужные ресурсы. В моем файле Ant build.xml, как добавить файлы JAR в путь к классам (изнутри Ant), чтобы все работало идеально, когда мой исполняемый файл JAR запускается как автономный инструмент командной строки? - person IAmYourFaja; 06.09.2011
comment
Java использует путь к классам, чтобы знать, где искать файлы .class. Обычно вы добавляете файлы .jar в путь к классам, и Java загружает эти файлы. Вы можете задать путь к классу одним из нескольких способов. В вашей ситуации вы должны установить атрибут Class-Path в файле MANIFEST.MF. Муравей может помочь вам здесь. Просто добавьте элемент manifest к задаче jar и установите атрибуты Main-Class и Class-Path. Подробнее см. здесь: ant.apache.org/manual/Tasks/jar.html< /а> - person Jack Edmonds; 06.09.2011

Сторонние библиотеки (например, JodaTime) должны находиться в пути к классам во время выполнения. Не «упаковано в ваш JAR».

Если ваше приложение запускается из JAR. Вы должны указать путь к классам в файле манифеста, который упакован в jar - http://download.oracle.com/javase/tutorial/deployment/jar/downman.html

Вы можете заставить ANT сгенерировать для вас путь к классам манифеста, используя элемент manifestclasspathhttp://ant.apache.org/manual/Tasks/manifestclasspath.html

person Liggy    schedule 06.09.2011