Inclure tous les fichiers jar dans un répertoire dans le classpath Java


Est-il un moyen d'inclure tous les fichiers jar dans un répertoire dans le chemin de classe?

J'essaie java -classpath lib/*.jar:. my.package.Program et il n'est pas capable de trouver des fichiers de classe qui sont certainement dans ces pots. Dois-je ajouter chaque fichier jar au chemin de classe séparément?

Author: Maarten Bodewes, 2008-10-20

22 answers

En utilisant Java 6 ou version ultérieure, l'option classpath prend en charge les caractères génériques. Notez ce qui suit:

  • Utiliser des guillemets droits (")
  • Utilisez *, pas *.jar

Les fenêtres

java -cp "Test.jar;lib/*" my.package.MainClass

Unix

java -cp "Test.jar:lib/*" my.package.MainClass

Ceci est similaire à Windows, mais utilise : au lieu de ;. Si vous ne pouvez pas utiliser de caractères génériques, bash autorise la syntaxe suivante (où lib est le répertoire contenant Fichiers d'archives Java):

java -cp $(echo lib/*.jar | tr ' ' ':')

(Notez que l'utilisation d'un chemin de classe est incompatible avec l'option -jar. Voir aussi: Exécuter le fichier jar avec plusieurs classpath bibliothèques à partir de l'invite de commande)

Comprendre les caractères génériques

Du document Classpath :

Les entrées de chemin de classe peuvent contenir le caractère générique basename *, ce qui est considéré comme équivalent à spécifier une liste de tous les fichiers dans le répertoire avec l'extension .jar ou .JAR. Par exemple, l' l'entrée de chemin de classe foo/* spécifie tous les fichiers JAR dans le répertoire nommé foo. Une entrée classpath composée simplement de * se développe en une liste de tous les fichiers jar dans le répertoire courant.

Une entrée de chemin de classe qui contient * ne correspondra pas aux fichiers de classe. De faites correspondre les deux classes et les fichiers JAR dans un seul répertoire foo, utilisez soit foo;foo/* ou foo/*;foo. L'ordre choisi détermine si le les classes et les les ressources dans foo sont chargées avant les fichiers JAR dans foo, ou inversement.

Les sous-répertoires ne sont pas recherchés récursivement. Par exemple, foo/* regarde pour les fichiers JAR uniquement dans foo, pas dans foo/bar, foo/baz, etc.

L'ordre dans lequel les fichiers JAR d'un répertoire sont élargi la catégorie chemin n'est pas spécifié et peut varier d'une plateforme à plate-forme, et même d'un moment à l'autre sur la même machine. Un une application bien construite ne doit pas dépendre tout particulier ordre. Si un ordre spécifique est requis les fichiers JAR peuvent être énumérés explicitement dans le chemin de classe.

L'expansion des caractères génériques se fait tôt, avant l'invocation d'un méthode principale du programme, plutôt que tardive, pendant le chargement de la classe le processus lui-même. Chaque élément du chemin de classe d'entrée contenant un le caractère générique est remplacé par la séquence (éventuellement vide) d'éléments généré en énumérant les fichiers JAR dans le répertoire nommé. Pour exemple, si le répertoire foo contient a.jar, b.jar, et c.jar, alors le chemin de classe foo/* est développé en foo/a.jar;foo/b.jar;foo/c.jar, et cette chaîne serait la valeur de la propriété système java.class.path.

La variable d'environnement CLASSPATH n'est pas traitée différemment de l'option de ligne de commande -classpath (ou -cp). Qui est, les jokers sont à l'honneur dans tous ces cas. Cependant, les caractères génériques de chemin de classe ne sont pas honoré dans l'en-tête Class-Path jar-manifest.

Remarque: en raison d'un bogue connu dans java 8, le les exemples Windows doivent utiliser une barre oblique inverse précédant les entrées avec un astérisque de fin: https://bugs.openjdk.java.net/browse/JDK-8131329

 997
Author: basszero, 2018-07-18 19:30:55

Sous Windows, cela fonctionne:

java -cp "Test.jar;lib/*" my.package.MainClass

Et cela ne fonctionne pas:

java -cp "Test.jar;lib/*.jar" my.package.MainClass

Notez le *.jar, donc le caractère générique * doit être utilisé seul.


Sous Linux, les travaux suivants:

java -cp "Test.jar:lib/*" my.package.MainClass

Les séparateurs sont des deux-points au lieu de points-virgules.

 201
Author: davorp, 2012-01-05 17:43:43

Nous contournons ce problème en déployant un fichier jar main myapp.jar qui contient un manifeste (Manifest.mf) fichier spécifiant un chemin de classe avec les autres fichiers jar requis, qui sont ensuite déployés à côté de celui-ci. Dans ce cas, il vous suffit de déclarer java -jar myapp.jar lors de l'exécution du code.

Donc, si vous déployez le jar principal dans un répertoire, puis placez les fichiers jar dépendants dans un dossier lib en dessous, le manifeste ressemble à:

Manifest-Version: 1.0
Implementation-Title: myapp
Implementation-Version: 1.0.1
Class-Path: lib/dep1.jar lib/dep2.jar

NB: ceci est indépendant de la plateforme - nous pouvons utiliser les mêmes jars pour lancer sur un serveur UNIX ou sur un PC Windows.

 59
Author: oxbow_lakes, 2014-10-09 09:43:47

Ma solution sur Ubuntu 10.04 en utilisant java-sun 1.6.0_24 ayant tous les pots dans le répertoire "lib":

java -cp .:lib/* my.main.Class

Si cela échoue, la commande suivante devrait fonctionner (affiche tout*.jars dans le répertoire lib au paramètre classpath)

java -cp $(for i in lib/*.jar ; do echo -n $i: ; done). my.main.Class
 37
Author: Habi, 2011-03-17 11:01:22

Réponse courte: java -classpath lib/*:. my.package.Program

Oracle fournit de la documentation sur l'utilisation de caractères génériques dans les chemins de classeici pour Java 6 etici pour Java 7 , sous l'en-tête de sectionComprendre les caractères génériques de chemin de classe . (Au moment où j'écris ceci, les deux pages contiennent les mêmes informations.) Voici un résumé des faits saillants:

  • En général, pour inclure tous les Bocaux dans un répertoire donné, vous pouvez utiliser le caractère générique * (pas *.jar).

  • Le caractère générique ne correspond qu'aux fichiers JAR, pas aux fichiers de classe; pour obtenir toutes les classes dans un répertoire, terminez simplement l'entrée classpath au nom du répertoire.

  • Les deux options ci-dessus peuvent être combinées pour inclure tous les fichiers JAR et class dans un répertoire, et les règles de priorité classpath habituelles s'appliquent. Par exemple. -cp /classes;/jars/*

  • Le caractère générique ne recherche pas les fichiers JAR dans les sous-répertoires.

  • Les puces ci-dessus sont vraies si vous utilisez le CLASSPATH propriété système ou les indicateurs de ligne de commande -cp ou -classpath. Cependant, si vous utilisez l'en-tête du manifeste JAR Class-Path (comme vous pouvez le faire avec un fichier de construction ant), les caractères génériques ne seront pas honorés.

Oui, mon premier lien est le même que celui fourni dans la réponse la mieux notée (que je n'ai aucun espoir de dépasser), mais cette réponse ne fournit pas beaucoup d'explication au-delà du lien. Depuis ce genre de comportement est découragé sur un Débordement de Pile ces jours - , Je pensais étendre sur elle.

 29
Author: Pops, 2017-03-20 10:29:34

Pour moi, cela fonctionne sous Windows .

java -cp "/lib/*;" sample

Pour linux

java -cp "/lib/*:" sample

Je suis l'aide de Java 6

 28
Author: SANN3, 2014-11-13 07:42:39

Vous pouvez essayer java -Djava.ext.dirs=jarDirectory http://docs.oracle.com/javase/6/docs/technotes/guides/extensions/spec.html

Répertoire pour les fichiers jar externes lors de l'exécution de java

 21
Author: Navi, 2015-10-28 15:53:54

Corriger:

java -classpath "lib/*:." my.package.Program

Incorrect:

java -classpath "lib/a*.jar:." my.package.Program
java -classpath "lib/a*:."     my.package.Program
java -classpath "lib/*.jar:."  my.package.Program
java -classpath  lib/*:.       my.package.Program
 20
Author: rvernica, 2012-02-13 17:57:06

Windows:
java -cp fichier.jar; dir / * mon.App.className

Linux:
java -cp fichier.jar: dir / * mon.App.className

Rappeler:
- Windows séparateur de chemin est ";"
- Linux séparateur de chemin est ":"
- Dans Windows si l'argument cp ne contient pas d'espace blanc, les "guillemets" sont facultatifs

 12
Author: Wender, 2016-07-18 19:10:11

Si vous avez vraiment besoin de spécifier tous les .fichiers jar dynamiquement, vous pouvez utiliser des scripts shell, ou Apache Ant . Il existe un projet commons appelé Commons Launcher qui vous permet essentiellement de spécifier votre script de démarrage en tant que fichier de construction ant (si vous voyez ce que je veux dire).

Ensuite, vous pouvez spécifier quelque chose comme:

<path id="base.class.path">
    <pathelement path="${resources.dir}"/>
    <fileset dir="${extensions.dir}" includes="*.jar" />
    <fileset dir="${lib.dir}" includes="*.jar"/>
</path>

Dans votre fichier de construction de lancement, qui lancera votre application avec le chemin de classe correct.

 8
Author: , 2008-10-20 19:55:27

Si vous utilisez Java 6, vous pouvez utiliser des caractères génériques dans le chemin de classe.

Maintenant, il est possible d'utiliser des caractères génériques dans la définition de classpath:

javac -cp libs/* -verbose -encoding UTF-8 src/mypackage/*.java  -d build/classes

Réf.: http://www.rekk.de/bloggy/2008/add-all-jars-in-a-directory-to-classpath-with-java-se-6-using-wildcards/

 8
Author: prakash, 2014-08-13 12:06:59

Veuillez noter que l'extension générique est interrompue pour Java 7 sous Windows.

Consultez ce problème StackOverflow pour plus d'informations.

La solution consiste à mettre un point-virgule juste après le caractère générique. java -cp "somewhere/*;"

 7
Author: Jake Toronto, 2017-05-23 11:33:25

À qui cela peut concerner,

J'ai trouvé ce comportement étrange sous Windows sous un shell MSYS/MinGW.

Œuvres:

$ javac -cp '.;c:\Programs\COMSOL44\plugins\*' Reclaim.java

Ne fonctionne pas:

$ javac -cp 'c:\Programs\COMSOL44\plugins\*' Reclaim.java
javac: invalid flag: c:\Programs\COMSOL44\plugins\com.comsol.aco_1.0.0.jar
Usage: javac <options> <source files>
use -help for a list of possible options

Je suis tout à fait sûr que le caractère générique n'est pas développé par le shell, car par exemple

$ echo './*'
./*

(Essayé avec un autre programme aussi, plutôt que le echo intégré, avec le même résultat.)

Je crois que c'est javac qui essaie de l'étendre, et il se comporte différemment s'il y a est un point-virgule dans l'argument ou pas. Tout d'abord, il peut essayer d'étendre tous les arguments qui ressemblent à des chemins. Et seulement alors il les analyserait, avec -cp ne prenant que le jeton suivant. (Notez que com.comsol.aco_1.0.0.jar est le deuxième JAR de ce répertoire.) C'est tout une supposition.

C'est

$ javac -version
javac 1.7.0
 5
Author: Evgeni Sergeev, 2014-12-12 01:33:30

Toutes les solutions ci-dessus fonctionnent très bien si vous développez et exécutez l'application Java en dehors de toutE comme Eclipse ou Netbeans.

Si vous utilisez Windows 7 et utilisez Eclipse ID pour le développement en Java, vous pouvez rencontrer des problèmes si vous utilisez l'invite de commande pour exécuter les fichiers de classe construits dans Eclipse.

Par exemple, votre code source dans Eclipse a la hiérarchie de paquets suivante: edu.sjsu.myapp.Principal.java

Vous avez json.bocal comme une dépendance externe pour le Principal.java

Lorsque vous essayez d'exécuter Main.java à partir d'Eclipse, il fonctionnera sans aucun problème.

Mais lorsque vous essayez de l'exécuter à l'aide de l'invite de commande après la compilation de Main.java dans Eclipse, il va tirer quelques erreurs étranges disant "Erreur ClassNotDef bla bla".

Je suppose que vous êtes dans le répertoire de travail de votre code source !!

Utilisez la syntaxe suivante pour l'exécuter à partir de l'invite de commande:

  1. Javac -cp ".; json.jar " Principal.java

  2. Java -cp ".; json.jar" edu.sjsu.myapp.Principal

    [Ne manquez pas le . ci-dessus]

C'est parce que vous avez placé le Principal.java dans le paquet edu.sjsu.myapp et java.exe recherchera le modèle exact.

J'espère que ça aide !!

 3
Author: realPK, 2011-11-21 03:54:39

Pour Windows, les guillemets sont requis et ; doit être utilisé comme séparateur. par exemple:

java -cp "target\\*;target\\dependency\\*" my.package.Main
 3
Author: Alexey, 2013-07-01 09:36:17

Forme courte: Si votre main est dans un jar, vous aurez probablement besoin d'un chemin '-jar supplémentaire pour/yourJar/YourJarsName.jar 'explicitement déclaré pour le faire fonctionner (même si' YourJarsName.jar ' était sur le chemin de classe) (ou, exprimé pour répondre à la question originale qui a été posée il y a 5 ans: vous n'avez pas besoin de redéclarer explicitement chaque pot, mais semble, même avec java6, vous devez redéclarer votre propre pot ...)


Formulaire long: (J'ai rendu cela explicite au point que j'espère même les interlopers vers java peuvent utiliser ceci)

Comme beaucoup ici, j'utilise eclipse pour exporter des pots: (Fichier->Exporter> > 'Fichier JAR exécutable'). Il existe trois options sur la gestion de la bibliothèque eclipse (Juno):

opt1: "Extract required libraries into generated JAR"
opt2: "Package required libraries into generated JAR"
opt3: "Copy required libraries into a sub-folder next to the generated JAR"

Typiquement, j'utiliserais opt2 (et opt1 cassait définitivement), mais le code natif dans l'un des pots que j'utilise, j'ai découvert des ruptures avec l'astuce pratique "jarinjar" qu'eclipse exploite lorsque vous choisissez cette option. Même après avoir réalisé que j'avais besoin d'opt3, puis trouver ceci Entrée StackOverflow, il m'a encore fallu un certain temps pour comprendre comment lancer mon principal en dehors d'eclipse, alors voici ce qui a fonctionné pour moi, car c'est utile pour les autres...


Si vous avez nommé votre pot: "fooBarTheJarFile.pot" et tout est configuré pour exporter vers le répertoire: "/ theFully/qualifiedPath / toYourChosenDir".

(ce qui signifie que le champ 'Export destination' se lira: '/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar')

Après avoir touché finish, vous trouverez eclipse place ensuite toutes les bibliothèques dans un dossier nommé 'fooBarTheJarFile_lib' dans ce répertoire d'exportation, vous donnant quelque chose comme:

/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar
/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/SomeOtherJar01.jar
/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/SomeOtherJar02.jar
/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/SomeOtherJar03.jar
/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/SomeOtherJar04.jar

Vous pouvez ensuite lancer de n'importe où sur votre système avec:

java -classpath "/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/*" -jar  /theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar   package.path_to.the_class_with.your_main.TheClassWithYourMain

(Pour les débutants Java: 'package.chemin_to.the_class_with.your_main ' est le chemin de paquet déclaré que vous trouverez en haut de 'TheClassWithYourMain.java fichier qui contient le main(String[] args){...} 'que vous souhaitez courir de l'extérieur java)


L'écueil à remarquer: est que d'avoir 'fooBarTheJarFile.jar ' dans la liste des jars sur votre chemin de classe déclaré ne suffit pas. Vous devez déclarer explicitement '- jar' et redéclarer l'emplacement de ce jar.

Par exemple, cela casse:

 java -classpath "/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar;/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/*"  somepackages.inside.yourJar.leadingToTheMain.TheClassWithYourMain

Reformulé avec des chemins relatifs:

cd /theFully/qualifiedPath/toYourChosenDir/;
BREAKS:  java -cp "fooBarTheJarFile_lib/*"                                package.path_to.the_class_with.your_main.TheClassWithYourMain    
BREAKS:  java -cp ".;fooBarTheJarFile_lib/*"                              package.path_to.the_class_with.your_main.TheClassWithYourMain   
BREAKS:  java -cp ".;fooBarTheJarFile_lib/*"   -jar                       package.path_to.the_class_with.your_main.TheClassWithYourMain   
WORKS:   java -cp ".;fooBarTheJarFile_lib/*"   -jar  fooBarTheJarFile.jar package.path_to.the_class_with.your_main.TheClassWithYourMain   

(en utilisant la version java "1.6.0_27"; via OpenJDK 64-Bit Server VM sur ubuntu 12.04)

 3
Author: Matt S., 2016-11-29 08:05:39

La seule façon dont je sais comment est de le faire individuellement, par exemple:

setenv CLASSPATH /User/username/newfolder/jarfile.jar:jarfile2.jar:jarfile3.jar:.

J'espère que ça aide!

 2
Author: ParseTheData, 2013-07-01 09:36:58

Classe de wepapp:

  > mvn clean install

  > java -cp "webapp/target/webapp-1.17.0-SNAPSHOT/WEB-INF/lib/tool-jar-1.17.0-SNAPSHOT.jar;webapp/target/webapp-1.17.0-SNAPSHOT/WEB-INF/lib/*" com.xx.xx.util.EncryptorUtils param1 param2
 2
Author: Mindaugas K., 2015-04-29 06:55:56

Pas une solution directe pour pouvoir définir /* sur-cp mais j'espère que vous pourriez utiliser le script suivant pour faciliter un peu la situation pour les chemins de classe dynamiques et les répertoires lib.

 libDir2Scan4jars="../test";cp=""; for j in `ls ${libDir2Scan4jars}/*.jar`; do if [ "$j" != "" ]; then cp=$cp:$j; fi; done; echo $cp| cut -c2-${#cp} > .tmpCP.tmp; export tmpCLASSPATH=`cat .tmpCP.tmp`; if [ "$tmpCLASSPATH" != "" ]; then echo .; echo "classpath set, you can now use  ~>         java -cp \$tmpCLASSPATH"; echo .; else echo .; echo "Error please check libDir2Scan4jars path"; echo .; fi; 

Scripté pour Linux, pourrait avoir un similaire pour Windows aussi. Si le répertoire approprié est fourni en entrée dans le "libDir2Scan4jars" ; le script analysera tous les fichiers jar et créera une chaîne classpath et l'exportera vers une variable env"tmpCLASSPATH".

 1
Author: Sreesankar, 2016-06-27 12:05:44

Vous devez tous les ajouter séparément. Alternativement, si vous vraiment devez simplement spécifier un répertoire, vous pouvez tout ajouter dans un répertoire et l'ajouter à votre chemin de classe. Je ne recommande cependant pas cette approche car vous risquez des problèmes bizarres dans la gestion des versions de classpath et l'ingérable.

 0
Author: Daniel Spiewak, 2008-10-20 19:36:03

Considérez un fichier jar comme la racine d'une structure de répertoires. Oui, vous devez les ajouter tous séparément.

 0
Author: R. Van Hoose, 2008-10-20 19:37:49

Définissez le chemin de classe d'une manière appropriée plusieurs fichiers jar et les fichiers de classe du répertoire courant.

CLASSPATH=${ORACLE_HOME}/jdbc/lib/ojdbc6.jar:${ORACLE_HOME}/jdbc/lib/ojdbc14.jar:${ORACLE_HOME}/jdbc/lib/nls_charset12.jar; 
CLASSPATH=$CLASSPATH:/export/home/gs806e/tops/jconn2.jar:.;
export CLASSPATH
 0
Author: Girdhar Singh Rathore, 2016-06-30 17:46:41