Здесь я покажу пример использования Apache Ant для сборки Java приложения. Эта статья покажет только знакомство с Ant, более подробную информацию можно найти в документации. Проект будет располагаться в директории ~/ant. Исходники в ~/ant/src. Откомпилированные файлы в ~/ant/build разделенны в несколько директорий в зависимости от назначения: классы в ~/ant/build/classes, jar файлы в ~/ant/build/jar. Создадим необходимые директории сейчас, они нужны только для демонстрации запуска Java приложения из командной строки, ant сам в дальнейшем создаст или удалит все необходимые директории.
roonyk@MacBookPro:~$pwd
/Users/roonyk
roonyk@MacBookPro:~$mkdir ant
roonyk@MacBookPro:~$cd ant
roonyk@MacBookPro:~/ant$
roonyk@MacBookPro:~/ant$mkdir src
roonyk@MacBookPro:~/ant$mkdir src/testant
roonyk@MacBookPro:~/ant$
roonyk@MacBookPro:~/ant$mkdir build
roonyk@MacBookPro:~/ant$mkdir build/classes
roonyk@MacBookPro:~/ant$mkdir build/jar
roonyk@MacBookPro:~/ant$
roonyk@MacBookPro:~/ant$ls -l
total 0
drwxr-xr-x 4 roonyk staff 136 Sep 16 14:26 build
drwxr-xr-x 3 roonyk staff 102 Sep 16 14:25 src
roonyk@MacBookPro:~/ant$
Создадим простое и самое популярное приложение в мире HelloWorld!
Создадим простой java класс, который будет выводить фиксированное сообщение в STDOUT, ~/ant/src/testant/HelloWorld.java добавив в него следующий код:
package testant;
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
Скомпилируем и запустим нашу мега программу.
roonyk@MacBookPro:~/ant$pwd
/Users/roonyk/ant
roonyk@MacBookPro:~/ant$
roonyk@MacBookPro:~/ant$javac -sourcepath src -d build/classes/ src/testant/HelloWorld.java
roonyk@MacBookPro:~/ant$java -classpath build/classes/ testant.HelloWorld
Hello World
roonyk@MacBookPro:~/ant$
Теперь создадим исполняемый jar файл.
roonyk@MacBookPro:~/ant$pwd
/Users/roonyk/ant
roonyk@MacBookPro:~/ant$echo Main-Class: testant.HelloWorld>myManifest
roonyk@MacBookPro:~/ant$jar cfm build/jar/HelloWorld.jar myManifest -C build/classes/ .
roonyk@MacBookPro:~/ant$java -jar build/jar/HelloWorld.jar
Hello World
roonyk@MacBookPro:~/ant$
После выполнения этих java-only шагов мы можем продумать build процесс:
1. Мы должны скомпилировать исходники.
2. Мы должны упаковать скомпилированные файлы, сейчас у нас только один файл, но обычно серьезное приложение состоит из нескольких файлов(возможно сотни).
3. Мы должны создать запускающийся архив.
4. Хорошая практика прибирать за собой мусор.
По умолчанию в качестве имени build файла ant использует build.xml. Создадим build.xml файл и поместим его в ~/ant директорию. Build.xml файл будет иметь вид:
<project>
<target name="clean">
<delete dir="build"/>
</target>
<target name="compile">
<mkdir dir="build/classes"/>
<javac srcdir="src" destdir="build/classes"/>
</target>
<target name="jar">
<mkdir dir="build/jar"/>
<jar destfile="build/jar/HelloWorld.jar" basedir="build/classes">
<manifest>
<attribute name="Main-Class" value="oata.HelloWorld"/>
</manifest>
</jar>
</target>
<target name="run">
<java jar="build/jar/HelloWorld.jar" fork="true"/>
</target>
</project>
roonyk@MacBookPro:~/ant$pwd
/Users/roonyk/ant
roonyk@MacBookPro:~/ant$ls -l
total 16
drwxr-xr-x 4 roonyk staff 136 Sep 16 14:26 build
-rw-r--r-- 1 roonyk staff 604 Sep 16 18:16 build.xml
-rw-r--r-- 1 roonyk staff 31 Sep 16 14:50 myManifest
drwxr-xr-x 3 roonyk staff 102 Sep 16 14:25 src
roonyk@MacBookPro:~/ant$
Сейчас мы можем компилировать, собирать архив и выполнять приложение через запуск таких команд:
ant compile
ant jar
ant run
ant clean
или
ant clean compile jar run
в результате получив такой вывод:
roonyk@MacBookPro:~/ant$ant clean compile jar run
Buildfile: /Users/roonyk/ant/build.xml
clean:
[delete] Deleting directory /Users/roonyk/ant/build
compile:
[mkdir] Created dir: /Users/roonyk/ant/build/classes
[javac] /Users/roonyk/ant/build.xml:9: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds
[javac] Compiling 1 source file to /Users/roonyk/ant/build/classes
jar:
[mkdir] Created dir: /Users/roonyk/ant/build/jar
[jar] Building jar: /Users/roonyk/ant/build/jar/HelloWorld.jar
run:
[java] Hello World
BUILD SUCCESSFUL
Total time: 0 seconds
roonyk@MacBookPro:~/ant$
Красоту портит строка:
[javac] /Users/roonyk/ant/build.xml:9: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds
Решение - необходимо установить атрибут includeantruntime="false"
.
<project>
<target name="clean">
<delete dir="build"/>
</target>
<target name="compile">
<mkdir dir="build/classes"/>
<javac srcdir="src" destdir="build/classes" includeantruntime="false"/>
</target>
<target name="jar">
<mkdir dir="build/jar"/>
<jar destfile="build/jar/HelloWorld.jar" basedir="build/classes">
<manifest>
<attribute name="Main-Class" value="testant.HelloWorld"/>
</manifest>
</jar>
</target>
<target name="run">
<java jar="build/jar/HelloWorld.jar" fork="true"/>
</target>
</project>
Вывод стал более красивый:
roonyk@MacBookPro:~/ant$ant clean compile jar run
Buildfile: /Users/roonyk/ant/build.xml
clean:
[delete] Deleting directory /Users/roonyk/ant/build
compile:
[mkdir] Created dir: /Users/roonyk/ant/build/classes
[javac] Compiling 1 source file to /Users/roonyk/ant/build/classes
jar:
[mkdir] Created dir: /Users/roonyk/ant/build/jar
[jar] Building jar: /Users/roonyk/ant/build/jar/HelloWorld.jar
run:
[java] Hello World
BUILD SUCCESSFUL
Total time: 0 seconds
roonyk@MacBookPro:~/ant$
Взглянув на build файл мы можем отметить схожесть между Ant and java-only командами:
java-only |
Ant |
mkdir build\classes javac -sourcepath src -d build\classes src\testant\HelloWorld.java echo Main-Class: testant.HelloWorld>mf mkdir build\jar jar cfm build\jar\HelloWorld.jar mf -C build\classes .
java -jar build\jar\HelloWorld.jar
|
<mkdir dir="build/classes"/> <javac srcdir="src" destdir="build/classes"/> <!-- automatically detected --> <!-- obsolete; done via manifest tag --> <mkdir dir="build/jar"/> <jar destfile="build/jar/HelloWorld.jar"
basedir="build/classes"> <manifest> <attribute name="Main-Class" value="testant.HelloWorld"/> </manifest> </jar> <java jar="build/jar/HelloWorld.jar" fork="true"/>
|
Теперь у нас есть рабочий build файл, который мы можем немного улучшить, а именно зададим в виде переменных директории и имя main-class, а также порядок шагов сборки зависящих один от другого.
<project name="HelloWorld" basedir="." default="main">
<property name="src.dir" value="src"/>
<property name="build.dir" value="build"/>
<property name="classes.dir" value="${build.dir}/classes"/>
<property name="jar.dir" value="${build.dir}/jar"/>
<property name="main-class" value="testant.HelloWorld"/>
<target name="clean">
<delete dir="${build.dir}"/>
</target>
<target name="compile">
<mkdir dir="${classes.dir}"/>
<javac srcdir="${src.dir}" destdir="${classes.dir}" includeantruntime="false"/>
</target>
<target name="jar" depends="compile">
<mkdir dir="${jar.dir}"/>
<jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}">
<manifest>
<attribute name="Main-Class" value="${main-class}"/>
</manifest>
</jar>
</target>
<target name="run" depends="jar">
<java jar="${jar.dir}/${ant.project.name}.jar" fork="true"/>
</target>
<target name="clean-build" depends="clean,jar"/>
<target name="main" depends="clean,run"/>
</project>
Теперь просто выполнив команду ant получим:
roonyk@MacBookPro:~/ant$ant
Buildfile: /Users/roonyk/ant/build.xml
clean:
[delete] Deleting directory /Users/roonyk/ant/build
compile:
[mkdir] Created dir: /Users/roonyk/ant/build/classes
[javac] Compiling 1 source file to /Users/roonyk/ant/build/classes
jar:
[mkdir] Created dir: /Users/roonyk/ant/build/jar
[jar] Building jar: /Users/roonyk/ant/build/jar/HelloWorld.jar
run:
[java] Hello World
main:
BUILD SUCCESSFUL
Total time: 0 seconds
roonyk@MacBookPro:~/ant$
Вот таким образом осуществляется простейшая сборка простейшего Java приложения с помощью Apache Ant.
Комментарии