クラスパス内のディレクトリ内にすべてのjarファイルを含める方法はありますか?
私はJava -classpath lib/*.jar:. my.package.Program
を試していますが、これらのjarファイルに確実に含まれるクラスファイルを見つけることができません。各jarファイルをクラスパスに別々に追加する必要がありますか?
Java 6以降を使用して、classpathオプションはワイルドカードをサポートします。次の点に注意してください。
"
)*
ではなく*.jar
を使用Windows
Java -cp "Test.jar;lib/*" my.package.MainClass
Unix
Java -cp "Test.jar:lib/*" my.package.MainClass
これはWindowsと似ていますが、:
の代わりに;
を使用します。ワイルドカードを使用できない場合、bash
では次の構文を使用できます(lib
はすべてのJavaアーカイブファイルを含むディレクトリです)。
Java -cp $(echo lib/*.jar | tr ' ' ':')
(クラスパスを使用することは-jar
オプションと互換性がないことに注意してください。参照: コマンドプロンプトから複数のクラスパスライブラリを含むjarファイルを実行 )
ワイルドカードについて
Classpath ドキュメントから:
クラスパスエントリには、ベース名のワイルドカード文字
*
を含めることができます。これは、ディレクトリ内のすべてのファイルのリストを拡張子.jar
または.JAR
で指定するのと同等と見なされます。たとえば、クラスパスエントリfoo/*
は、fooという名前のディレクトリ内のすべてのJARファイルを指定します。単に*
からなるクラスパスエントリは、現在のディレクトリ内のすべてのjarファイルのリストに展開されます。
*
を含むクラスパスエントリは、クラスファイルと一致しません。単一のディレクトリfoo内のクラスとJARファイルの両方を一致させるには、foo;foo/*
またはfoo/*;foo
を使用します。選択された順序によって、foo
内のクラスとリソースがfoo
内のJARファイルの前にロードされるか、またはその逆かが決まります。サブディレクトリは再帰的には検索されません。たとえば、
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の既知のバグのため、ウィンドウの例では末尾にアスタリスクを付けてエントリーの前にバックスラッシュを使用する必要があります。 https://bugs.openjdk.Java.net/browse/JDK-8131329
窓の下でこれは働く:
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
区切り文字はセミコロンではなくコロンです。
この問題を回避するには、クラスパスを指定する manifest (myapp.jar
)ファイルを含む main 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
NB:これはプラットフォームに依存しません - 同じjarを使ってUNIXサーバーやWindows PCで起動することもできます。
"lib"ディレクトリにすべてのjarファイルを持つJava-Sun 1.6.0_24を使用したUbuntu 10.04上の私の解決策:
Java -cp。:lib/* my.main.Class
これが失敗した場合は、次のコマンドが機能するはずです(libディレクトリ内のすべての* .jarsをクラスパスパラメータに出力します)。
Java -cp $(lib/*。jar内のiの場合、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をnot検索します。
上記の箇条書きは、CLASSPATH
システムプロパティ、または-cp
または-classpath
コマンドラインフラグを使用する場合に当てはまります。ただし、Class-Path
JARマニフェストヘッダーを使用する場合(antビルドファイルを使用する場合と同様)、ワイルドカードはnotを受け入れます。
はい、私の最初のリンクはトップスコアの回答で提供されたものと同じです(これを追い越す見込みはありません)が、その回答はリンクを超えて多くの説明を提供しません。そのような動作は discouraged Stack Overflow these days なので、私はそれを拡張すると思った。
あなたはJavaを試すことができます-Djava.ext.dirs=jarDirectory
http://docs.Oracle.com/javase/6/docs/technotes/guides/extensions/spec.html
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 -cp file.jar;dir/* my.app.ClassName
Linux :
Java -cp file.jar:dir/* my.app.ClassName
思い出させる:
- Windows パスの区切り文字は;
です
- Linux パスの区切り文字は:
です
- Windowsでは、cp引数に空白が含まれていない場合、 "引用符"はオプションです。
本当にすべての.jarファイルを動的に指定する必要がある場合は、シェルスクリプト、または Apache Ant を使用できます。 Commons Launcher と呼ばれるcommonsプロジェクトがあります。これは基本的にあなたが起動スクリプトをantビルドファイルとして指定することを可能にします(私が言っていることがわかるなら)。
その後、次のように指定できます。
<path id="base.class.path">
<pathelement path="${resources.dir}"/>
<fileset dir="${extensions.dir}" includes="*.jar" />
<fileset dir="${lib.dir}" includes="*.jar"/>
</path>
起動ビルドファイルで、正しいクラスパスを使用してアプリケーションを起動します。
Java 6を使用している場合は、クラスパスにワイルドカードを使用できます。
クラスパス定義でワイルドカードを使用することが可能になりました。
javac -cp libs/* -verbose -encoding UTF-8 src/mypackage/*.Java -d build/classes
Windows上のJava 7では、ワイルドカード拡張は機能しません。
このStackOverflowの問題 /をチェックしてください。
これを回避するには、ワイルドカードの直後にセミコロンを付けます。 Java -cp "somewhere/*;"
ご担当者様、
私は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
は次のトークンのみを取り、それらを解析します。 (com.comsol.aco_1.0.0.jar
がそのディレクトリの2番目のJARであることに注意してください。)それはすべて推測です。
これは
$ javac -version
javac 1.7.0
Windowsの場合は引用符が必要です。区切り文字として使用する必要があります。例えば。:
Java -cp "target\\*;target\\dependency\\*" my.package.Main
短縮形:メインがjar内にある場合は、( 'YourJarsName.jar'がクラスパスにあったとしても)それを機能させるために明示的に宣言された追加の '-jar pathTo/yourJar/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"という名前を付け、allがディレクトリにエクスポートするように設定されている場合: "/ 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){..を含む' TheClassWithYourMain.Java 'ファイルの一番上にある宣言されたpackage-pathです。 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"を使用。Ubuntu12.04のOpenJDK 64ビットサーバーVMを介して)
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をコンパイルした後にコマンドプロンプトを使用してこれを実行しようとすると、 "ClassNotDef Error blah blah"という奇妙なエラーが発生します。
私はあなたがあなたのソースコードの作業ディレクトリにいると思います!
コマンドプロンプトから実行するには、次の構文を使用します。
javac -cp "。; json.jar" Main.Java
Java -cp "。; json.jar" edu.sjsu.myapp.Main
[お見逃しなく。上記]
これは、Main.Javaをパッケージedu.sjsu.myapp内に配置したため、Java.exeが正確なパターンを検索するためです。
それが役に立てば幸い !!
私が知っている唯一の方法はそれを個別に行うことです、例えば:
setenv CLASSPATH /User/username/newfolder/jarfile.jar:jarfile2.jar:jarfile3.jar:.
それが役立つことを願っています!
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
/ *を-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ファイルをスキャンしてクラスパス文字列を作成し、それをenv変数 "tmpCLASSPATH"にエクスポートします。
複数のjarファイルと現在のディレクトリのクラスファイルに適した方法でクラスパスを設定します。
CLASSPATH=${Oracle_HOME}/jdbc/lib/ojdbc6.jar:${Oracle_HOME}/jdbc/lib/ojdbc14.jar:${Oracle_HOME}/jdbc/lib/nls_charset12.jar;
CLASSPATH=$CLASSPATH:/export/home/gs806e/tops/jconn2.jar:.;
export CLASSPATH
あなたはそれらをすべて別々に追加する必要があります。あるいは、 本当に ディレクトリを指定するだけでよい場合は、すべてを1つのディレクトリに展開してクラスパスに追加することができます。ただし、クラスパスのバージョン管理や管理しにくいという点で奇妙な問題が発生する可能性があるため、この方法はお勧めしません。
Jarファイルをディレクトリ構造のルートとして考えます。はい、あなたはそれらをすべて別々に追加する必要があります。
フォルダに複数のjarファイルがあります。下記のコマンドは私のためにJDK1.8
でフォルダーに存在するすべてのjarファイルを含めるように働きました。クラスパスにスペースがある場合は引用符で囲むことに注意してください。
ウィンドウズ
コンパイル:javac -classpath "C:\My Jars\sdk\lib\*" c:\programs\MyProgram.Java
実行中:Java -classpath "C:\My Jars\sdk\lib\*;c:\programs" MyProgram
Linux
コンパイル:javac -classpath "/home/guestuser/My Jars/sdk/lib/*" MyProgram.Java
実行中:Java -classpath "/home/guestuser/My Jars/sdk/lib/*:/home/guestuser/programs" MyProgram
私はJavaファイルをjarとして、またはUbuntuのクラスとして実行しようとしています。私は両方の選択肢に失敗した。次の例外はその出力です。
Download link: https://upload.cat/f694139f88c663b1
Java org.statmetrics.Statmetric
または
Java -cp /home/elias/statmetrics/statmetrics.jar: org.statmetrics.Statmetrics
または
Javaクラスパス "/usr/lib/jvm/Java-1.8.0-openjdk-AMD64/jre/lib/*" -jar /home/elias/statmeics/statmetrics.jar
Exception in thread "Thread-0" Java.lang.NoClassDefFoundError: javax/xml/bind/annotation/adapters/XmlAdapter
at Java.base/Java.lang.ClassLoader.defineClass1(Native Method)
at Java.base/Java.lang.ClassLoader.defineClass(ClassLoader.Java:1016)
at Java.base/Java.security.SecureClassLoader.defineClass(SecureClassLoader.Java:174)
at Java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.Java:802)
at Java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.Java:700)
at Java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.Java:623)
at Java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.Java:581)
at Java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.Java:178)
at Java.base/Java.lang.ClassLoader.loadClass(ClassLoader.Java:521)
at org.statmetrics.c.a(Unknown Source)
at org.statmetrics.dw.a(Unknown Source)
at org.statmetrics.dx.run(Unknown Source)
Caused by: Java.lang.ClassNotFoundException: javax.xml.bind.annotation.adapters.XmlAdapter
at Java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.Java:583)
at Java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.Java:178)
at Java.base/Java.lang.ClassLoader.loadClass(ClassLoader.Java:521)
... 12 more
私は答えを見つけました:
私の愚かさ.
最初のステップ:あなたは対応するJavaをセットしなければなりません:私はJava 11を持っていました、しかし私はJava libパスとして第8バージョンをセットしました! - ここからJavaのバージョンを設定できます。
Sudo update-alternatives --config Java
第2ステップ:次に、パスとファイル名を対応するパスとファイルに変更して、次のコマンドを実行します。
Java -classpath "/usr/lib/jvm/Java-1.8.0-openjdk-AMD64/jre/lib/*" -jar /home/elias/statmetrics/statmetrics.jar org.statmetrics.Statmetrics
正常に実行されました。