Apache Ant Jar作成
今回は、AntでJarファイルを作ってみます。前々回の続きからやるので、そちらを先に見てください。
ただのJar
単純なJarファイルを作ります。C:\work\hello\src\hello\world.java
package hello;
public class world {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
C:\work\hello\build.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project basedir="." default="build" name="hello">
<property name="workdir" value="bin"/>
<target name="init">
<mkdir dir="${workdir}" />
<copy todir="${workdir}">
<fileset dir="src">
<exclude name="**/*.java" />
</fileset>
</copy>
</target>
<target name="clean">
<delete dir="${workdir}" />
</target>
<target depends="init" name="build">
<javac fork="true" debug="true" destdir="${workdir}" includeantruntime="false">
<src path="src" />
</javac>
</target>
<target depends="build" name="jar">
<jar basedir="${workdir}" jarfile="world.jar" />
</target>
</project>
jarタグでJar作成の設定を行います。
basedirで作業フォルダを指定し、jarfileで作成されるJarファイル名を指定します。
Jar作成実行コマンド
set ANT_HOME=C:\apache-ant-1.9.7
set JAVA_HOME=C:\Program Files\Java\jdk1.8.0_60
set PATH=%ANT_HOME%\bin;%JAVA_HOME%\bin;%PATH%
cd C:\work\hello
ant jar
実行結果
C:\work\hello>ant jar
Buildfile: C:\work\hello\build.xml
init:
[mkdir] Created dir: C:\work\hello\bin
[copy] Copied 1 empty directory to 1 empty directory under C:\work\hello\bin
build:
[javac] Compiling 1 source file to C:\work\hello\bin
jar:
[jar] Building jar: C:\work\hello\world.jar
BUILD SUCCESSFUL
Total time: 3 seconds
Jarを実行
java -cp world.jar hello.world
mainメソッドがあるクラスを引数で指定します。
-cp はクラスパス指定。
実行できるJar
mainメソッドのあるクラスを指定しなくても実行できるJarを作成します。world.javaは変更なし。
C:\work\hello\build.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project basedir="." default="build" name="hello">
<property name="workdir" value="bin"/>
<target name="init">
<mkdir dir="${workdir}" />
<copy todir="${workdir}">
<fileset dir="src">
<exclude name="**/*.java" />
</fileset>
</copy>
</target>
<target name="clean">
<delete dir="${workdir}" />
</target>
<target depends="init" name="build">
<javac fork="true" debug="true" destdir="${workdir}" includeantruntime="false">
<src path="src" />
</javac>
</target>
<target depends="build" name="jar">
<jar basedir="${workdir}" jarfile="world.jar">
<manifest>
<attribute name="Main-Class" value="hello.world"/>
</manifest>
</jar>
</target>
</project>
Jarを実行
java -jar world.jar
他のJarを参照するJar
他のJarファイルを参照するプログラムでコンパイル時に他のJarを参照しています。実行時はコマンドラインのオプションで他のJarを参照します。
今回はlog4j2を使ってみます。log4j2は こちらを参照して環境を用意して下さい。
C:\work\hello\lib に以下を格納します。
- log4j-api-2.9.1.jar
- log4j-core-2.9.1.jar
C:\work\hello\src\hello\world.java
package hello;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class world {
static Logger logger = LogManager.getLogger(world.class);
public static void main(String[] args) {
System.out.println("Hello World");
logger.debug("logger");
}
}
C:\work\hello\build.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project basedir="." default="build" name="hello">
<property name="workdir" value="bin"/>
<path id="classpath">
<pathelement location="lib/log4j-api-2.9.1.jar"/>
<pathelement location="lib/log4j-core-2.9.1.jar"/>
</path>
<target name="init">
<mkdir dir="${workdir}" />
<copy todir="${workdir}">
<fileset dir="src">
<exclude name="**/*.java" />
</fileset>
</copy>
</target>
<target name="clean">
<delete dir="b${workdir}in" />
</target>
<target depends="init" name="build">
<javac fork="true" debug="true" destdir="${workdir}" includeantruntime="false">
<src path="src" />
<classpath>
<path refid="classpath"/>
</classpath>
</javac>
</target>
<target depends="build" name="jar">
<jar basedir="${workdir}" jarfile="world.jar">
<manifest>
<attribute name="Main-Class" value="hello.world"/>
</manifest>
</jar>
</target>
</project>
Jarを実行
java -cp "world.jar;lib/log4j-api-2.9.1.jar;lib/log4j-core-2.9.1.jar" hello.world
他のJarを参照する場合のJarのパスを内部に持つJar
他のJarのパスをMANIFEST.MFに持たせます。実行時は他のJarを指定する必要がなくなります。
C:\work\hello\build.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project basedir="." default="build" name="hello">
<property name="workdir" value="bin"/>
<path id="classpath">
<pathelement location="lib/log4j-api-2.9.1.jar"/>
<pathelement location="lib/log4j-core-2.9.1.jar"/>
</path>
<target name="init">
<mkdir dir="${workdir}" />
<copy todir="${workdir}">
<fileset dir="src">
<exclude name="**/*.java" />
</fileset>
</copy>
</target>
<target name="clean">
<delete dir="${workdir}" />
</target>
<target depends="init" name="build">
<javac fork="true" debug="true" destdir="${workdir}" includeantruntime="false">
<src path="src" />
<classpath>
<path refid="classpath"/>
</classpath>
</javac>
</target>
<target depends="build" name="jar">
<jar basedir="${workdir}" jarfile="world.jar">
<manifest>
<attribute name="Main-Class" value="hello.world"/>
<attribute name="Class-Path" value=". lib/log4j-api-2.9.1.jar lib/log4j-core-2.9.1.jar" />
</manifest>
</jar>
</target>
</project>
Jarを実行
java -jar world.jar
上の例では個別にJarファイルを指定しましたが、ワイルドカードで指定して、クラスパス用に変換することができます。
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project basedir="." default="build" name="hello">
<property name="jarname" value="world.jar"/>
<property name="workdir" value="bin"/>
<path id="jarlist">
<fileset dir="lib">
<include name="*.jar"/>
</fileset>
</path>
<manifestclasspath property="manifestclasspath" jarfile="${jarname}">
<classpath refid="jarlist" />
</manifestclasspath>
<target name="init">
<mkdir dir="${workdir}" />
<copy todir="${workdir}">
<fileset dir="src">
<exclude name="**/*.java" />
</fileset>
</copy>
</target>
<target name="clean">
<delete dir="${workdir}" />
</target>
<target depends="init" name="build">
<javac fork="true" debug="true" destdir="${workdir}" includeantruntime="false">
<src path="src" />
<classpath>
<path refid="jarlist"/>
</classpath>
</javac>
</target>
<target depends="build" name="jar">
<jar basedir="${workdir}" jarfile="${jarname}">
<manifest>
<attribute name="Main-Class" value="hello.world"/>
<attribute name="Class-Path" value=". ${manifestclasspath}"/>
</manifest>
</jar>
</target>
</project>
fileset タグでフルパスのファイル一覧を取得し、manifestclasspath タグで相対パスに変換しています。
manifestclasspathタグのjarfileはjarタグのjarfileと同じものにします。
パスを比較して相対パスに変換してくれます。
MANIFEST.MFは以下のようになります。
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.9.7
Created-By: 1.8.0_60-b27 (Oracle Corporation)
Main-Class: hello.world
Class-Path: . lib/log4j-api-2.9.1.jar lib/log4j-core-2.9.1.jar
他のJarを取り込む(Fat Jar)Jar
他のJarを作成するJarに取り込み、実行時に他のJarがなくても動作します。
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project basedir="." default="build" name="hello">
<property name="workdir" value="bin"/>
<path id="classpath">
<pathelement location="lib/log4j-api-2.9.1.jar"/>
<pathelement location="lib/log4j-core-2.9.1.jar"/>
</path>
<target name="init">
<mkdir dir="${workdir}" />
<copy todir="${workdir}">
<fileset dir="src">
<exclude name="**/*.java" />
</fileset>
</copy>
</target>
<target name="clean">
<delete dir="${workdir}" />
</target>
<target depends="init" name="build">
<javac fork="true" debug="true" destdir="${workdir}" includeantruntime="false">
<src path="src" />
<classpath>
<path refid="classpath"/>
</classpath>
</javac>
</target>
<target depends="build" name="jar">
<jar basedir="${workdir}" jarfile="world.jar">
<zipgroupfileset dir="lib" includes="*.jar"/>
<manifest>
<attribute name="Main-Class" value="hello.world"/>
</manifest>
</jar>
</target>
</project>
Jarを実行
java -jar world.jar
ページのトップへ戻る