Windows で長い Java クラスパスを設定するにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/201816

  •  03-07-2019
  •  | 
  •  

質問

Windows XP コマンド ラインで特定の JUnit テストを手動で実行しようとしていますが、クラス パス内の要素の数が異常に多いです。次のようないくつかのバリエーションを試してみました。

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

(他のバリエーションとしては、クラスパスをすべて 1 行で設定する方法や、-classpath を java への引数として使用してクラスパスを設定する方法があります。)結局のところ、コンソールが次のエラーで手を投げ出してしまいます。

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

これは、かなり大規模な既存のレガシー プロジェクトをテストする JUnit テストであるため、ディレクトリ構造をより合理的なものに再配置することに関する提案はありません。そのような種類のソリューションは現時点では公開されていません。このプロジェクトに対して簡単なテストを作成し、コマンド ラインで実行しようとしたところ、コンソールが邪魔をしてしまいました。ヘルプ!

役に立ちましたか?

解決

Windowsのコマンドラインは、この点で非常に制限されています。回避策は、「pathing jar」を作成することです。これは Manifest.mf ファイルのみを含むjarファイルで、その Class-Path はjarファイルの長いリストのディスクパスを指定します。次に、この jarをコマンドラインクラスパスにパスします。これは通常、実際のリソースを一緒にパッケージ化するよりも便利です。

思い出すと、ディスクパスは pathing jar に相対することができます。したがって、 Manifest.mf は次のようになります。

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

pathing jar に主に基本的なリソースが含まれている場合、あまり頻繁に変更されることはありませんが、おそらくビルドのどこかに生成する必要があります。例:

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

他のヒント

Java 6以降では、 classpathを使用できます。ワイルドカード

例: foo / * 、ディレクトリ foo

内のすべての.jarファイルを参照します
  • これはクラスファイルと一致しません(jarファイルのみ)。両方に一致させるには、 foo; foo / * または foo / *; foo を使用します。最初にロードされるものは順序によって決まります。
  • 検索は再帰的ではありません

Java 9以降で「引数ファイル」を使用する

Java 9 以降では、Java 実行可能ファイルはファイルを介した引数の提供をサポートしています。見るhttps://docs.oracle.com/javase/9​​/tools/java.htm#JSWOR-GUID-4856361B-8BFD-4964-AE84-121F5F6CF111.

このメカニズムは、コマンドの長さに関する OS の制限の問題を解決することを明確に目的としています。

@Argumentファイルを使用して、オプションやクラス名などの引数を含むテキストファイルをJavaコマンドに渡すテキストファイルを指定することにより、Javaコマンドを短縮または簡素化できます。 これにより、オペレーティングシステムで任意の長さのJavaコマンドを作成できます。

コマンドラインでは、AT Sign(@)プレフィックスを使用して、Javaオプションとクラス名を含む引数ファイルを識別します。JavaコマンドがAT Sign(@)で始まるファイルに遭遇すると、コマンドラインで指定されるように、そのファイルの内容が引数リストに拡張されます。

バージョン 9 以降を実行している場合、これは「正しい」解決策です。このメカニズムは単に引数が JVM に提供される方法を変更するだけです。 したがって、あらゆるフレームワークやアプリケーションと 100% 互換性があります。, 、クラスローディングの方法に関係なく、つまりこれは、通常のようにコマンド ラインで単に引数を指定することと完全に同等です。これは、この OS の制限に対するマニフェストベースの回避策には当てはまりません。

この例は次のとおりです。

元のコマンド:

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

次のように書き換えることができます。

java @c:\path\to\cparg

どこ c:\path\to\cparg は以下を含むファイルです:

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

この「引数ファイル」は、パス内のスペースを適切に処理するための行継続文字と引用符もサポートしています。

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

グラドル

Gradle でこの問題が発生した場合は、このプラグインを参照してください。このプラグインは、クラスパスを「引数ファイル」に自動的に変換し、Windows で実行またはテスト タスクを実行するときにそれを JVM に提供します。Linux またはその他のオペレーティング システムでは、デフォルトでは何も行われませんが、オプションの構成値を使用して、OS に関係なく変換を適用できます。

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

(免責事項:私が作者です)

この関連する Gradle の問題も参照してください。この機能が最終的に Gradle コアに統合されることを願っています。 https://github.com/gradle/gradle/issues/1989.

(実際にはDOSを意味するのではなく、cmd.exeを参照します)

環境のサイズ/環境変数のサイズ制限よりもCLASSPATHの制限の方が少ないと思います。 XPでは、個々の環境変数のサイズは8kであり、環境全体は64kに制限されています。あなたがその制限に達するとは思いません。

Windowsにはコマンドラインの長さを制限する制限があり、WindowsNT +ではcmd.exeで8kです。 setコマンドにはその制限が適用されます。 setコマンドで8k以上のディレクトリを使用できますか?あなたは運が悪いかもしれません-それを Nick Berardi が提案しました。

私があなたの靴を履いているなら、私はジャンクションユーティリティをMSからダウンロードします: http://technet.microsoft.com/en-us/sysinternals/bb896768.aspx にマップします &quot; C:\ path&quot;言うには、&quot; z:\&quot;および&quot; c:\ path2&quot; &quot; y:\&quot;と言います。これにより、 classpath のアイテムごとに4文字削減されます。

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;

今、クラスパスは次のようになります:

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

実際の classpath に応じて、さらに多くのことが行われる可能性があります。

ここでは、パドルなしで小川を登っていると思います。 コマンドラインには、プログラムを呼び出す引数の制限があります。

2つのサジェストを試してみました。 まず、junitテストを実行する前に、スクリプト/ ant_taskにクラスパス上のさまざまなクラスのJARを作成させることができます。 その後、クラスパスにJARを配置できます。これは短くする必要があります。

別の方法として、JUNITを実行するためのAntscriptを作成し、 ANTでは、クラスパスエントリにそのような制限はありません。

HuibertGillが言及しているように、このすべてを自分で管理する必要がないように、これをAntビルドスクリプトでラップします。

これを試すことができます


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

コマンドプロンプトに移動して、2回実行します(理由はわかりません。...Windows XPマシンで実行する必要があります)。 また、現在のコマンドプロンプトセッションに対してのみ設定されたパスr

jarファイルを&quot; C:\ jars&quot;などのフォルダーに移動することにより、何らかの方法でクラスパスを短くする以外に問題の解決策はありませんでした。

Raman に感謝します。Java9+のパス問題に対する新しいソリューションを導入してくれました。 bootRun タスクへのハックを作成しました。これにより、既にgradleによって評価されたすべてのものを使用して、引数ファイルでjavaを実行できます。エレガントではありませんが機能しています。

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

それらを積み重ねてみましたか?

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%
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top