Включение всех jar-файлов в каталог в пути к классам Java

Есть ли способ включить все файлы jar в каталоге в путь к классам?

Я пробую java -classpath lib/*.jar:. my.package.Program, и он не может найти файлы классов, которые точно находятся в этих банках. Нужно ли мне добавлять каждый файл jar в путь к классам отдельно?

Извините, я никогда не принимал это. Это должна быть вики сообщества. Ни разу не использовал ни один из предоставленных ответов. Я считаю, что создал сценарий оболочки, который просто просканировал каталог lib / и создал путь к классам, проанализировав имена файлов.

Chris Serra 28.03.2011 19:02

В этой новой функции Java есть какая-то ошибка, потому что она не работает, как описано. Я сдался и использовал Ant, чтобы обойти это, как описано в одном из ответов.

Alex R 03.04.2011 04:17

В Windows есть проблема с обработкой подстановочных знаков. stackoverflow.com/questions/11607873/…

Mike 23.07.2012 12:44

Сначала я подумал, что . после jar: вставлен по ошибке, но ... Стандартный символ для `текущего каталога '- это одна точка (.) Как в системах Unix, так и в Windows.

KNU 20.11.2014 14:21

Краткий ответ: (1) отбросьте часть .jar, (2) должна быть как минимум 2 части, разделенные ; в Windows (обычно это : в другом месте). Например: java -classpath ".;lib/*" Program

Evgeni Sergeev 12.12.2014 04:38
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1 068
5
1 111 434
25

Ответы 25

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

Возможно, это был единственный путь в 2008 году, но не сейчас.

simo.3792 09.10.2014 09:31

Думайте о файле jar как о корне структуры каталогов. Да, вам нужно добавить их все по отдельности.

Если вам действительно нужно указать все файлы .jar динамически, вы можете использовать сценарии оболочки или Apache Ant. Есть общий проект под названием Commons Launcher, который в основном позволяет вам указать ваш сценарий запуска как файл сборки муравья (если вы понимаете, что я имею в виду).

Затем вы можете указать что-то вроде:

<path id = "base.class.path">
    <pathelement path = "${resources.dir}"/>
    <fileset dir = "${extensions.dir}" includes = "*.jar" />
    <fileset dir = "${lib.dir}" includes = "*.jar"/>
</path>

В вашем файле сборки запуска, который запустит ваше приложение с правильным путем к классам.

Мы обходим эту проблему, развертывая файл jar основнойmyapp.jar, который содержит файл манифест (Manifest.mf), определяющий путь к классам с другими необходимыми jar-файлами, которые затем развертываются вместе с ним. В этом случае вам нужно только объявить java -jar myapp.jar при запуске кода.

Итак, если вы развернете основной jar в какой-то каталог, а затем поместите зависимые банки в папку lib под ним, манифест будет выглядеть так:

Manifest-Version: 1.0
Implementation-Title: myapp
Implementation-Version: 1.0.1
Class-Path: lib/dep1.jar lib/dep2.jar

NB: это не зависит от платформы - мы можем использовать одни и те же jar-файлы для запуска на сервере UNIX или на ПК с Windows.

Кажется, что это работает для многих людей, однако Java, похоже, просто игнорирует записи Class-Path в файле манифеста здесь. Мы не можем запустить приложение, не добавив вручную «lib / *» в путь к классам с помощью -cp. Есть идеи?

Raku 12.10.2011 15:36

Ответ oxbow_lakes не совсем правильный; объект Class-Path соблюдается (и ТОЛЬКО это соблюдается; -cp / -classpath игнорируется!), если вы запускаете эту банку с java -jar myapp.jar. Я полагаю, что oxbow_lakes хотел написать это, когда писал «java -classpath myapp.jar».

rzwitserloot 08.01.2013 17:00

При использовании Java 6 или более поздней версии параметр classpath поддерживает подстановочные знаки. Обратите внимание на следующее:

  • Используйте прямые кавычки (")
  • Используйте *, а не *.jar

Окна

java -cp "Test.jar;lib/*" my.package.MainClass

Unix

java -cp "Test.jar:lib/*" my.package.MainClass

Это похоже на Windows, но использует : вместо ;. Если вы не можете использовать подстановочные знаки, bash допускает следующий синтаксис (где lib - это каталог, содержащий все файлы архива Java):

java -cp "$(printf %s: lib/*.jar)"

(Обратите внимание, что использование пути к классам несовместимо с опцией -jar. См. Также: Выполнить файл jar с несколькими библиотеками пути к классам из командной строки)

Понимание подстановочных знаков

Из документа Путь к классам:

Class path entries can contain the basename wildcard character *, which is considered equivalent to specifying a list of all the files in the directory with the extension .jar or .JAR. For example, the class path entry foo/* specifies all JAR files in the directory named foo. A classpath entry consisting simply of * expands to a list of all the jar files in the current directory.

A class path entry that contains * will not match class files. To match both classes and JAR files in a single directory foo, use either foo;foo/* or foo/*;foo. The order chosen determines whether the classes and resources in foo are loaded before JAR files in foo, or vice versa.

Subdirectories are not searched recursively. For example, foo/* looks for JAR files only in foo, not in foo/bar, foo/baz, etc.

The order in which the JAR files in a directory are enumerated in the expanded class path is not specified and may vary from platform to platform and even from moment to moment on the same machine. A well-constructed application should not depend upon any particular order. If a specific order is required then the JAR files can be enumerated explicitly in the class path.

Expansion of wildcards is done early, prior to the invocation of a program's main method, rather than late, during the class-loading process itself. Each element of the input class path containing a wildcard is replaced by the (possibly empty) sequence of elements generated by enumerating the JAR files in the named directory. For example, if the directory foo contains a.jar, b.jar, and c.jar, then the class path foo/* is expanded into foo/a.jar;foo/b.jar;foo/c.jar, and that string would be the value of the system property java.class.path.

The CLASSPATH environment variable is not treated any differently from the -classpath (or -cp) command-line option. That is, wildcards are honored in all these cases. However, class path wildcards are not honored in the Class-Path jar-manifest header.

Примечание: из-за известной ошибки в java 8 в примерах Windows должна использоваться обратная косая черта перед записями со звездочкой в ​​конце: https://bugs.openjdk.java.net/browse/JDK-8131329

На самом деле мы сейчас используем Java 5. Но это полезно знать на будущее, спасибо за подсказку!

Chris Serra 21.10.2008 08:25

Потрясающий. У меня работает что-то вроде этого: java -cp target / classes; target / lib / * de.byteconsult.Main

Tom 19.11.2010 14:58

Эта функция плохо документирована и, похоже, требует выполнения некоторых менее чем очевидных предварительных условий, чтобы она работала должным образом.

Alex R 03.04.2011 04:20

Лорд Торгамус ниже приводит пример и объяснение.

Ellen Spertus 12.06.2012 22:54

Вы также можете использовать find: cp=$(find /path/to/std/jars /path/to/your/jar -not -type d -printf "%p:")

JohnnyLambada 16.08.2012 01:01

+1 за последний трюк bash / tr. Java / JamVM здесь не любит подстановочные знаки для путей за пределами рабочего каталога, но явная ссылка на каждый JAR с помощью подстановочного знака оболочки + tr работает!

Supr 15.05.2013 17:13

У меня есть команда java -classpath /jars/*:/anotherJarsDir/* com.test.MyClass без кавычек, и она отлично работает. Мне интересно, почему оболочка не расширяет ее и не выходит из строя?

yellavon 03.03.2014 18:01

Имейте в виду, что java -cp "Test.jar;lib/*" my.package.MainClass работает, но если параметр classpath указан как второй аргумент, он не работает (java my.package.MainClass -cp "Test.jar;lib/*").

AndiDog 26.03.2015 00:56

Также не используйте ~ в -cp

Sohail Si 10.08.2015 23:01

Следующее также недействительно java -cp = "" как вы используете в set classpath = ""

manifold 18.07.2016 11:36

В bash следует использовать одинарные кавычки

Konstantin Pelepelin 05.05.2018 15:11

Ваш пример Windows не работает с java 8 или более ранней версией, но будет с этим путем к классам: Test.jar; lib \ * ... прямая косая черта в порядке, за исключением случаев, когда перед звездочкой и некоторыми другими ... см. bugs.openjdk.java.net/browse/JDK-8131329

philwalk 18.07.2018 19:32

В Cygwin нам нужно использовать разделитель точка с запятой (;) вместо двоеточия (:)

Peter 19.06.2019 18:34

@basszero С двойными кавычками, он работал на MacOS 10.15.2 Catalina. Спасибо :) +1 за это.

Anish B. 04.01.2020 20:17

как насчет более старой версии, чем java 6 @basszero

Aman 21.03.2020 14:31

java -cp "Test.jar; lib / *" my.package.MainClass не будет ли это искать дочерние папки в lib? Например, моя банка находится в каталоге lib / org / abc.jar

Hardik Rana 20.08.2020 09:46

Единственный способ, которым я знаю, как это делать индивидуально, например:

setenv CLASSPATH /User/username/newfolder/jarfile.jar:jarfile2.jar:jarfile3.jar:.

Надеюсь, это поможет!

Возможно, это был единственный путь в 2008 году, но не сейчас.

simo.3792 09.10.2014 09:30

Это не самое страшное. Это хак, но у меня в bashrc for jar in $(ls $HOME/bin/*.jar); do export CLASSPATH=$jar:$CLASSPATH; done есть такой набор

Devon Peticolas 07.04.2015 02:44

Под Windows это работает:

java -cp "Test.jar;lib/*" my.package.MainClass

и это не работает:

java -cp "Test.jar;lib/*.jar" my.package.MainClass

Обратите внимание на *.jar, поэтому подстановочный знак * следует использовать отдельно.


В Linux работает следующее:

java -cp "Test.jar:lib/*" my.package.MainClass

Разделителями являются двоеточия вместо точка с запятой.

Идеальный ответ. 2 важных момента, на которые следует обратить внимание: 1) Используйте кавычки и 2) Используйте только *, а не * .jar

Wim Deblauwe 03.12.2012 14:20

Год и 8 месяцев спустя редактирование, которое я сделал, чтобы включить версию для UNIX, снова спасло меня. :) Забавно, как он не распознавал мои jar-файлы с *.jar, а только с *.

jmort253 29.09.2013 04:12

Я обнаружил, что порядок путей к классам важен (но я не знаю почему). Я получал ошибки, пока не поменял порядок путей к классам.

user13107 19.03.2014 11:27

@ jmort253, дело в том, что это не оболочка * расширяется, а подстановочный знак - это java, анализирующая путь к классам, видя * и заполняя подстановочный знак

Sebastian 08.05.2014 23:29

@SebastianGodelet - Ага, я просто запутался между подстановочными знаками Regex и этой нотацией, что, я думаю, не то же самое. В основном меня спасло знание разницы между : на одной платформе и ; на другой. :) Я компилирую Java из командной строки примерно раз в год, ровно столько, чтобы не вспоминать, сколько еще, достаточно часто, чтобы раздражать.

jmort253 08.05.2014 23:33

java -cp "Test.jar; lib / *" my.package.MainClass не будет ли это искать дочерние папки в lib? Например, моя банка находится в каталоге lib / org / abc.ja

Hardik Rana 20.08.2020 10:14

Для окон требуются кавычки и; следует использовать как разделитель. например.:

java -cp "target\\*;target\\dependency\\*" my.package.Main

Можете попробовать java -Djava.ext.dirs=jarDirectoryhttp://docs.oracle.com/javase/6/docs/technotes/guides/extensions/spec.html

Каталог для внешних jar-файлов при запуске java

Это работает, но будьте осторожны, передайте -Djava.ext.dirs= ПЕРЕД -jar.

Giovanni Funchal 04.06.2010 17:31

java.ext.dirs будет работать совсем иначе, чем обычный jar в пути к классам. У него более высокий приоритет и разрешение, которое сможет каким-то образом переопределить классы в bootstamp (rt.jar).

Dennis C 30.11.2010 04:56

Спасибо. В 'java версии «1.8.0_221» Java (TM) SE Runtime Environment (build 1.8.0_221-b27) Java HotSpot (TM) 64-Bit Server VM (build 25.221-b27, смешанный режим) », только эта версия -D прохождения в пути к классам сработало. Традиционная форма - нет.

Matt Campbell 06.11.2019 01:29

Если вы используете Java 6, вы можете использовать подстановочные знаки в пути к классам.

Теперь можно использовать подстановочные знаки в определении пути к классам:

javac -cp libs/* -verbose -encoding UTF-8 src/mypackage/*.java  -d build/classes

Ссылка: http://www.rekk.de/bloggy/2008/add-all-jars-in-a-directory-to-classpath-with-java-se-6-using-wildcards/

Мое решение на Ubuntu 10.04 с использованием java-sun 1.6.0_24 со всеми банками в каталоге "lib":

java -cp .:lib/* my.main.Class

Если это не удается, следующая команда должна работать (распечатывает все * .jars в каталоге lib в параметр classpath)

java -cp $(for i in lib/*.jar ; do echo -n $i: ; done). my.main.Class

забавная записка. java -cp lib / * my.main.Class всегда будет терпеть неудачу, потому что расширение glob оболочки для lib / *, в то время как java -cp.: lib / * my.main.Class не будет, потому что.: lib / * не является допустимым glob путь. Обратите внимание на то, что

albfan 23.03.2012 02:03

Это не работает; linux расширит . вы можете попробовать: java -cp '.: lib / ', и это отлично работает (обратите внимание на одинарные кавычки! Это не будет работать с двойными кавычками!). На самом деле,.: Lib / * может работать, если это недопустимый глобус из-за двоеточия, но это кажется немного сомнительным. Я бы добавил цитаты. Одиночные кавычки говорят bash не касаться какой-либо части содержимого.

rzwitserloot 08.01.2013 17:01

Не имеет значения (в данном контексте), используете ли вы одинарные или двойные кавычки. Вы хотите, чтобы оболочка не расширяла (подтасовывала) символ *, вот и все. И передайте JVM буквально «lib / *», чтобы виртуальная машина распознала это как «специальный шаблон» и самостоятельно начала поиск файлов jar.

Angel O'Sphere 30.05.2016 16:05

Все вышеперечисленные решения отлично работают, если вы разрабатываете и запускаете приложение Java вне любой IDE, такой как Eclipse или Netbeans.

Если вы работаете в Windows 7 и используете Eclipse IDE для разработки на Java, вы можете столкнуться с проблемами при использовании командной строки для запуска файлов классов, созданных внутри Eclipse.

Например. Ваш исходный код в Eclipse имеет следующую иерархию пакетов: edu.sjsu.myapp.Main.java

У вас есть json.jar как внешняя зависимость для Main.java

Когда вы пытаетесь запустить Main.java из Eclipse, он будет работать без каких-либо проблем.

Но когда вы попытаетесь запустить это с помощью командной строки после компиляции Main.java в Eclipse, он выдаст несколько странных ошибок, в которых говорится: «Ошибка ClassNotDef бла-бла».

Я предполагаю, что вы находитесь в рабочем каталоге исходного кода !!

Используйте следующий синтаксис для запуска из командной строки:

  1. javac -cp ".;json.jar" Main.java

  2. java -cp ".;json.jar" edu.sjsu.myapp.Main

    [Не пропустите. над]

Это потому, что вы поместили Main.java в пакет edu.sjsu.myapp, и java.exe будет искать точный шаблон.

Надеюсь, это поможет !!

Краткий ответ: java -classpath lib/*:. my.package.Program

Oracle предоставляет документацию по использованию подстановочных знаков в путях к классам здесь для Java 6 и здесь для Java 7 под заголовком раздела Общие сведения о подстановочных знаках пути к классам. (Пока я пишу это, две страницы содержат одинаковую информацию.) Вот краткое изложение основных моментов:

  • В общем, чтобы включить все JAR в данный каталог, вы можете использовать подстановочный знак * (нет*.jar).

  • Подстановочный знак соответствует только JAR, но не файлам классов; чтобы получить все классы в каталоге, просто завершите запись пути к классам именем каталога.

  • Вышеупомянутые два параметра могут быть объединены для включения всех файлов JAR и классов в каталог, при этом применяются обычные правила приоритета пути к классам. Например. -cp /classes;/jars/*

  • Подстановочный знак будет нет искать JAR в подкаталогах.

  • Приведенные выше пункты верны, если вы используете системное свойство CLASSPATH или флаги командной строки -cp или -classpath. Однако, если вы используете заголовок манифеста Class-Path JAR (как вы могли бы сделать с файлом сборки ant), подстановочные знаки будут учтены.

Да, моя первая ссылка та же, что и в ответе, получившем наибольшее количество баллов (который у меня нет надежды обогнать), но этот ответ не дает подробного объяснения, кроме ссылки. Поскольку такое поведение является обескураженный при переполнении стека В эти дни, я подумал, что я бы расширил его.

моя проблема была с lib / *. jar, а не с lib / *. Большое спасибо, что это исправлено. Я заметил разницу между: и; но это могло быть моим делом «тестирование множества изменений одновременно».

Eyad Ebrahim 19.09.2012 12:05

Спасибо, что подчеркнули разницу между * и * .jar

burak 10.08.2018 14:56

Я не уверен, зачем нужна дополнительная запись пути к классам для "." исправил мою проблему, но теперь он работает. "." - это тот же каталог, что и каталог, который я указал с подстановочным знаком. Я не понимаю, почему это имеет значение, но это имело значение. Спасибо!

Datbates 20.07.2020 19:24

Правильный:

java -classpath "lib/*:." my.package.Program

Неправильно:

java -classpath "lib/a*.jar:." my.package.Program
java -classpath "lib/a*:."     my.package.Program
java -classpath "lib/*.jar:."  my.package.Program
java -classpath  lib/*:.       my.package.Program

java -classpath "lib / * :." my.package.Program у меня работает

Mugeesh Husain 11.06.2020 06:54

Для меня это работает в окнах.

java -cp "/lib/*;" sample

Для linux

java -cp "/lib/*:" sample

Я использую Java 6

пример Windows, похоже, работал для java 6, возможно, java 7, но не для java 8 (см. bugs.openjdk.java.net/browse/JDK-8131329)

philwalk 18.07.2018 22:46

Работает для java 8 в Linux

Jonathan Drapeau 11.01.2019 17:15

java -cp "Test.jar; lib / *" my.package.MainClass не будет ли это искать дочерние папки в lib? Например, моя банка находится в каталоге lib / org / abc.ja

Hardik Rana 20.08.2020 10:14

Краткая форма: если ваш main находится внутри jar, вам, вероятно, понадобится дополнительный '-jar pathTo / yourJar / YourJarsName.jar', явно объявленный, чтобы заставить его работать (даже если 'YourJarsName.jar' был в пути к классам) (или, выраженный, чтобы ответить на исходный вопрос, который был задан 5 лет назад: вам не нужно повторно объявлять каждую банку явно, но кажется, даже с java6 вам нужно повторно объявить свою собственную банку ...)


Полная форма: (Я сделал это явным до такой степени, что надеюсь, что даже нарушители Java могут использовать это)

Как и многие здесь, я использую eclipse для экспорта jar-файлов: (Файл-> Экспорт -> «Запускаемый файл JAR»). В eclipse (Juno) есть три варианта работы с библиотекой:

opt1: "Extract required libraries into generated JAR"
opt2: "Package required libraries into generated JAR"
opt3: "Copy required libraries into a sub-folder next to the generated JAR"

Обычно я использовал opt2 (а opt1 определенно ломался), однако в собственном коде одной из используемых мною jar я обнаружил разрывы с помощью удобного трюка jarinjar, который eclipse использует, когда вы выбираете этот вариант. Даже после того, как я понял, что мне нужен opt3, а затем нашел эту запись в StackOverflow, мне все же потребовалось некоторое время, чтобы понять, как запустить мой main за пределами eclipse, поэтому вот что сработало для меня, так как это полезно для других ...


Если вы назвали свою банку: "fooBarTheJarFile.jar" и все настроено на экспорт в каталог: "/ theFully / qualifiedPath / toYourChosenDir".

(это означает, что в поле «Место назначения экспорта» будет указано: «/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar»)

После того, как вы нажмете «Готово», вы обнаружите, что eclipse помещает все библиотеки в папку с именем fooBarTheJarFile_lib в этом каталоге экспорта, что дает вам что-то вроде:

/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar
/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/SomeOtherJar01.jar
/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/SomeOtherJar02.jar
/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/SomeOtherJar03.jar
/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/SomeOtherJar04.jar

Затем вы можете запускать из любой точки вашей системы с помощью:

java -classpath "/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/*" -jar  /theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar   package.path_to.the_class_with.your_main.TheClassWithYourMain

(Для новичков в Java: 'package.path_to.the_class_with.your_main' - это объявленный путь к пакету, который вы найдете в верхней части файла 'TheClassWithYourMain.java', который содержит 'main (String [] args) {.. .} ', который вы хотите запустить извне java)


Обратите внимание на ловушку: недостаточно иметь 'fooBarTheJarFile.jar' в списке jar-файлов в объявленном пути к классам. Вам нужно явно объявить '-jar' и повторно объявить местоположение этого jar-файла.

например это ломается:

 java -classpath "/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar;/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/*"  somepackages.inside.yourJar.leadingToTheMain.TheClassWithYourMain

пересчитывается с относительными путями:

cd /theFully/qualifiedPath/toYourChosenDir/;
BREAKS:  java -cp "fooBarTheJarFile_lib/*"                                package.path_to.the_class_with.your_main.TheClassWithYourMain    
BREAKS:  java -cp ".;fooBarTheJarFile_lib/*"                              package.path_to.the_class_with.your_main.TheClassWithYourMain   
BREAKS:  java -cp ".;fooBarTheJarFile_lib/*"   -jar                       package.path_to.the_class_with.your_main.TheClassWithYourMain   
WORKS:   java -cp ".;fooBarTheJarFile_lib/*"   -jar  fooBarTheJarFile.jar package.path_to.the_class_with.your_main.TheClassWithYourMain   

(с использованием версии java "1.6.0_27"; через виртуальную машину 64-разрядного сервера OpenJDK в ubuntu 12.04)

Обратите внимание, что расширение подстановочных знаков не работает для Java 7 в Windows.

Посетите эта проблема StackOverflow для получения дополнительной информации.

Обходной путь - поставить точку с запятой сразу после подстановочного знака. java -cp "somewhere/*;"

Для предъявления по месту требования,

Я обнаружил это странное поведение в Windows под оболочкой MSYS / MinGW.

Работает:

$ javac -cp '.;c:\Programs\COMSOL44\plugins\*' Reclaim.java

Не работает:

$ javac -cp 'c:\Programs\COMSOL44\plugins\*' Reclaim.java
javac: invalid flag: c:\Programs\COMSOL44\plugins\com.comsol.aco_1.0.0.jar
Usage: javac <options> <source files>
use -help for a list of possible options

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

$ echo './*'
./*

(Пробовал и с другой программой, а не со встроенным echo, с тем же результатом.)

Я считаю, что это javac, который пытается его расширить, и он ведет себя по-разному, есть ли в аргументе точка с запятой или нет. Во-первых, он может пытаться расширить все аргументы, которые выглядят как пути. И только после этого он их проанализирует, а -cp получит только следующий токен. (Обратите внимание, что com.comsol.aco_1.0.0.jar является вторым JAR в этом каталоге.) Это все предположение.

Это

$ javac -version
javac 1.7.0

класс из веб-приложения:

  > mvn clean install

  > java -cp "webapp/target/webapp-1.17.0-SNAPSHOT/WEB-INF/lib/tool-jar-1.17.0-SNAPSHOT.jar;webapp/target/webapp-1.17.0-SNAPSHOT/WEB-INF/lib/*" com.xx.xx.util.EncryptorUtils param1 param2

Это не прямое решение проблемы установки / * в -cp, но я надеюсь, что вы могли бы использовать следующий сценарий, чтобы немного облегчить ситуацию для динамических путей к классам и каталогов lib.

 libDir2Scan4jars = "../test";cp = ""; for j in `ls ${libDir2Scan4jars}/*.jar`; do if [ "$j" != "" ]; then cp=$cp:$j; fi; done; echo $cp| cut -c2-${#cp} > .tmpCP.tmp; export tmpCLASSPATH=`cat .tmpCP.tmp`; if [ "$tmpCLASSPATH" != "" ]; then echo .; echo "classpath set, you can now use  ~>         java -cp \$tmpCLASSPATH"; echo .; else echo .; echo "Error please check libDir2Scan4jars path"; echo .; fi; 

Сценарий для Linux, может быть аналогичный и для Windows. Если правильный каталог указан в качестве входных данных для "libDir2Scan4jars"; сценарий просканирует все jar-файлы, создаст строку пути к классам и экспортирует ее в переменную env "tmpCLASSPATH".

Установите путь к классам подходящим образом для нескольких jar-файлов и файлов классов текущего каталога.

CLASSPATH=${ORACLE_HOME}/jdbc/lib/ojdbc6.jar:${ORACLE_HOME}/jdbc/lib/ojdbc14.jar:${ORACLE_HOME}/jdbc/lib/nls_charset12.jar; 
CLASSPATH=$CLASSPATH:/export/home/gs806e/tops/jconn2.jar:.;
export CLASSPATH

Окна:

 java -cp file.jar;dir/* my.app.ClassName

Linux:

 java -cp file.jar:dir/* my.app.ClassName

Напомнить:
- разделитель пути Окна - ;
- разделитель пути Linux - :
- В Windows, если аргумент cp не содержит пробелов, "кавычки" указывать необязательно.

пример Windows не работает для Java 8 и ранее: см. bugs.openjdk.java.net/browse/JDK-8131329

philwalk 18.07.2018 19:34

Возможно, не работает для открытого JDK, я протестирую это и расскажу здесь

Wender 18.07.2018 21:31

Извините, я тестировал HotSpot и думал, что он работает с openjdk.

Wender 17.09.2018 21:15

Oracle java под Windows требует обратной косой черты перед звездочкой, а не прямой косой черты, хотя я не повторно тестировал самые последние или альтернативные версии java.

philwalk 21.09.2018 18:37

java -cp "Test.jar; lib / *" my.package.MainClass не будет ли это искать дочерние папки в lib? Например, моя банка находится в каталоге lib / org / abc.ja

Hardik Rana 20.08.2020 10:14

У меня в папке несколько банок. Приведенная ниже команда работала для меня в JDK1.8, чтобы включить все банки, присутствующие в папке. Обратите внимание, что для включения в кавычки, если у вас есть пробел в пути к классам

Окна

Компиляция: javac -classpath "C:\My Jars\sdk\lib\*" c:\programs\MyProgram.java

Бег: java -classpath "C:\My Jars\sdk\lib\*;c:\programs" MyProgram

Linux

Компиляция: javac -classpath "/home/guestuser/My Jars/sdk/lib/*" MyProgram.java

Бег: java -classpath "/home/guestuser/My Jars/sdk/lib/*:/home/guestuser/programs" MyProgram

macOS, текущая папка

Для Java 13 на macOS Mojave

Если все ваши файлы .jar находятся в одной папке, используйте cd, чтобы сделать это вашим текущий рабочий каталог. Подтвердите с помощью pwd.

Для -classpath вы должны сначала указать Файл JAR для вашего приложения. Используя символ двоеточия : в качестве разделителя, добавьте звездочку *, чтобы получить все остальные файлы JAR в той же папке. Наконец, передайте полное имя пакета класса с вашим main метод.

Например, для приложения в файле JAR с именем my_app.jar с методом main в классе с именем App в пакете с именем com.example вместе с некоторыми необходимыми банками в той же папке:

java -classpath my_app.jar:* com.example.App

Также важен порядок аргументов команды java:

c:\projects\CloudMirror>java Javaside -cp "jna-5.6.0.jar;.\"
Error: Unable to initialize main class Javaside
Caused by: java.lang.NoClassDefFoundError: com/sun/jna/Callback

против

c:\projects\CloudMirror>java -cp "jna-5.6.0.jar;.\" Javaside
Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable

Другие вопросы по теме