Including all the jars in a directory within the Java classpath
Включение всех jar в каталог в пределах пути к классу Java
Есть ли способ включить все файлы jar в каталоге в classpath?
Я пытаюсь java -classpath lib/*.jar:. my.package.Program и не могу найти файлы классов, которые определенно находятся в этих jar. Нужно ли мне добавлять каждый jar-файл в classpath отдельно?
Переведено автоматически
Ответ 1
При использовании Java 6 или более поздней версии параметр classpath поддерживает подстановочные знаки. Обратите внимание на следующее:
Используйте прямые кавычки (")
Использовать *, а не *.jar
Windows
java -cp "Test.jar;lib/*" my.package.MainClass
Unix
java -cp "Test.jar:lib/*" my.package.MainClass
Это похоже на Windows, но использует : вместо ;. Если вы не можете использовать подстановочные знаки, bash допускается следующий синтаксис (где lib - каталог, содержащий все файлы архива Java):
Записи пути к классу могут содержать подстановочный знак basename *, который считается эквивалентным указанию списка всех файлов в каталоге с расширением .jar или .JAR. Например, запись пути к классу foo/* указывает все JAR-файлы в каталоге с именем foo. Запись classpath, состоящая просто из *, расширяется до списка всех jar-файлов в текущем каталоге.
Запись пути к классу, которая содержит *, не будет соответствовать файлам класса. Чтобы сопоставить оба класса и JAR-файлы в одном каталоге foo, используйте или foo;foo/* или foo/*;foo. Выбранный порядок определяет, загружаются ли классы и ресурсы в foo перед файлами JAR в foo, или наоборот.
Рекурсивный поиск в подкаталогах не выполняется. Например, foo/* ищет JAR-файлы только в foo, а не в foo/bar, foo/baz и т.д.
Порядок, в котором JAR-файлы в каталоге перечисляются в расширенном пути к классу, не указан и может варьироваться от платформы к платформе и даже от момента к моменту на одном и том же компьютере. Хорошо сконструированное приложение не должно зависеть от какого-либо определенного порядка. Если требуется определенный порядок, файлы JAR могут быть явно перечислены в пути к классу.
Расширение подстановочных знаков выполняется заранее, до вызова основного метода программы, а не позже, во время самого процесса загрузки класса. Каждый элемент входного пути к классу, содержащий подстановочный знак, заменяется (возможно, пустой) последовательностью элементов, сгенерированной путем перечисления JAR-файлов в именованном каталоге. Например, если каталог foo содержит a.jar, b.jar, и c.jar, то путь к классу foo/* расширяется в foo/a.jar;foo/b.jar;foo/c.jar, и эта строка будет значением системного свойства java.class.path.
CLASSPATH Переменная среды обрабатывается таким же образом, как и параметр -classpath (или -cp) командной строки. То есть во всех этих случаях используются подстановочные знаки. Однако подстановочные знаки пути к классу не учитываются в Class-Path jar-manifest заголовке.
Примечание: из-за известной ошибки в java 8, в примерах Windows перед записями должна использоваться обратная косая черта со звездочкой в конце: https://bugs.openjdk.java.net/browse/JDK-8131329
Обратите внимание на *.jar, поэтому подстановочный знак * следует использовать отдельно.
В Linux работает следующее:
java -cp "Test.jar:lib/*" my.package.MainClass
Разделителями являются двоеточия вместо точки с запятой.
Ответ 3
Мы решаем эту проблему путем развертывания основного jar-файла, myapp.jar который содержит файл манифеста (Manifest.mf), указывающий путь к классу, с другими необходимыми jar-файлами, которые затем развертываются вместе с ним. В этом случае вам нужно только объявить java -jar myapp.jar при запуске кода.
Итак, если вы развернете main jar в некоторый каталог, а затем поместите зависимые jar-файлы в lib папку под ним, манифест будет выглядеть следующим образом: