Question Inclure tous les fichiers jars dans un répertoire du chemin de classe Java


Est-il possible d'inclure tous les fichiers jar dans un répertoire dans le classpath?

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. Ai-je besoin d'ajouter chaque fichier jar au classpath séparément?


844
2017-10-20 19:32


origine


Réponses:


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

  • Utilisez des guillemets droits (")
  • Utilisation *, ne 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 permet la syntaxe suivante (où lib est le répertoire contenant tous les fichiers d'archive Java):

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

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

Comprendre les caractères génériques

Du Classpath document:

Les entrées de chemin de classe peuvent contenir le caractère générique de nom de base *, ce qui équivaut à spécifier une liste de tous les fichiers   dans le répertoire avec l'extension .jar ou .JAR. Par exemple, le   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 à 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. À   correspondre à la fois les 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   classes et ressources dans foo sont chargés avant les fichiers JAR dans foo, ou   vice versa.

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

L'ordre dans lequel les fichiers JAR d'un répertoire sont énumérés dans le répertoire   chemin de classe étendu n'est pas spécifié et peut varier d'une plate-forme à   plate-forme et même de moment en moment sur la même machine. UNE   une application bien construite ne doit pas dépendre d'un   commande. Si une commande spécifique est requise, les fichiers JAR peuvent être   énuméré explicitement dans le chemin de la classe.

L'expansion des caractères génériques est faite tôt, avant l'invocation d'un   méthode principale du programme, plutôt que tard, au cours du chargement de la classe   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 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 la 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.

le CLASSPATH variable d'environnement n'est pas traitée différemment de   la -classpath (ou -cp) option de ligne de commande. Autrement dit, les caractères génériques sont   honoré dans tous ces cas. Cependant, les caractères génériques de chemin de classe ne sont pas   honoré dans le Class-Path jar-manifestentête.

Note: en raison d'un bug connu dans java 8, les exemples de fenêtres doivent utiliser une barre oblique inverse précédant les entrées avec un astérisque à la fin: https://bugs.openjdk.java.net/browse/JDK-8131329


976
2017-10-20 20:32



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

remarquez le * .jar, donc le * wildcard devrait être utilisé seul.


Sur Linux, les travaux suivants:

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

Les séparateurs sont des deux-points à la place des points-virgules.


199
2017-08-14 00:42



Nous contournerons ce problème en déployant un principale fichier jar myapp.jar qui contient un manifeste (Manifest.mf) spécifiant un chemin de classe avec les autres jars requis, qui sont ensuite déployés à côté de celui-ci. 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, puis mettre les jarres dépendants dans un lib dossier ci-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
2017-10-20 20:08



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

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

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

java -cp $ (pour i dans lib / *. jar; echo -n $ i:; done). my.main.Class

36
2018-03-17 10:55



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

Oracle fournit une documentation sur l'utilisation de caractères génériques dans les chemins de classes ici pour Java 6 et ici pour Java 7, sous le titre de la section Présentation des caractères génériques de chemin 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, pour inclure tous les fichiers JAR dans un répertoire donné, vous pouvez utiliser le caractère générique * (ne pas  *.jar).

  • Le caractère générique correspond uniquement aux fichiers JAR et non aux 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 classe dans un répertoire, et les règles habituelles de priorité de chemin de classe s'appliquent. Par exemple. -cp /classes;/jars/*

  • Le caractère générique sera ne pas rechercher des fichiers JAR dans des sous-répertoires.

  • Les points ci-dessus sont vrais si vous utilisez le CLASSPATH propriété du système ou le -cp ou -classpath drapeaux de ligne de commande. Cependant, si vous utilisez le Class-Path En-tête du manifeste JAR (comme vous pourriez le faire avec un fichier de construction ant), les caractères génériques ne pas être honoré.

Oui, mon premier lien est le même que celui fourni dans la réponse de haut niveau (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 Stack Overflow ces jours-ci, Je pensais que je développerais dessus.


27
2017-12-21 19:32



Pour moi cela fonctionne dans les fenêtres.

java -cp "/lib/*;" sample

Pour Linux

java -cp "/lib/*:" sample

j'utilise Java 6


27
2017-10-15 07:43



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

Répertoire pour les jars externes lors de l'exécution de Java


21
2018-03-06 21:00



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
2018-02-13 17:57



les fenêtres:
 java -cp fichier.jar; dir / * mon.app.ClassName

Linux:
java -cp fichier.jar: dir / * mon.app.ClassName

Rappeler:
- les fenêtres le séparateur de chemin est ";"
- Linux le séparateur de chemin est ":"
- Dans Windows si l'argument cp ne contient pas d'espace, les "quotes" sont optionnelles


13
2017-07-18 19:03



Si vous avez vraiment besoin de spécifier dynamiquement tous les fichiers .jar, vous pouvez utiliser des scripts shell, ou Apache Ant. Il y a un projet commun appelé Commons Launcher ce 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).

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 bon chemin de classe.


8
2017-10-20 19:55