Inclusion de tous les fichiers JAR dans un répertoire du chemin de classe Java

1019

Existe-t-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.Programet il n'est pas en mesure de trouver des fichiers de classe qui se trouvent certainement dans ces pots. Dois-je ajouter chaque fichier jar au chemin de classe séparément?

Chris Serra
la source
3
Désolé, je n'ai jamais accepté cela. Ce devrait être un wiki communautaire. Jamais utilisé l'une des réponses fournies. Je crois que j'ai créé un script shell qui vient de scanner le répertoire lib / et a créé le chemin de classe à partir de l'analyse des noms de fichiers.
Chris Serra
Il y a une sorte de bogue dans cette nouvelle fonctionnalité Java, car elle ne fonctionne pas comme décrit. J'ai abandonné et utilisé Ant pour contourner ce problème, comme décrit dans l'une des réponses.
Alex R
1
Il y a un problème avec le traitement des caractères génériques dans Windows. stackoverflow.com/questions/11607873/…
Mykhaylo Adamovych
6
Réponse courte: (1) supprimez la .jarpartie, (2) doit avoir au moins 2 parties, séparées par un ;sur Windows (qui est généralement :ailleurs). Par exemple:java -classpath ".;lib/*" Program
Evgeni Sergeev

Réponses:

1160

