ディレクトリ内のすべてのjarファイルをクラスパスに含める方法はありますか?
私は試しjava -classpath lib/*.jar:. my.package.Program
ていますが、確かにそれらのjarファイルにあるクラスファイルを見つけることができません. 各 jar ファイルを個別にクラスパスに追加する必要がありますか?
ディレクトリ内のすべてのjarファイルをクラスパスに含める方法はありますか?
私は試しjava -classpath lib/*.jar:. my.package.Program
ていますが、確かにそれらのjarファイルにあるクラスファイルを見つけることができません. 各 jar ファイルを個別にクラスパスに追加する必要がありますか?
Java 6 以降を使用すると、classpath オプションでワイルドカードがサポートされます。次の点に注意してください。
"
)を使用する*
しない*.jar
ウィンドウズ
java -cp "Test.jar;lib/*" my.package.MainClass
Unix
java -cp "Test.jar:lib/*" my.package.MainClass
これは Windows に似ていますが、:
代わりに;
. ワイルドカードを使用できない場合bash
は、次の構文を使用できます (lib
はすべての Java アーカイブ ファイルを含むディレクトリ)。
java -cp "$(printf %s: lib/*.jar)"
-jar
(クラスパスの使用はオプションと互換性がないことに注意してください。参照:コマンド プロンプトから複数のクラスパス ライブラリを含む jar ファイルを実行する)
ワイルドカードについて
クラスパスドキュメントから:
クラス パス エントリには、ベース名のワイルドカード文字 を含めることができます
*
。これは、ディレクトリ内のすべてのファイルのリストを拡張子.jar
または.JAR
. たとえば、クラス パス エントリfoo/*
は、foo という名前のディレクトリ内のすべての JAR ファイルを指定します。だけで構成されるクラスパス エントリ*
は、現在のディレクトリ内のすべての jar ファイルのリストに展開されます。を含むクラス パス エントリは、
*
クラス ファイルと一致しません。1 つのディレクトリ foo 内のクラスと JAR ファイルの両方を一致させるには、 または のいずれfoo;foo/*
かを使用しますfoo/*;foo
。選択した順序によって、 のクラスとリソースfoo
が の JAR ファイルの前にロードされるかfoo
、またはその逆かが決まります。サブディレクトリは再帰的に検索されません。たとえば、 では
foo/*
JAR ファイルのみを検索し、などでは検索しfoo
ません。foo/bar
foo/baz
ディレクトリ内の JAR ファイルが展開されたクラス パスに列挙される順序は指定されておらず、プラットフォームごとに異なる場合があり、同じマシン上でも刻々と異なる場合があります。適切に構築されたアプリケーションは、特定の順序に依存するべきではありません。特定の順序が必要な場合は、JAR ファイルをクラス パスで明示的に列挙できます。
ワイルドカードの展開は、プログラムのメイン メソッドの呼び出しの前に、クラスのロード プロセス自体の後半ではなく、早い段階で行われます。ワイルドカードを含む入力クラスパスの各要素は、指定されたディレクトリ内の JAR ファイルを列挙することによって生成された一連の (空の可能性がある) 要素に置き換えられます。たとえば、ディレクトリ
foo
にa.jar
、b.jar
、およびが含まれている場合c.jar
、クラス パスfoo/*
は に展開されfoo/a.jar;foo/b.jar;foo/c.jar
、その文字列がシステム プロパティの値になりますjava.class.path
。
CLASSPATH
環境変数は、(または) コマンド ライン オプションと同じように扱われ-classpath
ます-cp
。つまり、ワイルドカードはこれらすべての場合に受け入れられます。ただし、クラスパスのワイルドカードはClass-Path jar-manifest
ヘッダーでは受け入れられません。
注: Java 8 の既知のバグにより、Windows の例では、エントリの前にバックスラッシュを使用し、末尾にアスタリスクを付ける必要があります: https://bugs.openjdk.java.net/browse/JDK-8131329
Windows では次のように動作します:
java -cp "Test.jar;lib/*" my.package.MainClass
これは機能しません:
java -cp "Test.jar;lib/*.jar" my.package.MainClass
に注意してください*.jar
。したがって、* ワイルドカードは単独で使用する必要があります。
Linux では、次のように動作します。
java -cp "Test.jar:lib/*" my.package.MainClass
セパレータはセミコロンではなくコロンです。
この問題は、クラスパスを指定するマニフェスト( ) ファイルを含むメインのjar ファイルをデプロイすることで回避できます。この場合、コードの実行時にのみ宣言する必要があります。myapp.jar
Manifest.mf
java -jar myapp.jar
したがって、メインjar
をあるディレクトリにデプロイし、依存する jar をlib
その下のフォルダーに配置すると、マニフェストは次のようになります。
Manifest-Version: 1.0
Implementation-Title: myapp
Implementation-Version: 1.0.1
Class-Path: lib/dep1.jar lib/dep2.jar
注意: これはプラットフォームに依存しません。同じ jar を使用して、UNIX サーバーまたは Windows PC で起動できます。
「lib」ディレクトリにすべてのjarを持つJava-sun 1.6.0_24を使用したUbuntu 10.04での私のソリューション:
java -cp .:lib/* my.main.Class
これが失敗した場合は、次のコマンドが機能するはずです (lib ディレクトリ内のすべての *.jar をクラスパス パラメータに出力します)。
java -cp $(for i in lib/*.jar ; do echo -n $i: ; done). my.main.Class
簡潔な答え:java -classpath lib/*:. my.package.Program
Oracle では、クラスパスでのワイルドカードの使用に関するドキュメントを、Java 6 についてはこちら、Java 7 についてはこちらで、クラス パス ワイルドカードについてのセクションの見出しの下に提供しています。(これを書いている時点では、2 つのページには同じ情報が含まれています。)ハイライトの概要は次のとおりです。
通常、特定のディレクトリにすべての JAR を含めるには、ワイルドカード*
( not *.jar
) を使用できます。
ワイルドカードは JAR のみに一致し、クラス ファイルには一致しません。ディレクトリ内のすべてのクラスを取得するには、ディレクトリ名でクラスパス エントリを終了するだけです。
上記の 2 つのオプションを組み合わせて、ディレクトリ内のすべての JAR ファイルとクラス ファイルを含めることができ、通常のクラスパス優先規則が適用されます。例えば-cp /classes;/jars/*
ワイルドカードは、サブディレクトリ内の JAR を検索しません。
上記の箇条書きは、CLASSPATH
システム プロパティまたは-cp
または-classpath
コマンド ライン フラグを使用する場合に当てはまります。ただし、Class-Path
JAR マニフェスト ヘッダーを使用する場合 (ant ビルド ファイルの場合と同様)、ワイルドカードは使用できません。
はい、私の最初のリンクは、トップスコアの回答で提供されたものと同じです(追い越すことはできません)が、その回答はリンクを超えて多くの説明を提供しません. 最近のスタック オーバーフローでは、そのような動作は推奨されていないため、拡張することにしました。
窓:
java -cp file.jar;dir/* my.app.ClassName
Linux :
java -cp file.jar:dir/* my.app.ClassName
注意:
- Windowsのパス セパレータは;
- Linuxのパス セパレータは:
- Windows では、cp 引数に空白が含まれていない場合、「引用符」はオプションです。
私にとって、これは windows で機能します。
java -cp "/lib/*;" sample
Linux の場合
java -cp "/lib/*:" sample
javahttp ://docs.oracle.com/javase/6/docs/technotes/guides/extensions/spec.htmlを試すことができます-Djava.ext.dirs=jarDirectory
javaを実行するときの外部jarのディレクトリ
正解:
java -classpath "lib/*:." my.package.Program
正しくない:
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
Java 6 を使用している場合は、クラスパスでワイルドカードを使用できます。
クラスパス定義でワイルドカードを使用できるようになりました。
javac -cp libs/* -verbose -encoding UTF-8 src/mypackage/*.java -d build/classes
すべての .jar ファイルを動的に指定する必要がある場合は、シェル スクリプトまたはApache Antを使用できます。Commons Launcherと呼ばれるコモンズ プロジェクトがあり、基本的に起動スクリプトを ant ビルド ファイルとして指定できます (意味がわかれば)。
次に、次のように指定できます。
<path id="base.class.path">
<pathelement path="${resources.dir}"/>
<fileset dir="${extensions.dir}" includes="*.jar" />
<fileset dir="${lib.dir}" includes="*.jar"/>
</path>
起動ビルド ファイルで、正しいクラスパスでアプリケーションを起動します。
ご担当者様、
MSYS/MinGW シェルの下の Windows で、この奇妙な動作を見つけました。
作品:
$ javac -cp '.;c:\Programs\COMSOL44\plugins\*' Reclaim.java
動作しません:
$ 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
ワイルドカードがシェルによって展開されていないことは確かです。
$ echo './*'
./*
(組み込みの ではなく、別のプログラムでも試してみましたがecho
、同じ結果が得られました。)
それを展開しようとしているのはそれだと思いますjavac
。引数にセミコロンがあるかどうかにかかわらず、動作が異なります。まず、パスのように見えるすべての引数を展開しようとしている可能性があります。そして-cp
、次のトークンのみを取得して、それらを解析します。(そのディレクトリの 2 番目の JAR であることに注意してくださいcom.comsol.aco_1.0.0.jar
。) それはすべて推測です。
これは
$ javac -version
javac 1.7.0
上記のすべてのソリューションは、EclipseやNetbeansなどのIDEの外部でJavaアプリケーションを開発して実行する場合にうまく機能します。
Windows 7を使用していて、Javaでの開発にEclipse IDEを使用している場合、コマンドプロンプトを使用してEclipse内に構築されたクラスファイルを実行すると、問題が発生する可能性があります。
たとえば、Eclipseのソースコードには次のパッケージ階層があります:edu.sjsu.myapp.Main.java
Main.javaの外部依存関係としてjson.jarがあります
Eclipse内からMain.javaを実行しようとすると、問題なく実行されます。
しかし、EclipseでMain.javaをコンパイルした後にコマンドプロンプトを使用してこれを実行しようとすると、「ClassNotDefErrorblahblah」という奇妙なエラーが発生します。
私はあなたがあなたのソースコードの作業ディレクトリにいると仮定します!!
コマンドプロンプトから実行するには、次の構文を使用します。
javac -cp"。;json.jar" Main.java
java -cp"。;json.jar" edu.sjsu.myapp.Main
[お見逃しなく。その上]
これは、Main.javaをパッケージedu.sjsu.myapp内に配置し、java.exeが正確なパターンを検索するためです。
それが役に立てば幸い !!
Windows の場合、引用符が必要です。区切りとして使用する必要があります。例えば:
java -cp "target\\*;target\\dependency\\*" my.package.Main
macOS Mojave上の Java 13 の場合…</p>
すべての.jar
ファイルが同じフォルダーにある場合は、 を使用cd
して、それを現在の作業ディレクトリにします。で確認しpwd
ます。
の場合、最初にアプリのJAR ファイル-classpath
を一覧表示する必要があります。コロン文字を区切り文字として使用し、アスタリスクを追加して、同じフォルダー内の他のすべての JAR ファイルを取得します。最後に、メソッドでクラスの完全なパッケージ名を渡します。:
*
main
たとえば、という名前のパッケージで名前が付けられたクラスmy_app.jar
のメソッドで名前が付けられた JAR ファイル内のアプリの場合、同じフォルダー内のいくつかの必要な jar と共に:main
App
com.example
java -classpath my_app.jar:* com.example.App
短い形式: メインが jar 内にある場合、それを機能させるために明示的に宣言された追加の「-jar pathTo/yourJar/YourJarsName.jar」がおそらく必要になるでしょう (「YourJarsName.jar」がクラスパスにあったとしても) (または、5年前に尋ねられた元の質問に答えるために表現されました:各jarを明示的に再宣言する必要はありませんが、java6でも独自のjarを再宣言する必要があるようです...)
長い形式: (Java への侵入者でさえもこれを利用できることを願って、これを明確にしました)
ここにいる多くの人と同じように、私は Eclipse を使用して jar をエクスポートしています: (File->Export-->'Runnable JAR File')。「ライブラリ処理」Eclipse (Juno) オファーには 3 つのオプションがあります。
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"
通常、私はopt2を使用します(そしてopt1は間違いなく壊れていました)が、使用しているjarの1つのネイティブコードが、そのオプションを選択したときにEclipseが活用する便利な「jarinjar」トリックで壊れていることを発見しました。opt3 が必要であることに気づき、この StackOverflow エントリを見つけた後でも、Eclipse の外部でメインを起動する方法を理解するのにまだ時間がかかりました。
jar に「fooBarTheJarFile.jar」という名前を付け、すべてがディレクトリ「/theFully/qualifiedPath/toYourChosenDir」にエクスポートするように設定されている場合。
(つまり、「エクスポート先」フィールドは「/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar」となります)
終了すると、Eclipse がすべてのライブラリをそのエクスポート ディレクトリ内の「fooBarTheJarFile_lib」という名前のフォルダーに配置し、次のようになります。
/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
次に、システムのどこからでも次のように起動できます。
java -classpath "/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/*" -jar /theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar package.path_to.the_class_with.your_main.TheClassWithYourMain
(Java初心者向け: 「package.path_to.the_class_with.your_main」は、「main(String[] args){.. .}' を Java の外部から実行したい場合)
注意すべき落とし穴: 宣言されたクラスパスの jar のリスト内に「fooBarTheJarFile.jar」があるだけでは十分ではないということです。「-jar」を明示的に宣言し、その jar の場所を再宣言する必要があります。
たとえば、これは壊れます:
java -classpath "/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar;/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/*" somepackages.inside.yourJar.leadingToTheMain.TheClassWithYourMain
相対パスで言い換えます:
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
(Java バージョン "1.6.0_27" を使用; ubuntu 12.04 の OpenJDK 64 ビット サーバー VM 経由)
私が知っている唯一の方法は、個別に行うことです。たとえば、次のようになります。
setenv CLASSPATH /User/username/newfolder/jarfile.jar:jarfile2.jar:jarfile3.jar:.
それが役立つことを願っています!
それらをすべて個別に追加する必要があります。または、本当にディレクトリを指定する必要がある場合は、すべてを 1 つのディレクトリに unjar し、それをクラスパスに追加できます。ただし、クラスパスのバージョン管理と管理不能で奇妙な問題が発生するリスクがあるため、このアプローチはお勧めしません。
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
jar ファイルはディレクトリ構造のルートと考えてください。はい、それらをすべて個別に追加する必要があります。
/* を -cp に設定できるという直接的な解決策ではありませんが、次のスクリプトを使用して、動的なクラスパスと 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;
Linux 用にスクリプト化されており、Windows 用にも同様のものがある可能性があります。「libDir2Scan4jars」への入力として適切なディレクトリが提供されている場合。スクリプトはすべての jar をスキャンしてクラスパス文字列を作成し、それを環境変数「tmpCLASSPATH」にエクスポートします。