Différences entre «java -cp» et «java -jar»?

118

Quelle est la différence entre exécuter une application Java avec
java -cp CLASSPATHet java -jar JAR_FILE_PATH? L'un d'entre eux est-il préféré à l'autre pour exécuter une application Java? Je veux dire, lequel de ces moyens est le plus cher pour JVM (en fonction de l'utilisation des ressources de leur machine)?

Lequel entraînera JVM pour générer plus de threads tout en essayant d'exécuter l'application?

Reza
la source

Réponses:

97

Je préfère la première version pour démarrer une application java juste parce qu'elle a moins de pièges ("Welcome to classpath hell"). Le second nécessite un fichier jar exécutable et le chemin de classe de cette application doit être défini dans le manifeste du fichier jar (toutes les autres déclarations de chemin de classe seront silencieusement ignorées ...). Donc, avec la deuxième version, vous devriez regarder dans le fichier jar, lire le manifeste et essayer de savoir si les entrées du chemin de classe sont valides à partir de l'endroit où le fichier est stocké ... C'est évitable.

Je ne m'attends à aucun avantage ou inconvénient en termes de performances pour les deux versions. Il indique simplement au jvm quelle classe utiliser pour le thread principal et où il peut trouver les bibliothèques.

Andreas Dolk
la source
Et les fils? Sont-ils identiques en termes de nombre de threads générés par la JVM lors de la tentative d'exécution de l'application?
Reza
1
Oui. Les deux versions localiseront la méthode principale et l'exécuteront avec un seul thread. La première version passe le nom de la classe comme argument, avec la seconde version, le jvm le trouvera dans le mainfest.
Andreas Dolk
@Andreas_D Je vous en prie, jetez un œil à ce post , je suppose que j'utilise -cp d'une mauvaise manière, et je ne sais pas comment corriger mon erreur.
fu DL
60

Avec l' -cpargument, vous indiquez le chemin de classe, c'est-à-dire le (s) chemin (s) vers des classes ou bibliothèques supplémentaires dont votre programme peut avoir besoin lors de sa compilation ou de son exécution. Avec -jarvous spécifiez le fichier JAR exécutable que vous souhaitez exécuter.

Vous ne pouvez pas les spécifier tous les deux. Si vous essayez de courir, java -cp folder/myexternallibrary.jar -jar myprogram.jarcela ne fonctionnera pas vraiment. Le chemin d'accès aux classes de ce JAR doit être spécifié dans son manifeste, et non en tant -cpqu'argument.

Vous pouvez en savoir plus ici et ici .

PS: -cpet -classpathsont des synonymes.

Radu Murzea
la source
Ma préoccupation concerne les ressources? y a-t-il une différence entre les ressources qu'ils utilisent?
Reza
@Hesam Si vous posez des questions sur les différences de performances entre -cpet -classpath, alors non, il n'y a pas de différence.
Radu Murzea
1
Non! Je voulais dire la différence de performance entre -cp (ou -classpath) et -jar
Reza
2
@Hesam Avec -jarvous spécifiez quel JAR exécutable vous voulez exécuter. Avec -cpvous spécifiez le (s) chemin (s) vers les classes / bibliothèques supplémentaires dont votre programme peut avoir besoin. Les 2 ont des objectifs très différents.
Radu Murzea
@RaduMurzea, que voulez-vous dire que cela ne fonctionnerait pas vraiment lorsque nous les combinons? Par exemplejava -jar PATH -cp PATH2
Pacerier
18

Lors de l'utilisation, java -cpvous devez fournir un nom de classe principal complet, par exemple

java -cp com.mycompany.MyMain

Lorsque java -jar myjar.jarvous utilisez votre fichier jar, vous devez fournir les informations sur la classe principale via manifest.mf contenues dans le fichier jar dans le dossier META-INF:

Main-Class: com.mycompany.MyMain

AlexR
la source
Je vous prie de jeter un œil à ce post , je suppose que j'utilise -cp d'une mauvaise manière, et je ne sais pas comment corriger mon erreur.
fu DL
10

java -cp CLASSPATH est nécessaire si vous souhaitez spécifier tout le code dans le chemin de classe. Ceci est utile pour le débogage du code.

Le format exécutable jarred: java -jar JarFilepeut être utilisé si vous souhaitez démarrer l'application avec une seule commande courte. Vous pouvez spécifier des fichiers jar dépendants supplémentaires dans votre MANIFEST en utilisant des fichiers jar séparés par des espaces dans une entrée Class-Path, par exemple:

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

Les deux sont comparables en termes de performances.

Reimeus
la source
Je vous prie de jeter un œil à ce post , je suppose que j'utilise -cp d'une mauvaise manière, et je ne sais pas comment corriger mon erreur.
fu DL
2

Comme déjà dit, le -cp est juste pour dire au jvm dans la ligne de commande quelle classe utiliser pour le thread principal et où il peut trouver les bibliothèques (définir le chemin de classe). Dans -jar, il s'attend à ce que le chemin de classe et la classe principale soient définis dans le manifeste du fichier jar. L'autre consiste donc à définir les choses en ligne de commande tandis que les autres les trouvent dans le manifeste jar. Il n'y a aucune différence de performance. Vous ne pouvez pas les utiliser en même temps, -jar remplacera le -cp.

Même si vous utilisez -cp, il vérifiera toujours le fichier manifeste. Vous pouvez donc définir certains des chemins de classe dans le manifeste et d'autres dans la ligne de commande. Ceci est particulièrement utile lorsque vous avez une dépendance sur un fichier jar tiers, que vous pourriez ne pas fournir avec votre build ou ne pas vouloir fournir (en espérant qu'il se trouve déjà dans le système où il doit être installé par exemple). Vous pouvez donc l'utiliser pour fournir des pots externes. Son emplacement peut varier entre les systèmes ou il peut même avoir une version différente sur un système différent (mais ayant les mêmes interfaces). De cette façon, vous pouvez créer l'application avec une autre version et ajouter la dépendance tierce réelle au chemin de classe sur la ligne de commande lors de son exécution sur différents systèmes.

Pehmolelu
la source
1

Il n'y aura aucune différence en termes de performances. En utilisant java - cp, nous pouvons spécifier les classes et les jar requis dans le chemin de classe pour exécuter un fichier de classe java.

S'il s'agit d'un fichier jar exécutable. Lorsque la commande java -jar est utilisée, jvm trouve la classe dont il a besoin pour s'exécuter à partir du fichier /META-INF/MANIFEST.MF dans le fichier jar.

ravi sankar reddy
la source