62

単一のjarに「再jar」したいいくつかの外部jarに実行時の依存関係があります。これらの外部依存関係はexternal_jarsディレクトリーに保管されており、それらすべてをリストする必要がないようにしたいと思います(つまり、依存関係が変更された場合にビルドスクリプトを変更する必要はありません)。何かご意見は?

Googleは、これを行う方法について良い答えをくれました-依存関係として各jarをリストアップしてもかまわない場合:

http://markmail.org/message/zijbwm46maxzzoo5

大まかに言って、libディレクトリ内のすべてのjarをout.jarに結合する次のようなものが必要です(いくつかの適切な上書きルールを使用)。

jar -combine -out out.jar -in lib/*.jar
4

11 に答える 11

67

ウラジミールの答えは正しいものですが、彼が提案することは、すべてのjarを1つの大きなout.jarに再パックすることを意味していると感じています。これは、単一<zipfileset>またはそのようなものとしてAnt Jarタスクに供給されます。この 2 段階のアプローチは不要です。これが Ant バージョンに関連しているかどうかはわかりませんが、私は Ant 1.7.1 を持っており、その<jar>タスクは を理解<zipgroupfileset>しており、サードパーティの jar のすべてのコンテンツを直接フィードすることができます。

<jar destfile="MyApplication.jar">
  <zipgroupfileset dir="lib" includes="*.jar" /> 
  <!-- other options -->
  <manifest>
    <attribute name="Main-Class" value="Main.MainClass" />
  </manifest>
</jar>
于 2009-10-24T21:14:27.143 に答える
23

jarjar をチェックアウトできます。

http://code.google.com/p/jarjar/

于 2009-02-05T11:03:41.593 に答える
9

最初にJARをマーシャリングディレクトリに抽出してみてください。

<target name="combine-jars">
    <mkdir dir="${marshall.dir}"/>
    <unzip dest="${marshall.dir}">
        <fileset dir="${external.jar.dir}">
            <include name="**/*.jar"/>
        </fileset>
    </unzip>
    <jar destfile="${combined.jar}" basedir="${marshall.dir"}>
    <delete dir="${marshall.dir}"/>
</target>

ここ${marshall.dir}で、は一時ディレクトリで${external.jar.dir}あり、はJARを保持する場所であり、${combined.jar}はターゲットJARです。

于 2009-02-05T12:55:14.677 に答える
3

Mavenを使用している場合、なぜあなたはそうしないのですか? :) maven-shade-pluginを使用するだけで、魅力的に機能します!

  <project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>1.5</version>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
            <configuration>
              <transformers>
                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                  <mainClass>com.YOUR_COMPANY.YOUR_MAIN_CLASS</mainClass>
                </transformer>
              </transformers>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
  ...
</project>
于 2012-01-31T15:15:34.007 に答える
2

これが私の解決策です:

<target name="-post-jar">
    <echo>Packaging ${application.title} into a single JAR</echo>

    <jar destfile="${basedir}${file.separator}${dist.dir}${file.separator}_${ant.project.name}_.jar">
        <zipgroupfileset dir="${basedir}${file.separator}${dist.dir}" includes="${ant.project.name}.jar"/>
        <zipgroupfileset dir="${basedir}${file.separator}${dist.dir}${file.separator}lib" includes="*.jar"/>
        <manifest>
            <attribute name="Main-Class" value="${main.class}"/>
        </manifest>
    </jar>
</target>
于 2011-01-14T13:40:38.933 に答える
1

質問はよく答えられています。One-Jarという便利なツールについて言及したいと思います。One-Jar は、リソースをよりきれいに処理します (すべてのリソースを保持することにより)。これは、コードがMANIFEST ファイルを処理する必要がある場合に便利です。

Web サイトからコピーしたサンプル XML..

<import file="one-jar-ant-task.xml"/>   

    <target name="hello" depends="init">
        <!-- Build lib.jar -->   
        <javac destdir="${classes.dir}/lib">
            <src path="${lib.dir}" />
        </javac>
        <jar destfile="${build.dir}/lib.jar" >
            <fileset dir="${classes.dir}/lib"/>
        </jar>   
        <!-- Build classes for main.jar -->   
        <javac destdir="${classes.dir}/src">
            <src path="${src.dir}" />
            <classpath path="${build.dir}/lib.jar"/>   
        </javac>
        <!-- Construct the One-JAR file -->   
        <one-jar destfile="hello.jar" manifest="hello.mf">
            <main>
                <!-- Construct main.jar from classes and source code -->
                <fileset dir="${classes.dir}/src"/>
            </main>
            <lib>
                <fileset file="${build.dir}/lib.jar" />
            </lib>
        </one-jar>
        <echo>
          Now you can run the Hello One-JAR example using 
          $ java -jar hello.jar
        </echo>   

    </target>
于 2012-03-14T05:11:59.400 に答える
1

ant で構築している場合 (私は eclipse の ant を使用しています)、追加の jar ファイルを追加するように ant に指示するだけで済みます。一人のプロジェクトのため、簡単です。

たとえば、.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のあるディレクトリでした。それだけです... 複数の zipgroupfileset タグを追加することもできます。

于 2012-04-25T18:41:33.940 に答える
0

Maven またはその他のビルド ツールは、クラス ファイルの複数のバージョンの解決を「管理」できません。実際、Maven は、プロジェクトで明示的に必要とされていないすべてのダウンストリーム jar ファイルを推移的に含めることにより、これらの問題を最初に引き起こします。

プロジェクトの推移的なクロージャ (プロジェクトに必要なすべてのライブラリとモジュール、およびプロジェクトに依存するすべてのプロジェクト) のどこかに、クラス ファイルの 2 つのバージョンがあるとします。Mavenは、どれが「正しい」ものであるかをどのように知ることができますか? プログラマーが意図したものはどれですか?

明示的な依存関係が破棄されて推移的な依存関係が優先されたときに、この情報が失われたため (XML の型付けを節約するため)、この情報が失われたためです。

于 2010-04-15T08:56:47.987 に答える
0

まあ、私はプログラミングにはあまり興味がありませんが、もっと簡単なことがうまくいきました...質問が意味するのであれば、jarファイルを1つに結合することです。もちろん、これは手動の汚れたソリューションです。すべての tar を untar しました...そして.. untar によって形成されたすべてのディレクトリを新しい tar ファイルに追加して、新しい tar ファイルを作成しました。出来た。

于 2010-03-18T03:57:26.060 に答える
0

依存関係を自動的に管理するMavenまたはその他のシステムの使用を検討しましたか? そうすれば、各ライブラリの場所、名前、および直接の依存関係が持つ推移的な依存関係を指定する必要がなくなります。依存関係とそのバージョンを 1 か所に記載するだけで、システムがライブラリのダウンロード、クラスパスの構成、およびプロジェクトのビルドを処理します。

于 2009-02-05T18:50:32.883 に答える