Выполнение файла jar с несколькими библиотеками путей к классам из командной строки


у меня есть проект Maven, который генерирует файл jar и копирует все зависимости в target/lib папка. Я хочу выполнить этот проект на клиентской машине (windows). Итак, я скопировал myproject.jar до C:\xyz папка и все зависимости от . Как выполнить этот проект из командной строки клиента? Я пытался использовать 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.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.

Я думаю, если я укажу все зависимости в classpath (например java -cp lib\dep1.jar;dep2.jar), он будет избавьтесь от проблемы, но я не хочу этого делать, так как у меня уже есть 40 библиотек, и она может вырасти в будущих версиях. Есть ли лучший способ сделать это?

8   51   2012-10-22 23:10:15

8 ответов:

пусть 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 каталог для всех файлов внутри него и установить каждый файл unside lib на classpath

после этого запустите банку

источник для цикла в пакетном файле для получения информации о циклах

вы можете использовать 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 plugin.

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

наконец, вы можете создать файл с classpath в него с помощью dependency:classpath цель.

Я столкнулся с той же проблемой, но смог упаковать все зависимости в мой файл jar с помощью Плагин Maven Shade

это не будет работать 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 для запуска более одного приложения I не рекомендую делать это.