トッカンソフトウェア

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 に以下を格納します。
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

			


ページのトップへ戻る