web-dev-qa-db-fra.com

Comment définir un long chemin de classes Java sous Windows?

J'essaie d'exécuter manuellement un test JUnit particulier sur une ligne de commande Windows XP, qui contient un nombre anormalement élevé d'éléments dans le chemin d'accès aux classes. J'ai essayé plusieurs variantes, telles que:

set CLASS_PATH=C:\path\a\b\c;C:\path\e\f\g;....
set CLASS_PATH=%CLASS_PATH%;C:\path2\a\b\c;C:\path2\e\f\g;....
...
C:\apps\jdk1.6.0_07\bin\Java.exe -client Oracle.jdevimpl.junit.runner.TestRunner com.myco.myClass.MyTest testMethod

(D'autres variantes consistent à placer le classpath sur une seule ligne, en définissant le classpath via -classpath comme argument pour Java "). Cela revient toujours à la console qui lève les mains avec cette erreur:

The input line is too long.
The syntax of the command is incorrect.

Il s'agit d'un test JUnit qui teste un projet existant assez volumineux. Par conséquent, aucune suggestion quant à la réorganisation de la structure de mon répertoire en quelque chose de plus raisonnable, ces types de solutions n'existent plus. J'essayais juste de générer un test rapide contre ce projet et de l'exécuter sur la ligne de commande, et la console me bloque. Aidez-moi!

39
Ogre Psalm33

La ligne de commande Windows est très limitante à cet égard. Une solution de contournement consiste à créer un "pot de cheminement". Il s'agit d'un fichier jar contenant uniquement un fichier Manifest.mf, dont Class-Path spécifie les chemins d'accès au disque de votre longue liste de fichiers jar, etc. Ajoutez maintenant ceci pathing jar à votre chemin de classe en ligne de commande. Cela est généralement plus pratique que de regrouper les ressources réelles.

Si je me souviens bien, les chemins du disque peuvent être relatifs au chemin du fichier lui-même. Donc, le Manifest.mf pourrait ressembler à ceci:

Class-Path: this.jar that.jar ../lib/other.jar

Si votre pathing jar contient principalement des ressources de base, il ne changera pas trop souvent, mais vous voudrez probablement quand même le générer quelque part dans votre construction. Par exemple:

<jar destfile="pathing.jar">
  <manifest>
    <attribute name="Class-Path" value="this.jar that.jar ../lib/other.jar"/>
  </manifest>
</jar>
52
Chris Noe

Depuis Java 6, vous pouvez utiliser classpath wildcards .

Exemple: foo/*, fait référence à tous les fichiers .jar du répertoire foo

  • cela ne correspondra pas aux fichiers de classe (uniquement les fichiers jar). Pour faire correspondre les deux, utilisez: foo;foo/* ou foo/*;foo. L'ordre détermine ce qui est chargé en premier.
  • La recherche n'est PAS récursive
20
johnstok

(Je suppose que vous ne voulez pas vraiment dire DOS, mais que vous vous référez à cmd.exe.)

Je pense que c'est moins une limitation CLASSPATH qu'une limite de taille d'environnement/taille d'environnement. Sous XP, les variables d’environnement individuelles peuvent avoir une taille de 8 Ko, l’environnement complet est limité à 64 Ko. Je ne vois pas que vous atteindriez cette limite.

Il y a une limite sur Windows qui limite la longueur d'une ligne de commande, sur Windows NT +, il est de 8k pour cmd.exe. Une commande set est soumise à cette restriction. Peut-être que vous avez plus de 8 000 répertoires dans votre commande set? Vous risquez de ne pas avoir de chance, même si vous les séparez comme le suggère Nick Berardi .

4
Tomalak

Utiliser un "fichier d'argument" sur Java 9+

Dans Java 9+, l'exécutable Java prend en charge la fourniture d'arguments via un fichier. Voir https://docs.Oracle.com/javase/9/tools/Java.htm#JSWOR-GUID-4856361B-8BFD-4964-AE84-121F5F6CF111 .

Ce mécanisme est explicitement destiné à résoudre le problème des limitations de longueur de commande du système d'exploitation:

Vous pouvez raccourcir ou simplifier la commande Java en utilisant des fichiers @argument pour spécifier un fichier texte contenant des arguments, tels que des options et noms de classe, passés à la commande Java. Ceci vous permet de créer Java commandes de n'importe quelle longueur sur n'importe quel système d'exploitation.

Dans la ligne de commande, utilisez le préfixe arobase (@) pour identifier un fichier d'argument contenant les options Java et les noms de classe. Quand le La commande Java rencontre un fichier commençant par le signe at (@), it étend le contenu de ce fichier dans une liste d'arguments comme ils le font serait spécifié sur la ligne de commande.

C'est la "bonne" solution, si vous utilisez la version 9 ou supérieure. Ce mécanisme modifie simplement la façon dont l'argument est fourni à la machine virtuelle Java, et est donc compatible à 100% avec tout framework ou application}, _ quelle que soit la façon dont ils effectuent le chargement de classes, c’est tout à fait équivalent à fournir l’argument sur la commande ligne comme d'habitude. Ce n'est pas vrai pour les solutions de contournement basées sur un manifeste à cette limitation de système d'exploitation.

Un exemple de ceci est:

Commande d'origine:

Java -cp c:\foo\bar.jar;c:\foo\baz.jar

peut être réécrit comme:

Java @c:\path\to\cparg

c:\path\to\cparg est un fichier qui contient:

-cp c:\foo\bar.jar;c:\foo\baz.jar

Ce "fichier d’arguments" prend également en charge les caractères de continuation de ligne et les citations permettant de gérer correctement les espaces dans les chemins, par exemple.

-cp "\
c:\foo\bar.jar;\
c:\foo\baz.jar"

Gradle

Si vous rencontrez ce problème dans Gradle, consultez ce plug-in, qui convertit automatiquement votre chemin d'accès aux classes en un "fichier d'arguments" et le fournit à la machine virtuelle Java lors de l'exécution de tâches d'exécution ou de test sous Windows. Sous Linux ou d'autres systèmes d'exploitation, il ne fait rien par défaut, bien qu'une valeur de configuration facultative puisse être utilisée pour appliquer la transformation, quel que soit le système d'exploitation.

https://github.com/redocksoft/classpath-to-file-gradle-plugin

(disclaimer: je suis l'auteur)

Voir également ce problème lié à Gradle - espérons que cette fonctionnalité sera éventuellement intégrée au noyau de Gradle: https://github.com/gradle/gradle/issues/1989 .

1
Raman

Si j'étais à votre place, je téléchargerais l'utilitaire de jonction à partir de MS: http://technet.Microsoft.com/en-us/sysinternals/bb896768.aspx puis mapper votre. chemin "à dire," z:\"et" c:\chemin2 "à dire," y:\". De cette façon, vous réduirez 4 caractères par élément dans votre classpath

set CLASS_PATH=C:\path\a\b\c;C:\path\e\f\g;
set CLASS_PATH=%CLASS_PATH%;C:\path2\a\b\c;C:\path2\e\f\g;

Maintenant, votre chemin de classe sera: 

set CLASS_PATH=z\a\b\c;z\e\f\g;
set CLASS_PATH=%CLASS_PATH%;y:\a\b\c;y:\e\f\g;

Cela pourrait faire plus en fonction de votre classpath réelle.

1
anjanb

Comme le mentionne HuibertGill, je voudrais envelopper ceci dans un script de construction Ant simplement pour que vous n'ayez pas à gérer tout cela vous-même.

0
matt b

Je pense que vous êtes en haut de la crique sans une palette ici . La ligne de commande a une limite pour les arguments d'appeler un programme.

J'ai deux suggestions que vous pourriez essayer… .. Premièrement, avant d'exécuter les tests de Junit, vous pouvez laisser un script/ant_task créer des JAR des différentes classes sur le chemin de classe . Ensuite, vous pouvez les mettre sur le chemin de classe, qui devrait être plus court.

Une autre façon d'essayer est de créer un script pour exécuter JUNIT, Dans ANT, il ne devrait pas y avoir une telle limite pour les entrées de chemin d'accès aux classes.

0
Huibert Gill

Il n’existait aucune solution au problème, à part réduire le chemin de classe en déplaçant les fichiers jar dans un dossier du type "C:\jars".

0
Snehal Masne

Tu pourrais essayer ça


@echo off
set A=D:\jdk1.6.0_23\bin
set B=C:\Documents and Settings\674205\Desktop\JavaProj
set PATH="%PATH%;%A%;"
set CLASSPATH="%CLASSPATH%;%B%;"

accédez à l'invite de commande et exécutez-la deux fois (vous ne savez pas pourquoi. Je dois le faire sur une machine Windows XP).

0
Shivananda Sahu