web-dev-qa-db-ja.com

JAR内のJARを含むクラスパス

別のJARファイルに含まれるJARファイルを含むJava classpathを指定することはできますか?

127
Paul Reiners

アプリケーションとその必要なライブラリを含む単一のjarを作成しようとしている場合、2つの方法(私が知っている)があります。最初は One-Jar で、特別なクラスローダーを使用してjarのネストを許可します。 2番目は berJar 、または Shade )です。これにより、含まれているライブラリが爆発し、すべてのクラスが最上位のjarに配置されます。

また、UberJarとShadeはそれぞれMaven1とMaven2のプラグインであることにも言及する必要があります。以下で説明するように、Assemblyプラグインを使用することもできます(実際にははるかに強力ですが、適切に構成するのははるかに困難です)。

91
Steve Moyer

これらの「エクスプロードJARコンテンツ」ソリューションを使用する必要はありません。彼らは間違いなくものを見るのを難しくします(すべてが同じレベルで爆発するため)。さらに、名前の競合が発生する可能性があります(適切なパッケージを使用している場合は発生しませんが、これを常に制御できるわけではありません)。

必要な機能は、 上位25個のSun RFERFE 4648386 のいずれかです。Sunは、無限の知恵で、優先度が低いと指定しています。私たちは太陽が目覚めることを願うだけです...

その間、私が遭遇した最良の解決策(SunがJDKにコピーすることを望みます)は、カスタムクラスローダー JarClassLoader を使用することです。

50
Bruce Willis

いくつかの調査の後、Mavenやサードパーティの拡張機能/プログラムを必要としない方法を見つけました。

マニフェストファイルで「クラスパス」を使用できます。

例えば:

マニフェストファイルMANIFEST.MFを作成する

Manifest-Version: 1.0
Created-By: Bundle
Class-Path: ./custom_lib.jar
Main-Class: YourMainClass

すべてのクラスをコンパイルし、jar cfm Testing.jar MANIFEST.MF *.class custom_lib.jarを実行します

cは、アーカイブの作成を表しますfは、ファイルを指定することを示しますvは、詳細な入力用ですmは、カスタムマニフェストファイルを渡すことを意味します

Libがjarパッケージに含まれていることを確認してください。 jarを通常の方法で実行できるはずです。

ベース: http://www.ibm.com/developerworks/library/j-5things6/

クラスパスについて必要な他のすべての情報はありますか here

29
Tezar

zipgroupfilesetタグを使用します(filesetタグと同じ属性を使用します);ディレクトリ内のすべてのファイルを解凍し、新しいアーカイブファイルに追加します。詳細: http://ant.Apache.org/manual/Tasks/Zip.html

これは、jar-in-a-jarの問題を回避するための非常に便利な方法です-何をすべきかを理解しようとしている間に、この正確なStackOverflowの質問をGoogleで検索したためです。 jarまたはjarのフォルダーを、Antを使用してビルドされた1つのjarにパッケージ化する場合、このクラスパスまたはサードパーティのプラグインのことはすべて忘れてください。

<jar destfile="your.jar" basedir="Java/dir">
  ...
  <zipgroupfileset dir="dir/of/jars" />
</jar>
22
ecbrodie

Ant(私はEclipseのantを使用しています)でビルドしている場合、antに言って追加のjarファイルを追加できます...一人のプロジェクトのため、簡単です。

たとえば、.jarファイルをビルドしていたターゲットは次のとおりでした。

<jar destfile="${plugin.jar}" basedir="${plugin.build.dir}">
    <manifest>
        <attribute name="Author" value="ntg"/>
        ................................
        <attribute name="Plugin-Version" value="${version.entry.commit.revision}"/>
    </manifest>
</jar>

1行追加して作成しました。

<jar ....">
    <zipgroupfileset dir="${external-lib-dir}" includes="*.jar"/>
    <manifest>
        ................................
    </manifest>
</jar>

どこ

<property name="external-lib-dir" 
          value="C:\...\eclipseWorkspace\Filter\external\...\lib" />

外部jarのあるディレクトリでした。以上です...

8
ntg

独自のクラスローダーを作成せずに。 jarをjarのクラスパスに追加できますが、メインjarに含まれず、同じ場所に配置する必要があります。

6
Joe Skora

これを行うカスタムクラスローダー、またはこれをサポートするサードパーティライブラリを構築する必要があります。最善の方法は、ランタイムからjarを抽出し、クラスパスに追加することです(または既にクラスパスに追加しておくことです)。

2
James Schek

IDEを使用している場合は、JARをエクスポートし、「必要なライブラリを生成されたJARにパッケージ化する」を選択するだけです。 Eclipseは、必要な依存JARを生成されたJARに自動的に追加し、これらのJARを自動的にロードするEclipseカスタムクラスローダーを生成します。

2
amralieg

maven Assembly plugin と呼ばれるプラグインを持つJavaビルドにmavenを使用します。

それはあなたの求めていることをしますが、他の提案のいくつかが説明しているように-本質的にすべての依存jarを爆発させ、それらを単一のjarに再結合します

2
Vinnie

さて、Eclipseを使用している場合、非常に簡単な方法があります。

プロジェクトを「実行可能な」Jarファイルとしてエクスポートします(Eclipse内からプロジェクトフォルダーを右クリックし、[エクスポート...]を選択します)。エクスポート設定を構成するときは、必ず「必要なライブラリを生成されたJarに抽出する」を選択してください。 「Extract ...」およびnot「Package required libraries ...」を選択してください。

追加:エクスポート設定で実行構成を選択する必要があります。そのため、何らかのクラスで常に空のmain()を作成し、実行構成に使用できます。

とにかく、100%動作することは保証されていません-あなたが含まれているJarファイルのライセンスと、署名ファイルをコピーしないことに関する何か。しかし、私はこれをyearsで行っており、問題に遭遇したことはありません。

1
CM_2014

パッケージシステムがそれらをきちんと分離しておくべきであるので、私は同じレベルですべてのファイルを抽出して、結果からjarを作るように助言しようとしていました。それは手動の方法であり、スティーブが示したツールはそれをうまくやってくれると思います。

1
PhiLho

Winstoneはかなり良い http://blog.jayway.com/2008/11/28/executable-war-with-winstone-maven-plugin/ 。しかし、複雑なサイトではありません。プラグインを含めるだけで済むので残念です。

1
Jan Goyvaerts