6

私はコマンドラインで実行可能なJavaプログラムに取り組んできました。それはテスト段階にあり、それをパッケージ化することは少し問題であることが証明されました。この問題の核心は、私のアプリケーションが持つ多くの依存関係を中心に展開しています。私のlibフォルダー(jarを含む)は500mbに近いです。

現在、Eclipse RunnableJarExportウィザードを使用しています。Eclipseから実行する必要があることを除いて、問題なく動作します。サイズが約500mbのJarを生成します(このプログラム内に多数のCOBOLプログラムをパッケージ化する必要があると言っておくだけで十分です)。このプロセスには30秒未満かかります。

理想的には、これをある種のAntタスクにし、Jenkinsを介して実行し、リポジトリに公開したいと思います。そうすれば、ユーザーはJarをつかんで実行することができます。

私が調査したオプション:

カスタムクラスローダー(FatJar、OneJarなど)。

  • 作品
  • jarを解凍する必要があるため、実行時に実行に時間がかかります。
  • ファイル構造は基本的にjarでいっぱいのJarであり、メインクラスはカスタムクラスローダーを介して委任されます。
  • 速いビルド時間(5分)

    <target name="hello" depends="compile">
        <property name="classes.dir" value="onejar" />
        <property name="build.dir" value="bin" />
    
        <one-jar destfile="hello.jar">
            <manifest>
                <attribute name="One-Jar-Main-Class" value="mainclass" />
                <attribute name="Class-Path" value="." />
                <attribute name="One-Jar-Show-Expand" value="true" />
            </manifest>
            <main>
                <fileset dir="${build.dir}"/>
            </main>
            <lib>
                <fileset dir="lib">
                    <include name="**/*.jar"/>
                </fileset>
    
            </lib>
    
    
        </one-jar>
    </target>
    

依存関係を手動で収集し、それらをフォルダーに解凍してから、カスタムMANIFESTファイルですべてをjar処理します。

  • 動作させることができません
  • LARGE(1500mb +)
  • ビルド時間が遅い(20分以上)

    <target name="compile" depends="resolve">
        <javac srcdir="src" destdir="bin" debug="true" deprecation="on">
            <classpath>
                <path refid="ivy.path" />
            </classpath>
        </javac>
    </target>
    
    
    
    <target name="jar" depends="compile" description="Create one big jarfile.">
        <jar jarfile="${dist}/deps.jar">
            <zipgroupfileset dir="lib">
                <include name="**/*.jar" />
            </zipgroupfileset>
        </jar>
        <sleep seconds="1" />
        <jar jarfile="${dist}/myjar.jar" basedir="bin">
            <zipfileset src="${dist}/deps.jar" excludes="META-INF/*.SF" />
            <manifest>
                <attribute name="Main-Class" value="mymainclassishere" />
            </manifest>
        </jar>
    </target>
    

そうそう、誰か提案がありますか?人々の考えを聞くことに興味があります。

編集:具体的には.... Eclipse Runnable Jarエクスポートウィザードが30秒未満でJarをエクスポートできるのに、ビルド時間が30分を超えるのはなぜですか。

4

1 に答える 1

4

あなたの質問に答えることは眉をひそめる可能性があることを私は知っています、しかし私は昨日この問題をなんとか解決することができました。私が試したすべてのオプションの中で、最速の解決策はEclipse Runnable JarExportWizardを複製することでした。Runnable Jar Export Wizardを使用して取得できるものが必要jar-in-jar-loader.zipです...または、Google/Eclipseインストールを介して見つけることができます。

このソリューションは、構築が速く(30秒)、実行がはるかに速い(5秒の起動コスト)ことがわかりました。それはまた、瓶の構造を非常にきれいに保ち、瓶が爆発することはありませんでした。

<target name="compile" depends="resolve">
    <mkdir dir="bin"/>
    <!-- Copy all non java resources since jar javac will exclude them by default. Needed for xmls, properties etc --->
    <copy todir="bin">
        <fileset dir="src" excludes="**/*.java" />
    </copy>

    <javac srcdir="src" destdir="bin" debug="true" deprecation="on">
        <classpath>
            <path refid="ivy.path" />
        </classpath>
    </javac>
</target>


<!-- Creates the runnable jar. Copies the dependencies as jar files, into the top level of a new jar. 
     This means nothing without a custom classloader and manifest with a jar listing -->
<target name="jar" depends="compile" description="Create one big jarfile.">

    <path id="dependencies.path">
        <fileset dir="lib">
            <include name="**/*.jar" />
        </fileset>
    </path>

    <pathconvert property="manifest.classpath" pathsep=" ">
        <path refid="dependencies.path" />
        <mapper>
            <chainedmapper>
                <flattenmapper />
                <globmapper from="*.jar" to="*.jar" />
            </chainedmapper>
        </mapper>
    </pathconvert>

    <mkdir dir="${dist}"/>
    <jar destfile="${dist}/jar/Runnable.jar" filesetmanifest="mergewithoutmain">
        <manifest>
            <attribute name="Main-Class" value="org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader" />
            <attribute name="Rsrc-Main-Class" value="mymainclass" />
            <attribute name="Class-Path" value="." />
            <attribute name="Rsrc-Class-Path" value="./ ${manifest.classpath}" />
        </manifest>
        <fileset dir="bin" />
        <zipfileset src="jar-in-jar-loader.zip" />
        <zipfileset dir="lib" includes="**/*.jar*" />
    </jar>
</target>
于 2012-04-21T06:58:51.240 に答える