Ответ 1
Пусть maven создает пакетный файл для запуска вашего приложения. Это самый простой способ этого.
Вы можете использовать appassembler-maven-plugin для таких целей.
У меня есть проект Maven, который создает файл jar и копирует все зависимости в папку target/lib
. Я хочу выполнить этот проект на клиентской машине (окнах). Итак, я скопировал папку myproject.jar
в C:\xyz
и все зависимости в папку C:\xyz\lib
. Как выполнить этот проект из командной строки клиента?
Я попытался использовать java -cp lib\*.jar -jar myproject.jar
из C:\xyz
, но он выдает следующую ошибку.
Exception in thread "main" java.lang.NoClassDefFoundError: lib\commons-codec-1/3/jar
Caused by: java.lang.ClassNotFoundException: lib\commons-codec-1.3.jar
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
Could not find the main class: lib\commons-codec-1.3.jar. Program will exit.
Я думаю, что если я укажу все зависимости в пути к классам (например, java -cp lib\dep1.jar;dep2.jar
), он избавится от проблемы, но я не хочу этого делать, поскольку у меня уже 40 библиотек, и это может расти в будущих выпусках. Есть ли лучший способ сделать это?
Пусть maven создает пакетный файл для запуска вашего приложения. Это самый простой способ этого.
Вы можете использовать appassembler-maven-plugin для таких целей.
Вы не можете использовать как -jar
, так и -cp
в командной строке - см. документацию java, в которой говорится, что если вы используете -jar
:
JAR файл является источником всех пользовательских классов, а другие параметры пути к пользовательскому классу игнорируются.
Вы можете сделать что-то вроде этого:
java -cp lib\*.jar;. myproject.MainClass
Обратите внимание на ;.
в аргументе -cp
, чтобы обойти ошибку командной строки Java. Также обратите внимание, что это версия для Windows. Разделитель путей в Unix равен :
.
Использование java 1.7, в UNIX -
java -cp myjar.jar:lib/*:. mypackage.MyClass
В Windows вам нужно использовать ';' вместо ':' -
java -cp myjar.jar;lib/*;. mypackage.MyClass
возможным решением может быть
создать пакетный файл
существует цикл в каталоге lib для всех файлов внутри него и задает каждый файл с помощью lib на пути к классу
то после этого запустите jar
source для цикла в пакетном файле для информации о циклах
Вы можете использовать maven-assembly-plugin, вот пример с официального сайта: https://maven.apache.org/plugins/maven-assembly-plugin/usage.html
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>your main class</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
Существует несколько вариантов.
Самый простой вариант - плагин exec.
Вы также можете создать банку, содержащую все зависимости, используя плагин сборки .
Наконец, вы можете сгенерировать файл с помощью пути к нему с помощью цели dependency:classpath
.
Я столкнулся с той же проблемой, но смог упаковать все зависимости в файл jar, используя Maven Shade Plugin
Независимо от ОС команда ниже должна работать:
java -cp "MyJar.jar;lib/*" com.mainClass
Всегда используйте кавычки и обратите внимание, что lib/*. Jar не будет работать.
Это не сработает java -cp lib\*.jar -jar myproject.jar
. Вы должны положить его в банку.
Итак, в случае commons-codec-1.3.jar
.
java -cp lib/commons-codec-1.3.jar;lib/next_jar.jar
и т.д.
Другое решение может помещать все ваши банки в каталог ext
вашей JRE. Это нормально, если вы используете автономную JRE. Если вы используете одну и ту же JRE для запуска более одного приложения, я не рекомендую делать это.