Incluant tous les pots dans un répertoire dans le classpath Java

y a-t-il un moyen d'inclure tous les fichiers jar dans un répertoire dans classpath?

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

862
demandé sur Maarten Bodewes 2008-10-20 23:32:45

22 réponses

en utilisant Java 6 ou plus tard, l'option classpath supporte les caractères génériques. Note ce qui suit:

  • utilisez des guillemets ( " )
  • utiliser * , pas *.jar

Windows

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

Unix

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

c'est similaire à Windows, mais utilise : au lieu de ; . Si vous ne pouvez pas utiliser les caractères génériques, bash permet la syntaxe suivante (où lib est le répertoire contenant tous les 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 un fichier jar avec plusieurs bibliothèques classpath à partir de l'invite de commande )

La Compréhension Des Caractères Génériques

De la Classpath document:

les entrées de chemin de classe peuvent contenir le caractère de caractère de base * , 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 consistant simplement en * s'étend à une liste de tous les les fichiers jar dans le répertoire courant.

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

Les sous-répertoires

ne font pas l'objet d'une recherche récursive. Par exemple, foo/* semble pour les fichiers JAR uniquement dans foo , pas dans foo/bar , foo/baz , etc.

L'ordre dans lequel les fichiers JAR dans un répertoire sont énumérés dans la é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 devrait pas dépendre d'une ordre. Si une commande spécifique est nécessaire, alors les fichiers JAR peuvent être énumérés explicitement dans le chemin de classe.

L'extension de wildcards 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 joker, c'est remplacé par la séquence d'éléments (éventuellement vide) 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 , puis le chemin de classe foo/* est élargi en foo/a.jar;foo/b.jar;foo/c.jar , et cette chaîne serait la valeur de la propriété du système java.class.path .

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

Note: en raison d'un bug connu dans java 8, les exemples de windows doivent utiliser un antislash précédent les entrées avec un astérisque de fuite: https://bugs.openjdk.java.net/browse/JDK-8131329

997
répondu 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

avis *.jar, donc le Joker * doit être utilisé seul .


sur Linux, les travaux suivants:

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

les séparateurs sont des colons au lieu de point-virgule.

201
répondu davorp 2012-01-05 17:43:43

nous contournons ce problème en déployant un fichier main jar file myapp.jar qui contient un fichier manifest ( Manifest.mf ) spécifiant un chemin de classe avec les autres jarres requises, qui sont ensuite déployées à ses côtés. Dans ce cas, vous n'avez qu'à déclarer java -jar myapp.jar lors de l'exécution du code.

donc si vous déployez le principal jar dans un répertoire, et puis mettre les pots dépendants dans un lib dossier 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 plate-forme - nous pouvons utiliser les mêmes bocaux pour lancer sur un serveur UNIX ou sur un PC Windows.

59
répondu oxbow_lakes 2014-10-09 09:43:47

Ma solution sur Ubuntu 10.04 à l'aide de java-sun 1.6.0_24 avoir tous les pots dans "lib":

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

Si cela échoue, la commande suivante devrait fonctionner (imprime tous *.les bocaux dans le répertoire lib du classpath param)

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

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

Oracle fournit de la documentation sur l'utilisation de caractères génériques dans les classpaths ici pour Java 6 et ici pour Java 7 , sous la rubrique comprendre les caractères génériques de classe . (Au moment où j'écris ces lignes, les deux pages contiennent la même information.) Voici un résumé des faits saillants:

  • en général, comprend tous les biens suivants: les pots dans un répertoire donné, vous pouvez utiliser le Joker * ( pas *.jar ).

  • le Joker ne correspond qu'à des jarres, pas à des fichiers de classe; pour obtenir toutes les classes dans un répertoire, il suffit de terminer 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 habituelles de priorité classpath appliquer. Par exemple: -cp /classes;/jars/*

  • Le caractère générique pas recherche pour les Bocaux dans des sous-répertoires.

  • les points de puce ci-dessus sont vrais si vous utilisez la propriété de système CLASSPATH ou les drapeaux de ligne de commande -cp ou -classpath . Cependant, si vous utilisez l'en-tête Class-Path jar manifest (comme vous pourriez le faire avec un fichier ANT build), les caractères génériques seront Non soit honoré.

Oui, mon premier lien est le même que celui fourni dans la réponse la mieux cotée (que je n'ai aucun espoir de dépasser), mais cette réponse ne fournit pas beaucoup d'explications au-delà du lien. Puisque ce genre de comportement est découragé sur le débordement de la pile ces jours , j'ai pensé que je voudrais développer sur elle.

29
répondu Pops 2017-03-20 10:29:34

pour moi cela fonctionne sous windows .

java -cp "/lib/*;" sample

Pour linux

java -cp "/lib/*:" sample

j'utilise Java 6

28
répondu 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 externe pots lors de l'exécution de java

21
répondu Navi 2015-10-28 15:53:54

Correct :

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
répondu rvernica 2012-02-13 17:57:06

Windows :

java -cp fichier.jar;dir/* mes.App.Nom de la classe

Linux :

java -cp fichier.jar:dir/* mes.App.Nom de la classe

rappeler:

- Windows séparateur de chemin est" ; "

- Linux séparateur de chemin d'accès est " : "

- Dans Windows si l'argument cp ne contient pas d'espace blanc, le " guillemets "est optionnel

12
répondu 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 y a un projet commun appelé Commons Launcher qui vous permet essentiellement de spécifier votre script de démarrage comme un fichier de construction ant (si vous voyez ce que je veux dire).

alors, 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 corriger classpath.

8
répondu 2008-10-20 19:55:27

si vous utilisez Java 6, Vous pouvez utiliser des caractères génériques dans classpath.

il est maintenant 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
répondu prakash 2014-08-13 12:06:59

veuillez noter que L'extension Joker est cassée pour Java 7 sous Windows.

Check out ce StackOverflow question pour plus d'informations.

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

7
répondu Jake Toronto 2017-05-23 11:33:25

à qui de droit,

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

:

$ 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 Joker n'est pas étendu par le shell, parce que par exemple

$ echo './*'
./*

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

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

C'est

$ javac -version
javac 1.7.0
5
répondu 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 tout IDE comme Eclipse ou Netbeans.

si vous êtes sur Windows 7 et que vous utilisez Eclipse IDE pour le développement en Java, vous pourriez rencontrer des problèmes si vous utilisez L'invite de commande pour exécuter les fichiers de classe construits à L'intérieur D'Eclipse.

E. G. Votre code source dans Eclipse a la hiérarchie de paquet suivante:: edu.sjsu.myapp.Principal.java

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

quand vous essayez de lancer Main.java depuis Eclipse, elle fonctionnera sans problèmes.

mais quand vous essayez d'exécuter ceci en utilisant la commande invite après avoir compilé Main.java dans Eclipse, il va tirer un peu bizarre erreurs en disant: "ClassNotDef Erreur 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.Main

    [ne manquez pas le . ci-dessus]

C'est parce que vous avez placé principal.de java à l'intérieur du paquet edu.sjsu.myapp et java.exe va chercher le modèle exact.

Espère que cela aide !!

3
répondu realPK 2011-11-21 03:54:39

Pour windows, les guillemets doivent être utilisés comme séparateurs. par exemple:

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

forme courte: si votre main est dans un pot, vous aurez probablement besoin d'un '-jar pathTo/yourJar/YourJarsName.jar 'a explicitement déclaré de le faire fonctionner (même si' YourJarsName.pot' était sur le chemin de la 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 re-écl arer chaque pot explicitement, mais ne semble, même avec java6, vous avez besoin de re-écl arer votre propre pot ...)


Forme Longue: (J'ai fait cette explicites au point que j'ai de l'espoir, même intrus à java pouvez utiliser ceci)

comme beaucoup ici j'utilise eclipse pour exporter des jarres: (File->Export-->'Runnable JAR File'). Il y a trois options sur les offres 'Library handling' 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 était définitivement en train de casser), cependant le code natif dans l'un des bocaux que j'utilise j'ai découvert des ruptures avec le trick "jarinjar" très pratique qui permet d'éclipser les leviers lorsque vous choisissez cette option. Même après avoir réalisé que j'avais besoin de l'opt3, et trouver cette entrée StackOverflow, il m'a fallu un certain temps pour comprendre comment lancer mon main en dehors d'eclipse, donc voici ce qui a fonctionné pour moi, car il est utile pour d'autres...


si vous avez nommé votre pot: "fooBarTheJarFile.pot" et tout est réglé pour exporter vers le dir: "/ theFully/qualifiedPath / toYourChosenDir".

(C'est-à-dire le le champ "destination" se lira comme suit: "/theFully/qualifiedPath/toYourChosenDir / fooBarTheJarFile.jar')

après que vous ayez appuyé sur finish, vous trouverez eclipse qui place 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 alors lancer à partir 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 En Java: ".path_to.the_class_with.your_main ' est le chemin de paquet déclaré que vous trouverez en haut du 'TheClassWithYourMain'.le fichier java 'qui contient le' main (String[] args){...}' que vous souhaitez exécuter à partir de l'extérieur de java)


le piège à remarquer: est celui ayant 'fooBarTheJarFile.jar " dans la liste des pots sur votre déclarée classpath n'est pas assez. Vous devez déclarer explicitement '-pot", et redeclare l'emplacement de ce pot.

p.ex. ceci casse:

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

reformulé avec les trajectoires relatives:

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   

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

3
répondu Matt S. 2016-11-29 08:05:39

la seule façon que je connaisse est de le faire individuellement, par exemple:

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

Espère que ça aide!

2
répondu 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
répondu Mindaugas K. 2015-04-29 06:55:56

N'est pas une solution directe à la possibilité de définir /* to-cp mais j'espère que vous pouvez utiliser le script suivant pour faciliter un peu la situation pour les chemins de classes 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 comme entrée dans les "libDir2Scan4jars", le script va scanner tous les jarres et créer une chaîne classpath et l'exporter vers une variable env"tmpCLASSPATH".

1
répondu Sreesankar 2016-06-27 12:05:44

vous devez les ajouter tous séparément. Sinon, si vous vraiment avez juste besoin de spécifier un répertoire, vous pouvez tout déballer dans un dir et ajouter cela à votre classpath. Je ne recommande pas cette approche, cependant, car vous risquez des problèmes bizarres de versioning classpath et d'ingérable.

0
répondu Daniel Spiewak 2008-10-20 19:36:03

pense à un fichier jar comme la racine d'une structure de répertoire. Oui, vous devez ajouter tous séparément.

0
répondu R. Van Hoose 2008-10-20 19:37:49

définit le chemin de classe d'une manière appropriée plusieurs pots 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
répondu Girdhar Singh Rathore 2016-06-30 17:46:41