Различия между «java -cp» и «java -jar»?

118

В чем разница между запуском Java-приложения с помощью
java -cp CLASSPATHи java -jar JAR_FILE_PATH? Один из них предпочтительнее другого для запуска приложения Java? Я имею в виду, какой из этих способов дороже для JVM (в зависимости от использования их машинных ресурсов)?

Какой из них приведет к тому, что JVM будет создавать больше потоков при попытке запустить приложение?

Реза
источник

Ответы:

97

Я предпочитаю, чтобы первая версия запускала java-приложение только потому, что в ней меньше подводных камней («добро пожаловать в ад пути к классам»). Для второго требуется исполняемый файл jar, а путь к классам для этого приложения должен быть определен внутри манифеста jar (все остальные объявления пути к классам будут игнорироваться без предупреждения ...). Итак, со второй версией вам нужно будет заглянуть в jar, прочитать манифест и попытаться выяснить, действительны ли записи пути к классам, откуда хранится jar ... Этого можно избежать.

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

Андреас Долк
источник
А как насчет ниток? Они одинаковы с точки зрения количества потоков, создаваемых JVM при попытке запустить приложение?
Реза
1
Да. Обе версии найдут основной метод и выполнят его в одном потоке. Первая версия передает имя класса в качестве аргумента, во второй версии jvm найдет его внутри mainfest.
Андреас Долк,
@Andreas_D Пожалуйста, взгляните на этот пост , я думаю, я неправильно использую -cp и не знаю, как исправить свою ошибку.
fu DL
60

С -cpаргументом вы указываете путь к классам, то есть пути к дополнительным классам или библиотекам, которые могут потребоваться вашей программе при компиляции или запуске. С помощью -jarвы указываете исполняемый файл JAR, который хотите запустить.

Вы не можете указать их обоих. Если вы попытаетесь бежать, java -cp folder/myexternallibrary.jar -jar myprogram.jarэто не сработает. Путь к классам для этого JAR должен быть указан в его манифесте, а не в качестве -cpаргумента.

Вы можете найти больше об этом здесь и здесь .

PS: -cpи -classpathявляются синонимами.

Раду Мурзея
источник
Меня беспокоят ресурсы? есть ли разница между ресурсами, которые они используют?
Реза
@Hesam Если вы спрашиваете о различиях в производительности между -cpи -classpath, то нет, разницы нет.
Radu Murzea
1
Нет! Я имел в виду разницу в производительности между -cp (или -classpath) и -jar
Реза,
2
@Hesam С помощью -jarвы указываете, какой исполняемый файл JAR вы хотите запустить. Здесь -cpвы указываете пути к дополнительным классам / библиотеке, которые могут потребоваться вашей программе. У двух очень разные цели.
Раду Мурзеа,
@RaduMurzea, Что вы имеете в виду , что не будет действительно работать , когда мы объединяем их? Egjava -jar PATH -cp PATH2
Pacerier
18

При использовании java -cpвам необходимо указать полное имя основного класса, например

java -cp com.mycompany.MyMain

При использовании java -jar myjar.jarфайла jar необходимо предоставить информацию об основном классе через manifest.mf, содержащийся в файле jar в папке META-INF:

Main-Class: com.mycompany.MyMain

AlexR
источник
Не могли бы вы взглянуть на этот пост? Думаю, я неправильно использую -cp и не знаю, как исправить свою ошибку.
fu DL
10

java -cp CLASSPATH необходим, если вы хотите указать весь код в пути к классам. Это полезно для отладки кода.

Формат исполняемого файла jarred: java -jar JarFileможно использовать, если вы хотите запустить приложение с помощью одной короткой команды. Вы можете указать дополнительные зависимые файлы jar в своем МАНИФЕСТЕ, используя jar-файлы, разделенные пробелами, в записи Class-Path, например:

Class-Path: mysql.jar infobus.jar acme/beans.jar

Оба сопоставимы по производительности.

Reimeus
источник
Не могли бы вы взглянуть на этот пост? Думаю, я неправильно использую -cp и не знаю, как исправить свою ошибку.
fu DL
2

Как уже было сказано, -cp предназначен только для указания jvm в командной строке, какой класс использовать для основного потока и где он может найти библиотеки (определить путь к классам). В -jar он ожидает, что путь к классу и основной класс будут определены в манифесте файла jar. Таким образом, другое предназначено для определения вещей в командной строке, в то время как другие находят их внутри манифеста jar. Нет разницы в производительности. Вы не можете использовать их одновременно, -jar переопределит -cp.

Хотя даже если вы используете -cp, он все равно проверит файл манифеста. Таким образом, вы можете определить некоторые пути к классам в манифесте, а некоторые - в командной строке. Это особенно полезно, когда у вас есть зависимость от стороннего jar-файла, который вы можете не предоставлять вместе со своей сборкой или не хотите предоставлять (например, ожидая, что он уже найден в системе, где он будет установлен). Таким образом, вы можете использовать его для создания внешних банок. Его местоположение может отличаться в зависимости от системы, или он может даже иметь другую версию в другой системе (но с одинаковыми интерфейсами). Таким образом, вы можете создать приложение с другой версией и добавить фактическую зависимость стороннего производителя к class-path в командной строке при его запуске в разных системах.

Pehmolelu
источник
1

По производительности разницы не будет. Используя java-cp, мы можем указать необходимые классы и jar-файлы в пути к классам для запуска файла класса java.

Если это исполняемый файл jar. Когда используется команда java -jar, jvm находит класс, который необходимо запустить, из файла /META-INF/MANIFEST.MF внутри файла jar.

Рави Санкар Редди
источник