Frage

Ich versuche, einen bestimmten JUnit-Test mit der Hand auf einer Windows XP-Befehlszeile ausgeführt werden, die eine ungewöhnlich hohe Anzahl von Elementen im Klassenpfad hat. Ich habe mehrere Varianten ausprobiert, wie zum Beispiel:

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

(Andere Varianten sind die Einstellung der Classpath alle auf einer Linie, die Einstellung der Classpath über -classpath als Argument für java ") Es kommt immer auf die Konsole es die Hände mit diesem Fehler werfen.

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

Dies ist ein JUnit-Test ein ziemlich großes bestehendes Legacy-Projekt zu testen, so dass keine Vorschläge über meine Verzeichnisstruktur etwas vernünftiger Neuanordnung, sind diese Arten von Lösungen aus für jetzt. Ich habe nur versucht, zu gen auf einen schnellen Test gegen dieses Projekt und es auf der Kommandozeile ausgeführt werden, und die Konsole mir mauern. Hilfe!

War es hilfreich?

Lösung

Die Kommandozeile von Windows ist die Begrenzung sehr in dieser Hinsicht. Eine Abhilfe ist es, eine „Wegfindung jar“ zu erstellen. Dies ist ein Glas nur eine Manifest.mf Datei enthält, deren Class-Path legt die Plattenpfade Ihrer langen Liste von Gläsern etc. Nun diese fügen Sie einfach Wegfindung jar auf der Kommandozeile Classpath. Dies ist in der Regel günstiger als die Verpackung die tatsächlichen Ressourcen zusammen.

Wie ich mich erinnere, können die Plattenpfade relativ zu der Wegfindung jar selbst. So ist die Manifest.mf etwas könnte wie folgt aussehen:

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

Wenn Ihr Wegfindung jar enthält hauptsächlich grundlegende Ressourcen, dann wird es nicht zu oft ändern, aber Sie werden wahrscheinlich immer noch wollen es in Ihrem Build irgendwo zu erzeugen. Zum Beispiel:

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

Andere Tipps

Da Java 6 Sie können Classpath Platzhalter .

Beispiel: foo/*, bezieht sich auf alle .jar-Dateien im Verzeichnis foo

  • das wird nicht von Klassendateien übereinstimmen (nur JAR-Dateien). Um sowohl die Nutzung zu entsprechen: foo;foo/* oder foo/*;foo. Die Reihenfolge bestimmt, was zuerst geladen wird.
  • Die Suche ist nicht rekursiv

Verwendung Ein "Argument Datei" auf Java 9 +

In Java 9+, die ausführbaren Java-Datei unterstützt Argumente über eine Datei bereitstellt. Sehen https: // docs .oracle.com / JavaSE / 9 / tools / java.htm # JSWOR-GUID-4856361B-8BFD-4964-AE84-121F5F6CF111 .

Dieser Mechanismus ist ausdrücklich beabsichtigt, das Problem der OS Einschränkungen auf Befehlslängen zu lösen:

  

Sie können mit @argument Dateien mit dem Befehl java verkürzen oder vereinfachen   geben Sie eine Textdatei, die Argumente, wie Optionen enthält und   Klassennamen, zu dem Java-Befehl übergeben. Sie ist dieses let erstellen java   Befehle beliebiger Länge auf jedem Betriebssystem.

     

In der Befehlszeile, verwenden Sie den At-Zeichen (@) Präfix eine identifizieren   Argument-Datei, die Java-Optionen und Klassennamen enthält. Wenn die   java-Kommando angetroffen wird eine Datei mit dem at-Zeichen (@) beginnen, es   erweitert den Inhalt dieses Argument Listendatei in genauso wie sie   würde in der Befehlszeile angegeben werden.

Dies ist die „richtige“ Lösung, wenn Sie Version 9 oder höher ausgeführt werden. Dieser Mechanismus einfach modifiziert, wie das Argument für die JVM zur Verfügung gestellt wird, und ist damit zu 100% kompatibel mit jedem Rahmen oder Anwendung , unabhängig davon, wie sie heißt es tut Classloading ist völlig gleichwertig einfach das Argument auf der Bereitstellung von Befehlszeile wie gewohnt. Dies gilt nicht für manifestbasierte Abhilfen für diese Beschränkung.

Ein Beispiel hierfür ist:

Original-Befehl:

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

kann wie folgt umgeschrieben werden:

java @c:\path\to\cparg

wo c:\path\to\cparg ist eine Datei mit folgendem Inhalt:

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

Diese „Argument Datei“ unterstützt auch die Zeilenfortsetzungszeichen und unter Angabe für richtig Leerzeichen in Pfaden z Handhabung.

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

Gradle

Wenn Sie dieses Problem in Gradle stoßen, sehen Sie dieses Plugin, das automatisch Classpath wandelt in eine „Argumente Datei“ und sieht vor, dass der JVM unter Windows exec oder Testaufgaben zu tun. Unter Linux oder anderen Betriebssystemen es tut nichts standardmäßig, wenn auch ein optionaler Konfigurationswert verwendet werden kann, um die Transformation unabhängig von O anzuwenden.

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

(Disclaimer: Ich bin der Autor)

Siehe auch dieses verwandte Gradle Problem - hoffentlich wird diese Fähigkeit schließlich in Gradle Kern integriert werden: https :. //github.com/gradle/gradle/issues/1989

(ich nehme an, Sie nicht wirklich DOS bedeuten, aber auf cmd.exe verweisen.)

Ich denke, es ist weniger eine CLASSPATH Einschränkung als eine Umgebungsgröße / environment variable Größenbegrenzung. Unter XP können einzelne Umgebungsvariablen 8k in der Größe sein, wird die gesamte Umgebung zu 64k begrenzt. Ich kann nicht sehen Sie würde diese Grenze erreicht.

Es gibt eine Grenze für Fenster, die die Länge einer Befehlszeile beschränkt, auf Windows NT + ist es 8k für cmd.exe. Ein Satz Befehl unterliegt diese Beschränkung. Kann es Ihnen mehr haben als 8k im Wert von Verzeichnissen in Ihrem Set-Befehl? Sie können von Glück, dann - auch wenn man sie wie vorgeschlagen.

Wenn ich an deiner Stelle wäre, würde ich die Kreuzung Dienstprogramm von MS herunterladen: http://technet.microsoft.com/en-us/sysinternals/bb896768.aspx und dann Karte Ihrer "C: \ path" zu sagen "z: \" und "c: \ path2" zu sagen, "y: \". Auf diese Weise werden Sie 4 Zeichen in Ihrem classpath pro Artikel werden reduziert.

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;

Nun Classpath wird:

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

Es könnte mehr tun, abhängig von Ihrem tatsächlichen classpath.

Ich glaube, Sie auf den Bach sind ohne Paddel hier. Die Kommandozeile hat ein Limit für Argumente ein Programm aufzurufen.

Ich habe 2 sugestion Sie könnten versuchen. Zuerst wird vor den JUnit-Tests ausgeführt wird, können Sie einen Skript lassen / ant_task JAR-Dateien der verschiedenen Klassen auf dem Classpath erstellen. Dann können Sie die JAR-Dateien auf dem Classpath setzen, die kürzer sein sollte.

Eine andere Möglichkeit, Sie versuchen könnte, ist eine antscript zu schaffen laufen JUNIT, in ANT sollte Classpath-Einträge nicht so eine Grenze für.

Wie HuibertGill erwähnt, würde ich wickeln diese in einem Ant-Build-Skript einfach so, dass Sie all dies nicht gelingt, müssen sich selbst.

Sie könnten versuchen, diese


@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%;"
go

zu einer Eingabeaufforderung und führen Sie es zweimal (keine Ahnung, warum .... ich so auf einem Windows XP-Maschine zu tun haben) auch die Pfade r nur für die aktuelle Eingabeaufforderungssitzung eingestellt

Es gab keine Lösung für das Problem anders als irgendwie die Classpath kürzer machen, indem Sie die JAR-Dateien in einen Ordner wie zu bewegen. „C: \ Gläser“

Durch Raman für eine neue Lösung für ein Problem Wegfindung für Java 9+ einzuführen. Ich habe einen Hack Aufgabe bootRun, die alles schon von gradle ausgewertet können Java mit dem Argument Dateien auszuführen. Nicht sehr elegant, aber arbeiten.

// 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 = ''
        }
    }
}

Haben Sie versucht, sie stapeln?

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%
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top