À l'aide de Java 6 ou version ultérieure, l'option classpath prend en charge les caractères génériques. Notez les points suivants:

  • Utilisez 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 à la :place de ;. Si vous ne pouvez pas utiliser de caractères génériques, bashautorise la syntaxe suivante (où se libtrouve le répertoire contenant tous les fichiers d'archive Java):

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

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

Comprendre les caractères génériques

Depuis le document Classpath :

Les entrées de chemin de classe peuvent contenir le caractère générique du nom de base *, qui est considéré comme équivalent à spécifier une liste de tous les fichiers du répertoire avec l'extension .jarou .JAR. Par exemple, l'entrée du chemin d'accès aux classes foo/*spécifie tous les fichiers JAR du répertoire nommé foo. Une entrée classpath consistant simplement à se *développer en une liste de tous les fichiers jar du répertoire courant.

Une entrée de chemin de classe qui contient *ne correspondra pas aux fichiers de classe. Pour faire correspondre 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 les classes et les ressources dans foosont chargées avant les fichiers JAR dans foo, ou vice versa.

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

L'ordre dans lequel les fichiers JAR d'un répertoire sont énumérés dans le chemin d'accès aux classes étendues n'est pas spécifié et peut varier d'une plateforme à l'autre et même d'un instant à l'autre sur la même machine. Une application bien construite ne doit pas dépendre d'un ordre particulier. Si une commande spécifique est requise, les fichiers JAR peuvent être énumérés explicitement dans le chemin d'accès aux classes.

L'expansion des caractères génériques se fait tôt, avant l'invocation de la méthode principale d'un programme, plutôt que tardivement, pendant le processus de chargement de classe lui-même. Chaque élément du chemin de classe d'entrée contenant un caractère générique est remplacé par la séquence (éventuellement vide) d'éléments générée par l'énumération des fichiers JAR dans le répertoire nommé. Par exemple, si le répertoire foocontient a.jar, b.jaret c.jar, le chemin de la classe foo/*est étendue dans 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 CLASSPATHvariable d'environnement n'est pas traitée différemment de l' option de ligne de commande -classpath(ou -cp). Autrement dit, les caractères génériques sont honorés dans tous ces cas. Cependant, les caractères génériques de chemin de classe ne sont pas respectés dans l'en- Class-Path jar-manifesttête.

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

basszero
la source
2
La fonctionnalité est mal documentée et semble nécessiter des conditions préalables moins évidentes pour fonctionner comme prévu.
Alex R
1
+1 pour le dernier tour bash / tr. Java / JamVM ici n'aime pas les caractères génériques pour les chemins en dehors du répertoire de travail, mais référencer explicitement chaque JAR en utilisant le caractère générique + trfonctionne!
Supr
1
J'ai une commande java -classpath /jars/*:/anotherJarsDir/* com.test.MyClasssans guillemets et cela fonctionne très bien. Je me demande pourquoi le shell ne l'étend pas et ne fait pas d'erreur?
yellavon
3
Ne pas utiliser non plus ~dans le -cp
Sohail Si
1
Votre exemple Windows ne fonctionne pas avec Java 8 ou une version antérieure, mais avec ce chemin de classe: Test.jar; lib \ * ... la barre oblique est correcte, sauf si elle précède un astérisque et quelques autres ... voir bugs.openjdk. java.net/browse/JDK-8131329
philwalk
226

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.

davorp
la source
17
La réponse parfaite. 2 choses importantes à noter: 1) Utilisez des guillemets et 2) Utilisez * seulement, pas * .jar
Wim Deblauwe
4
Un an et 8 mois plus tard, la modification que j'ai effectuée pour inclure la version UNIX m'a de nouveau sauvé. :) Drôle comment il ne reconnaîtrait pas mes fichiers jar avec *.jarmais seulement avec *.
jmort253
J'ai trouvé que l'ordre des chemins de classe est important (mais je ne sais pas pourquoi). J'obtenais des erreurs jusqu'à ce que je change l'ordre des chemins de classe.
user13107
@ jmort253, le problème est que ce n'est pas le shell * qui se développe, mais le caractère générique java analyse le chemin de classe, voit le * et remplit le caractère générique
Sebastian
1
@SebastianGodelet - Ouais, c'est juste que je me confond entre les caractères génériques Regex et cette notation, qui n'est pas la même, je suppose. Surtout, ce qui m'a sauvé, c'est de savoir la différence entre :sur une plateforme et ;sur l'autre. :) Je compile avec Java à partir de la ligne de commande environ une fois par an, juste assez pour ne pas me souvenir de la fréquence, mais assez ennuyeux.
jmort253
67

Nous contournons ce problème en déployant un fichier jar principalmyapp.jar qui contient un fichier manifest ( Manifest.mf) spécifiant un chemin de classe avec les autres jars requis, qui sont ensuite déployés à côté. Dans ce cas, vous devez uniquement déclarer java -jar myapp.jarlors de l'exécution du code.

Donc, si vous déployez le principal jardans un répertoire, puis placez les pots dépendants dans un libdossier 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 pots pour lancer sur un serveur UNIX ou sur un PC Windows.

oxbow_lakes
la source
Cela semble fonctionner pour beaucoup de gens, cependant, Java semble ignorer clairement les entrées de chemin de classe dans le fichier manifeste ici. Nous ne pouvons pas exécuter l'application sans ajouter manuellement "lib / *" au chemin de classe en utilisant -cp. Des idées?
Raku
6
la réponse d'oxbow_lakes n'est pas entièrement correcte; la chose Class-Path est honorée (et UNIQUEMENT qui est honorée; -cp / -classpath est ignoré!) si vous démarrez ce pot avec java -jar myapp.jar. Je suppose que oxbow_lakes voulait écrire cela quand il a écrit 'java -classpath myapp.jar'.
rzwitserloot du
47

Ma solution sur Ubuntu 10.04 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 tous les * .jars du répertoire lib dans le paramètre classpath)

java -cp $ (pour i dans lib / *. jar; do echo -n $ i:; done). my.main.Class
Habi
la source
4
une drôle de note. java -cp lib / * my.main.Class échouera toujours car l'expansion du shell glob de lib / *, tandis que java -cp.: lib / * my.main.Class ne le sera pas parce que.: lib / * n'est pas un glob valide chemin. Prenez le temps de noter que
albfan
1
Cela ne fonctionne pas; linux étendra le . vous pouvez essayer: java -cp '.: lib / ' et cela fonctionne très bien (notez les guillemets simples! Cela ne fonctionnera pas avec les guillemets doubles!). En fait,.: Lib / * pourrait fonctionner si ce n'est pas un glob légitime à cause du deux-points, mais cela semble un peu incertain. J'ajouterais les citations. Les guillemets simples indiquent à bash de ne toucher aucune partie du contenu.
rzwitserloot
Peu importe (dans ce contexte) si vous utilisez des guillemets simples ou doubles. Vous voulez empêcher le shell de développer (globuler) le *, c'est tout. Et passez littéralement le texte "lib / *" à la machine virtuelle Java, afin que la machine virtuelle le reconnaisse comme un "modèle spécial" et recherche d'elle-même les fichiers jar.
Angel O'Sphere
36

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

Oracle fournit de la documentation sur l'utilisation des caractères génériques dans les chemins de classe ici pour Java 6 et ici pour Java 7 , sous la rubrique Comprendre 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 points 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 *( 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, 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 de classe dans un répertoire, et les règles de priorité de chemin de classe habituelles s'appliquent. Par exemple-cp /classes;/jars/*

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

  • Les puces ci-dessus sont vraies si vous utilisez la CLASSPATHpropriété système ou les indicateurs de ligne de commande -cpou -classpath. Cependant, si vous utilisez leClass-Path tête du manifeste JAR (comme vous pourriez le faire avec un fichier de génération de fourmis), 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'explications au-delà du lien. Étant donné que ce type de comportement est déconseillé sur Stack Overflow ces jours-ci , je pensais que je développerais cela.

Pops
la source
mon problème était avec lib / *. jar plutôt que lib / *. Merci beaucoup, cela a résolu le problème. J'ai remarqué qu'il y a une différence entre: et; mais cela pourrait être mon genre de test-de-nombreux-changements-en-même temps.
Eyad Ebrahim
Merci d'avoir souligné la différence entre * et * .jar
burakhan alkan
36

Windows :

 java -cp file.jar;dir/* my.app.ClassName

Linux :

 java -cp file.jar:dir/* my.app.ClassName

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

Wender
la source
l'exemple de Windows ne fonctionne pas pour java 8 et versions
philwalk
Peut-être que cela ne fonctionne pas pour le JDK ouvert, je vais tester cela et je vais en parler ici
Wender
Désolé, j'ai testé avec HotSpot et j'ai pensé que cela fonctionne avec openjdk.
Wender
Oracle java sous windows nécessite une barre oblique inverse avant l'astérisque plutôt qu'une barre oblique, bien que je n'ai pas testé à nouveau les versions java les plus récentes ou alternatives.
philwalk
ne fonctionne pas sur macos
Greyshack
34

Pour moi, cela fonctionne sous Windows.

java -cp "/lib/*;" sample

Pour linux

java -cp "/lib/*:" sample

J'utilise Java 6

SANN3
la source
l'exemple de Windows semble avoir fonctionné pour java 6, peut-être java 7, mais pas pour java 8 (voir bugs.openjdk.java.net/browse/JDK-8131329 )
philwalk
Fonctionne pour java 8 sous linux
Jonathan Drapeau
29

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

Répertoire des fichiers jars externes lors de l'exécution de java

Navi
la source
3
Cela fonctionne, mais attention, passez le -Djava.ext.dirs=AVANT-jar
Giovanni Funchal
5
java.ext.dirs fonctionnera très différemment d'un pot normal dans classpath. Il a une priorité et une autorisation plus élevées qui pourront en quelque sorte remplacer les classes dans bootstamp (rt.jar)
Dennis C
Merci. Sur 'Java version "1.8.0_221" Java (TM) SE Runtime Environment (build 1.8.0_221-b27) Java HotSpot (TM) 64-Bit Server VM (build 25.221-b27, mixed mode)', seulement cette version -D de passer dans le chemin de classe a fonctionné. La forme traditionnelle ne l'a pas fait.
Matt Campbell
23

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
rvernica
la source
9

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 qui vous permet essentiellement de spécifier votre script de démarrage en tant que fichier de génération de fourmis (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 lancement, qui lancera votre application avec le chemin de classe correct.


la source
8

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/*;"

Jake Toronto
la source
6

À qui cela concerne,

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

Travaux:

$ 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 './*'
./*

(J'ai également essayé avec un autre programme, plutôt qu'avec le programme intégré echo, avec le même résultat.)

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

C'est

$ javac -version
javac 1.7.0
Evgeni Sergeev
la source
5

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

Si vous êtes sous Windows 7 et avez utilisé Eclipse IDE pour le développement en Java, vous pouvez rencontrer des problèmes si vous utilisez l'invite de commandes pour exécuter les fichiers de classe créés dans Eclipse.

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

Vous avez json.jar comme dépendance externe pour Main.java

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

Mais lorsque vous essayez de l'exécuter à l'aide de l'invite de commandes après avoir compilé Main.java dans Eclipse, cela provoquera des 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 commandes:

  1. javac -cp ".; json.jar" Main.java

  2. java -cp ".; json.jar" edu.sjsu.myapp.Main

    [Ne manquez pas le. au dessus de]

En effet, vous avez placé le fichier Main.java dans le package edu.sjsu.myapp et java.exe recherchera le modèle exact.

J'espère que cela aide !!

realPK
la source
4

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

java -cp "target\\*;target\\dependency\\*" my.package.Main
Alexey
la source
4

Forme courte: si votre main se trouve dans un bocal, vous aurez probablement besoin d'un '-jar pathTo / 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 initiale posée il y a 5 ans: vous n'avez pas besoin de redéclarer chaque pot de manière explicite, mais il semble, même avec java6, vous devez redéclarer votre propre pot ...)


Forme longue: (J'ai rendu cela explicite au point que j'espère que même les intrus de Java pourront l'utiliser)

Comme beaucoup ici, j'utilise eclipse pour exporter des pots: (Fichier-> Exporter -> 'Fichier JAR exécutable'). Il existe trois options sur les offres d'éclipse (Juno) de «gestion des bibliothèques»:

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"

En général, j'utilisais 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 "jarinjar" pratique qu'éclipse utilise lorsque vous choisissez cette option. Même après avoir réalisé que j'avais besoin d'opt3, puis trouver cette entrée StackOverflow, il m'a fallu un certain temps pour comprendre comment lancer mon principal en dehors d'Eclipse, alors voici ce qui a fonctionné pour moi, car il est utile pour les autres ...


Si vous avez nommé votre jar: "fooBarTheJarFile.jar" et que tout est configuré pour être exporté dans le répertoire: "/ theFully / qualifiéPath / toYourChosenDir".

(ce qui signifie que le champ «Destination d'exportation» se lira: «/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar»)

Une fois que vous avez terminé, vous trouverez eclipse puis 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 ensuite lancer depuis 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.path_to.the_class_with.your_main' est le chemin de package déclaré que vous trouverez en haut du fichier 'TheClassWithYourMain.java' qui contient les 'main (String [] args) {.. .} 'que vous souhaitez exécuter depuis l'extérieur de java)


Le piège à remarquer: est que le fait d'avoir 'fooBarTheJarFile.jar' dans la liste des pots sur votre chemin de classe déclaré n'est pas suffisant. Vous devez déclarer explicitement '-jar' et redéclarer l'emplacement de ce pot.

par exemple, cela casse:

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

retraité 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)

Matt S.
la source
3

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

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

J'espère que cela pourra aider!

ParseTheData
la source
C'était peut-être le seul moyen de revenir en 2008, mais plus maintenant.
simo.3792
Ce n'est pas la pire chose. C'est un hack, mais j'ai cet ensemble dans mon bashrcfor jar in $(ls $HOME/bin/*.jar); do export CLASSPATH=$jar:$CLASSPATH; done
Devon Peticolas
3

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
Mindaugas K.
la source
2

Vous devez les ajouter tous séparément. Alternativement, si vous avez vraiment besoin de simplement spécifier un répertoire, vous pouvez tout supprimer dans un seul répertoire et l'ajouter à votre chemin de classe. Cependant, je ne recommande pas cette approche car vous risquez des problèmes bizarres dans la gestion des versions de classpath et la non-gérabilité.

Daniel Spiewak
la source
3
C'était peut-être le seul moyen de revenir en 2008, mais plus maintenant.
simo.3792
2

Ce n'est pas une solution directe pour pouvoir définir / * sur -cp mais j'espère que vous pourrez utiliser le script suivant pour alléger 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 également en avoir un similaire pour Windows. Si le répertoire approprié est fourni comme entrée dans les "libDir2Scan4jars"; le script analysera tous les fichiers JAR, créera une chaîne de chemin de classe et l'exportera vers une variable env "tmpCLASSPATH".

Sreesankar
la source
2

macOS, dossier actuel

Pour Java 13 sur macOS Mojave

Si tous vos .jarfichiers sont dans le même dossier, utilisez cdpour en faire votre répertoire de travail actuel . Vérifiez avecpwd .

Pour le, -classpathvous devez d'abord répertorier le fichier JAR de votre application. En utilisant un caractère deux-points :comme délimiteur, ajoutez un astérisque *pour obtenir tous les autres fichiers JAR dans le même dossier. Enfin, passez le nom complet du package de la classe avec votre mainméthode .

Par exemple, pour une application dans un fichier JAR nommé my_app.jaravec une mainméthode dans une classe nommée Appdans un package nommé com.example, à côté de quelques pots nécessaires dans le même dossier:

java -classpath my_app.jar:* com.example.App
Basil Bourque
la source
ne fonctionne pas pour java 8
Greyshack
1

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

Robert Van Hoose
la source
1

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

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
Girdhar Singh Rathore
la source
0

J'ai plusieurs pots dans un dossier. La commande ci-dessous a fonctionné pour moi JDK1.8afin d'inclure tous les pots présents dans le dossier. Veuillez noter que pour inclure entre guillemets si vous avez un espace dans le chemin de classe

les fenêtres

Compilation: javac -classpath "C:\My Jars\sdk\lib\*" c:\programs\MyProgram.java

Fonctionnement: java -classpath "C:\My Jars\sdk\lib\*;c:\programs" MyProgram

Linux

Compilation: javac -classpath "/home/guestuser/My Jars/sdk/lib/*" MyProgram.java

Fonctionnement: java -classpath "/home/guestuser/My Jars/sdk/lib/*:/home/guestuser/programs" MyProgram

vkrams
la source
-1

J'essaie d'exécuter le fichier Java en tant que jar ou en tant que classes dans Ubuntu. J'ai échoué dans les deux options. L'exception suivante est sa sortie.

Download link: https://upload.cat/f694139f88c663b1

java org.statmetrics.Statmetric

ou

java -cp /home/elias/statmetrics/statmetrics.jar :. org.statmetrics.Statmetrics

ou

java -classpath "/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/*" -jar /home/elias/statmeics/statmetrics.jar org.statmetrics.Statmetrics

Exception in thread "Thread-0" java.lang.NoClassDefFoundError: javax/xml/bind/annotation/adapters/XmlAdapter
    at java.base/java.lang.ClassLoader.defineClass1(Native Method)
    at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016)
    at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174)
    at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:802)
    at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:700)
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:623)
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    at org.statmetrics.c.a(Unknown Source)
    at org.statmetrics.dw.a(Unknown Source)
    at org.statmetrics.dx.run(Unknown Source)
Caused by: java.lang.ClassNotFoundException: javax.xml.bind.annotation.adapters.XmlAdapter
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    ... 12 more

J'ai trouvé la réponse:

Ma stupidité.

Première étape: vous devez paramétrer le Java correspondant: j'avais Java 11 mais j'ai défini comme chemin de lib Java la 8ème version! - Vous pouvez définir la version Java à partir d'ici:

  sudo update-alternatives --config java

2ème étape: exécutez ensuite la commande suivante, en changeant les noms de chemin et de fichier en votre chemin et fichiers correspondants:

  java -classpath "/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/*" -jar /home/elias/statmetrics/statmetrics.jar org.statmetrics.Statmetrics

Il a été exécuté avec succès!

Elias EstatisticsEU
la source