Question

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 définissent le chemin d'accès aux classes sur une seule ligne et définissent le chemin d'accès aux classes via -classpath en tant qu'argument à 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 testant un projet existant assez volumineux. Par conséquent, aucune suggestion quant à la réorganisation de la structure de mes répertoires en un système 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. Au secours!

Était-ce utile?

La solution

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 le Class-Path spécifie les chemins de disque de votre longue liste de fichiers JAR, etc. Ajoutez maintenant ceci cheminant jar vers votre chemin de classe en ligne de commande. C’est généralement plus pratique que de regrouper les ressources réelles.

Si je me souviens bien, les chemins d'accès au disque peuvent être relatifs au chemin de cheminement lui-même. Ainsi, le Manifest.mf pourrait ressembler à ceci:

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

Si votre cheminement de cheminement contient principalement des ressources de base, il ne sera pas modifié trop souvent, mais vous souhaiterez probablement 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>

Autres conseils

Depuis Java 6, vous pouvez utiliser classpath. caractères génériques .

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 . La commande détermine ce qui est chargé en premier.
  • La recherche n'est PAS récursive

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

Sous 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 les 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 du java   commandes de toute 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 arobase (@), elle   étend le contenu de ce fichier dans une liste d'arguments, tout comme ils   serait spécifié sur la ligne de commande.

C’est le " right " 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 manière dont ils effectuent le chargement de classes. En d'autres termes, il est complètement équivalent à fournir l'argument de la même manière. ligne de commande comme d'habitude. Ce n'est pas vrai pour les solutions de contournement basées sur les manifestes à cette limitation de système d'exploitation.

Voici un exemple:

Commande d'origine:

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

peut être réécrit comme suit:

java @c: \ chemin \ vers \ cparg

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

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

Ce "fichier d'argument" " prend également en charge les caractères de continuation de ligne et les citations pour gérer correctement les espaces dans les chemins d'accès, par exemple.

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

Gradeau

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 fournit ces informations à 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, mais une valeur de configuration facultative peut ê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 aussi 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 .

(je suppose que vous ne voulez pas vraiment dire DOS, mais faites référence à 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 existe une limite sur Windows qui limite la longueur d'une ligne de commande. Sous Windows NT +, il est de 8 Ko 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 suit: Nick Berardi a suggéré.

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 mappez votre "C: \ path" pour dire, " z: \ " et " c: \ path2 " pour dire, "y:". De cette façon, vous réduirez de 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 chemin de classe actuel.

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

J'ai 2 suggestions que vous pouvez essayer. Tout d’abord, avant d’exécuter les tests Junit, vous pouvez laisser un script / ant_task créer les fichiers JAR des différentes classes sur le chemin de classe. Ensuite, vous pouvez mettre les JAR sur le classpath, qui devrait être plus court.

Vous pouvez également essayer de créer un index pour exécuter JUNIT, dans ANT, il ne devrait pas y avoir une telle limite pour les entrées de classpath.

Comme le mentionne HuibertGill, je l’encapsulerais dans un script de génération Ant simplement pour que vous n’ayez pas à gérer tout cela vous-même.

Vous pouvez essayer ceci

@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 à une invite de commande et exécutez-la deux fois (vous ne savez pas pourquoi…. Je dois le faire sur un ordinateur Windows XP). également les chemins r définis uniquement pour la session d'invite de commande en cours

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".

Merci à Raman d'avoir présenté une nouvelle solution à un problème de cheminement pour Java 9+. J'ai fait un hack à la tâche bootRun qui permet d'utiliser tout ce qui est déjà évalué par gradle pour exécuter java avec des fichiers d'arguments. Pas très élégant mais fonctionnel.

// Fix long path problem on Windows by utilizing java Command-Line Argument Files 
// https://docs.oracle.com/javase/9/tools/java.htm#JSWOR-GUID-4856361B-8BFD-4964-AE84-121F5F6CF111 
// The task creates the command-line argument file with classpath
// Then we specify the args parameter with path to command-line argument file and main class
// Then we clear classpath and main parameters
// As arguments are applied after applying classpath and main class last step 
// is done to cheat gradle plugin: we will skip classpath and main and manually
// apply them through args
// Hopefully at some point gradle will do this automatically 
// https://github.com/gradle/gradle/issues/1989 

if (Os.isFamily(Os.FAMILY_WINDOWS)) {
    bootRun {
        doFirst {
            def argumentFilePath = "build/javaArguments.txt"
            def argumentFile = project.file(argumentFilePath)
            def writer = argumentFile.newPrintWriter()
            writer.print('-cp ')
            writer.println(classpath.join(';'))
            writer.close()

            args = ["@${argumentFile.absolutePath}", main]
            classpath = project.files()
            main = ''
        }
    }
}

Avez-vous essayé de les empiler?

set CLASS_PATH = c:\path
set ALT_A = %CLASS_PATH%\a\b\c;
set ALT_B = %CLASS_PATH%\e\f\g;
...

set ALL_PATHS = %CLASS_PATH%;%ALT_A%;%ALT_B%
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top