Różnice między „java -cp” a „java -jar”?

118

Jaka jest różnica między uruchamianiem aplikacji Java za pomocą
java -cp CLASSPATHi java -jar JAR_FILE_PATH? Czy jeden z nich jest preferowany do uruchamiania aplikacji Java? Mam na myśli, który z tych sposobów jest droższy dla JVM (w zależności od wykorzystania zasobów maszynowych)?

Który z nich spowoduje, że JVM utworzy więcej wątków podczas próby uruchomienia aplikacji?

Reza
źródło

Odpowiedzi:

97

Wolę, aby pierwsza wersja uruchamiała aplikację java tylko dlatego, że ma mniej pułapek („witamy w piekle ścieżki klas”). Drugi wymaga wykonywalnego pliku jar, a ścieżka klas dla tej aplikacji musi być zdefiniowana w manifeście jar (wszystkie inne deklaracje ścieżki klas będą dyskretnie ignorowane ...). Więc w drugiej wersji musiałbyś zajrzeć do słoika, przeczytać manifest i spróbować dowiedzieć się, czy wpisy ścieżki klas są prawidłowe z miejsca przechowywania słoika ... Tego można uniknąć.

Nie spodziewam się żadnych zalet ani wad wydajności dla obu wersji. Po prostu informuje jvm, której klasy ma użyć w głównym wątku i gdzie może znaleźć biblioteki.

Andreas Dolk
źródło
A co z wątkami? Czy są takie same pod względem liczby wątków, które pojawiają się w JVM podczas próby uruchomienia aplikacji?
Reza
1
Tak. Obie wersje zlokalizują główną metodę i wykonają ją w jednym wątku. Pierwsza wersja przekazuje nazwę klasy jako argument, w drugiej wersji jvm znajdzie ją wewnątrz mainfestu.
Andreas Dolk
@Andreas_D Proszę rzucić okiem na ten post , myślę, że używam -cp w niewłaściwy sposób i nie wiem, jak poprawić swój błąd.
fu DL
60

Za pomocą -cpargumentu podajesz ścieżkę klas, tj. Ścieżki do dodatkowych klas lub bibliotek, których Twój program może wymagać podczas kompilowania lub uruchamiania. Za pomocą -jarokreśl wykonywalny plik JAR, który chcesz uruchomić.

Nie możesz określić ich obu. Jeśli spróbujesz uciec, java -cp folder/myexternallibrary.jar -jar myprogram.jarto nie zadziała. Ścieżka klas dla tego pliku JAR powinna być określona w jego Manifeście, a nie jako -cpargument.

Więcej na ten temat można znaleźć tutaj i tutaj .

PS: -cpi -classpathsą synonimami.

Radu Murzea
źródło
Moje obawy dotyczą zasobów? czy jest różnica między używanymi przez nich zasobami?
Reza
@Hesam Jeśli pytasz o różnice w wydajności między -cpa -classpath, to nie, nie ma różnicy.
Radu Murzea
1
Nie! Chodziło mi o różnicę w wydajności między -cp (lub -classpath) a -jar
Reza
2
@Hesam Z -jarokreślasz, jaki wykonywalny plik JAR chcesz uruchomić. Z -cpokreśleniem ścieżki (ścieżek) do dodatkowych klas / bibliotek, których może wymagać Twój program. Te 2 mają bardzo różne cele.
Radu Murzea
@RaduMurzea, co masz na myśli mówiąc, żeby tak naprawdę nie działało jak je połączymy? Np.java -jar PATH -cp PATH2
Pacerier
18

Podczas korzystania z usługi java -cpwymagane jest podanie w pełni kwalifikowanej nazwy klasy głównej, np

java -cp com.mycompany.MyMain

Korzystając java -jar myjar.jarz pliku jar, należy podać informacje o głównej klasie za pośrednictwem manifest.mf zawartej w pliku jar w folderze META-INF:

Main-Class: com.mycompany.MyMain

AlexR
źródło
Chciałbym rzucić okiem na ten post , myślę, że używam -cp w niewłaściwy sposób i nie wiem, jak poprawić swój błąd.
fu DL
10

java -cp ŚCIEŻKA KLASY jest niezbędna, jeśli chcesz określić cały kod w ścieżce klas. Jest to przydatne do debugowania kodu.

Format wykonywalny jarred: java -jar JarFilemoże być używany, jeśli chcesz uruchomić aplikację za pomocą jednego krótkiego polecenia. Możesz określić dodatkowe zależne pliki jar w swoim MANIFESTIE, używając plików jar oddzielonych spacjami we wpisie Class-Path, np .:

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

Oba są porównywalne pod względem wydajności.

Reimeus
źródło
Chciałbym rzucić okiem na ten post , myślę, że używam -cp w niewłaściwy sposób i nie wiem, jak poprawić swój błąd.
fu DL
2

Jak już zostało powiedziane, -cp służy tylko do informowania jvm w wierszu poleceń, której klasy ma użyć w głównym wątku i gdzie może znaleźć biblioteki (zdefiniować ścieżkę klas). In -jar oczekuje, że ścieżka-klasy i klasa główna zostaną zdefiniowane w manifeście pliku jar. Więc inne służy do definiowania rzeczy w linii poleceń, a inne do znajdowania ich w manifeście jar. Nie ma różnicy w wydajności. Nie możesz ich używać w tym samym czasie, -jar zastąpi -cp.

Chociaż nawet jeśli użyjesz -cp, nadal będzie sprawdzać plik manifestu. Możesz więc zdefiniować niektóre ścieżki klas w manifeście, a inne w linii poleceń. Jest to szczególnie przydatne, gdy masz zależność od jakiegoś pliku jar innej firmy, którego możesz nie dostarczyć wraz z kompilacją lub nie chcesz go udostępniać (na przykład spodziewając się, że znajduje się on już w systemie, w którym ma być zainstalowany). Możesz więc użyć go do dostarczenia zewnętrznych słoików. Jego lokalizacja może się różnić w różnych systemach lub może nawet mieć inną wersję w innym systemie (ale z tymi samymi interfejsami). W ten sposób możesz zbudować aplikację z inną wersją i dodać rzeczywistą zależność innej firmy do ścieżki klasy w wierszu poleceń podczas uruchamiania jej w różnych systemach.

Pehmolelu
źródło
1

Nie będzie żadnej różnicy w wydajności. Używając java - cp możemy określić wymagane klasy i pliki jar w ścieżce klas do uruchomienia pliku klas java.

Jeśli jest to wykonywalny plik jar. Gdy używana jest komenda java -jar, jvm znajduje klasę, którą potrzebuje do uruchomienia, z pliku /META-INF/MANIFEST.MF wewnątrz pliku jar.

ravi sankar reddy
źródło