Différences entre “java -cp” et “java -jar”?

Quelle est la différence entre exécuter une application Java avec
java -cp CLASSPATH et 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 laquelle de ces manières est la plus chère pour JVM (en fonction de leur utilisation de ressources de machine)?

Lequel causera à JVM de générer plus de threads tout en essayant d’exécuter l’application?

Je préfère la première version pour lancer une application java simplement parce qu’elle a moins de pièges (“bienvenue dans l’enfer de classpath”). Le second nécessite un fichier jar exécutable et le classpath de cette application doit être défini dans le manifeste du jar (toute autre déclaration de classpath sera ignorée en silence …). 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 jar est stocké … C’est évitable.

Je ne m’attends pas à des avantages ou des inconvénients de performance pour les deux versions. Il suffit de dire au jvm quelle classe utiliser pour le thread principal et où il peut trouver les bibliothèques.

Avec l’argument -cp , vous fournissez le chemin d’access aux classes, c’est-à-dire le ou les chemins d’access aux classes ou bibliothèques supplémentaires dont votre programme peut avoir besoin lorsqu’il est compilé ou exécuté. Avec -jar vous 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 d’exécuter le java -cp folder/myexternallibrary.jar -jar myprogram.jar cela ne fonctionnera pas vraiment. Le classpath pour ce fichier JAR doit être spécifié dans son manifeste, et non pas comme un argument -cp .

Vous pouvez trouver plus d’informations à ce sujet ici et ici .

PS: -classpath et -classpath sont des synonymes.

Lorsque vous utilisez java -cp vous devez fournir le nom complet de la classe principale, par exemple

java -cp com.mycompany.MyMain

Lorsque vous utilisez java -jar myjar.jar votre fichier jar doit fournir les informations sur la classe principale via le fichier manifest.mf contenu dans le fichier jar du dossier META-INF :

Main-Class: com.mycompany.MyMain

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

Le format exécutable java -jar JarFile : java -jar JarFile peut être utilisé si vous souhaitez démarrer l’application en une seule commande. Vous pouvez spécifier des fichiers jar dépendants supplémentaires dans votre MANIFEST en utilisant des 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 performance.

Il n’y aura pas de différence en termes de performance. Avec java-cp, nous pouvons spécifier les classes et les jar requirejs dans le classpath 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 qui doit être exécutée à partir du fichier /META-INF/MANIFEST.MF dans le fichier jar.

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 classpath). Dans -jar, le chemin de classe et la classe principale doivent être définis dans le manifeste du fichier jar. Donc, autre chose est de définir des choses en ligne de commande alors que d’autres les trouvent dans le manifeste JAR. Il n’y a pas de différence de performance. Vous ne pouvez pas les utiliser en même temps, -jar remplacera -cp.

Même si vous utilisez -cp, il vérifiera quand même le fichier manifeste. Vous pouvez donc définir certains 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 à un fichier JAR tiers, que vous ne fournissez peut-être pas avec votre build ou que vous ne souhaitez pas fournir (en attendant de le trouver 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 d’un système à l’autre ou il peut même avoir une version différente sur un système différent (mais avec les mêmes interfaces). De cette façon, vous pouvez créer l’application avec une autre version et append la dépendance réelle de tiers à class-path sur la ligne de commande lorsque vous l’exécutez sur différents systèmes.