Полезное для программистов:

Фриланс
Новости
Статьи
   
Рубрики:


Apache Ant

Поиск:
В течение долгого времени мне хватало для сборки приложения волшебной кнопочки «Build» с зеленой стрелочкой. Однако, по мере роста задач, она перестала удовлетворять моим нуждам, и я обратил свое внимание на утилиту ant. И вот что из этого получилось...


Цели

Имеем следующую ситуацию. Приложение крутится на сервере Sun под управлением OC Solaris. Для внесения изменений в какой-либо из классов необходимо произвести следующие действия:
  • Скорректировать исходный код класса (на своем компьютере).
  • Откомпилировать его (на своем компьютере).
  • Создать JAR-архив с новой версией класса (на своем компьютере).
  • Откомпилировать JSP-страницу.
  • Остановить работу приложения (которое крутится на сервере под связкой Apache + Resin).
  • Заменить лежащий там JAR-файл на свою версию (используя FTP), скопировать обновленную страницу.
  • Стартовать приложение.
Кроме того, по возможности хотелось выполнить SQL-запрос к базе Oracle, чтобы вычистить оттуда тестовые данные, оставшиеся там в результате работы приложения.

Разумеется, выполнять все эти действия вручную – занятие утомительное. Очень хочется выполнять всю последовательность одним кликом или одной командой. Тогда я вспомнил про Ant. Покопавшись в информации по нему, я с удивлением узнал, что он может выполнить и эти операции, и множество других заданий.


Hello, world

Начнем с начала. Ant представляет из себя утилиту, предназначенную для построения готовой build-версии приложения. Работа утилиты определяется XML-документом, состоящим из отдельных заданий (tasks). Обычно этот файл называется build.xml. Пример простейшего файла build.xml:

Код

<project>
<target name="clean">
<delete dir="build"/>
</target>
</project>


project – это корневой тег. Он обязательно должен присутствовать в файле build.xml. Он содержит энное количество тегов <target>, каждый из которых определяет одно задание. Каждое задание должно иметь уникальное (в пределах файла) имя. И, наконец, delete – конкретное действие, выполняющееся при запуске задания. В данном случае это удаление каталога build, находящегося в текущем каталоге.

Запуск

Запустить ant с этим файлом можно командой
ant -buildfile build.xml clean
Соответственно, в данном случае опция –buildfile указывает, что после нее будет идти имя xml-файла. clean – имя запускаемого задания.

Кроме того, существует опция –lib. Она нужна, чтобы подключать к антовскому classpath’у дополнительные библиотеки и классы.


Второй шаг

Расширим наш файл дополнительными параметрами:

Код

<project name="My Project Buildfile" default="clean" basedir=".">
<property name="build.dir" value="build"/>
<target name="clean" description="Removes all generated files">
<delete dir="${build.dir}"/>
</target>
</project>


Тег project. name – имя проекта. default – имя того задания, которое будет запускаться по умолчанию, если не будет указан конкретный таск. basedir – директория, которая будет считаться корневой при сборке, все пути будут указываться относительно нее. Все три параметра являются необязательными, их можно безболезненно опустить.

Тег property. Этот тег позволяет нам объявить поле с каким-либо значением, и использовать его затем по всему скрипту. Соответственно, если впоследствии нам нужно будет поменять это значение, это нужно будет делать в одном месте, а не во всем коде. name – название переменной, value – ее значение. Теперь мы можем использовать такую конструкцию: ${build.dir}, вместо нее будет подставлено значение «build».

К тегу target мы добавили атрибут description. Никакой смысловой нагрузки он не несет, просто дополнительное описание.


Поехали дальше. Сделаем несколько типовых тасков, а потом соберем их в итоговый документ. Некоторые задания требуют использования дополнительных библиотек. Но сначала определим свойства, которые мы будем использовать по ходу дальнейшей работы:

Код

<property name="src.dir" value="src"/>
<property name="build.dir" value="build"/>
<property name="build.classes" value="${build.dir}/classes"/>
<property name="lib" value="D:/projects/libs"/>


src.dir – каталог исходных java-файлов
build.dir – каталог для результатов компиляции и упаковки
build.classes – class-файлы
lib – каталог для сторонних библиотек. Здесь я использовал абсолютный путь, т.к. у меня один каталог на несколько проектов.


Создание новой директории

Код

<target name="prepare">
<mkdir dir="${build.dir}"/>
<mkdir dir="${build.classes}"/>
</target>


Новая директория создается тегом mkdir. Как мы видим из этого примера, задание может содержать несколько директив.


Компиляция

Код

<target name="compile" depends="prepare" description="Compiles all source code">
<javac srcdir="${src.dir}" destdir="${build.classes}">
<classpath>
<pathelement location="."/>
<pathelement location="${lib}/ojdbc14.jar"/>
<pathelement location="${lib}/j2ee.jar"/>
<pathelement location="${lib}/utils.jar"/>
<pathelement location="${lib}/context.jar"/>
<pathelement location="${lib}/signon.jar"/>
</classpath>
</javac>
</target>


Вот тут в теге target впервые появляется очень важный атрибут – depends. Запись depends="prepare" означает, что при запуске этого задания будет предварительно выполнено задание prepare. Если необходимо выполнить несколько тасков, они перечисляются через запятую, и выполняются в том порядке, в котором они указаны.

Тег javac, как нетрудно догадаться, выполняет компиляцию java-файлов. Атрибутами srcdir и destdir мы указываем каталоги исходных и скомпилированных файлов. Для указания classpath существует одноименный тег, каждый элемент пути указывается отдельным тегом pathelement с атрибутом location.


Упаковка в JAR-архив

Код

<target name="jar" depends="compile" description="Generates the result JAR-archive">
<jar jarfile="${build.dir}/tvspace.jar"
basedir="${build.classes}">
<metainf file="tvspace.tld"/>
</jar>
</target>


Здесь мы сначала указываем, что упаковке должна предшествовать компиляция. Затем осуществляем архивацию с помощью тега jar. jarfile – имя архива, basedir – каталог, который мы будем паковать, metainf – тег для указания дополнительных файлов, которые мы желаем включить в папку META-INF.


Компиляция JSP

Код

<target name="compileJSP">
<jspc srcdir="."
destdir="${build.dir}"
package="_tvspace"
compiler="jasper41">
<include name="**/*.jsp"/>
</jspc>
</target>


(необходимы библиотеки jasper.jar и jasper-runtime.jar)

Компиляция JSP-страниц выполняется с помощью задания jspc. Указывается исходная директория (srcdir), конечная директория (destdir), пакет (package), компилятор jasper (package). Директива include name="**/*.jsp" указывает, что должны быть откомпилированы все файлы с расширением .jsp, находящиеся в исходной директории.


Работа с FTP

Код

<target name="ftp" description="Uploads file to FTP">
<ftp action="put"
server="appserver.lab.ru"
userid="my_user"
password="my_user"
remotedir="/export/home/my_user/lib">
<fileset dir="${build.dir}">
<include name="tvspace.jar"/>
</fileset>
</ftp>
</target>


(необходима библиотека commons-net-1.4.0.jar)

Как всегда, все очевидно следует из имен и названий :)

Тег ftp. Атрибуты:
action – команда сервера. В данном случае мы делаем закачку на сервер, поэтому put.
server – имя удаленного сервера
userid – имя пользователя
password – пароль
remotedir – директория, в которую будет производиться аплоад.

Тег fileset используется в очень многих директивах ant. Он позволяет определить набор файлов, в т.ч. с использованием маски имени. В данном случае мы просто включаем туда конкретный файл директивой include. То есть, при запуске этого задания будет произведено копирование файла tvspace.jar в директорию /export/home/my_user/lib от имени пользователя my_user (разумеется, в случае правильной авторизации).

Запуск shell-скрипта

Код

<target name="stop" description="Stops server">
<sshexec host="my_host.lab.ru" trust="yes"
username="my_user"
password="my_user"
command="/export/home/my_user/myscript stop"/>
</target>


(необходима библиотека jsch-0.1.21.jar)

Запуск shell-скрипта можно осуществить с помощью тега sshexec. Этот тег отвечает за открытие SSH-соединения с удаленным сервером.
host – имя удаленного сервера.
trust – этот параметр показывает, «доверяет» ли сервер неизвестным хостам. Я с ним так до конца и не разобрался, но без этого не работало :)
username – имя пользователя
password – пароль
command – исполняемая команда.


Работа с БД

Код

<target name="deleteRecordFromDB" description="The SQL-script for clearing the added records">
<sql driver="oracle.jdbc.OracleDriver"
url="jdbc:oracle:thin:@mydbhost:1521:mydbsid"
userid="my_user"
password="my_user">
delete from test_table
</sql>
</target>


(для запуска необходимо подключить библиотеку ojdbc14.jar)

Вновь все очевидно. Формат параметров соответствует обычной JDBCшной нотации. Тег sql имеет атрибуты driver (JDBC-драйвер для базы), url (URL, по которому доступна база), userid (имя пользователя) и password (пароль). Кроме того, можно еще использовать атрибут src и указать sql-файл с выполняемым скриптом (sql=”my_script_file.sql”). Но я делаю это прямо в теле тега, как показано выше.



Итог

Все задания описаны. Теперь мы можем написать, например, такой таск:
Код

<target name="all" depends="stop, compile, jar, ftp, start"
description="Cleans, compiles, builds the JAR file, puts it on the server and restarts it"/>

и получим задание, позволяющее одной-единственной командой выполнить достаточно разноплановую последовательность действий.


Вся справочная информация получена из официального мануала, который можно найти по адресу http://ant.apache.org/manual/index.html. На официальном сайте ant (http://ant.apache.org) можно найти описания форматов всевозможных заданий, как базовых, так и сторонних. Возможности ant поистине огромны, и все это – при такой простоте управления! Кроме того, мы сохраняем преимущество кроссплатформенности и отвязываемся от среды-сборщика. Кстати, ant отлично интегрируется с современными IDE.
Автор: Lamer George
Сайт: http://www.livejournal.com/users/batigoal






Просмотров: 7650

 

 

Новые статьи:


Популярные:
  1. Как сделать цикличным проигрывание MIDI-файла?
  2. Создание AVI файла из рисунков
  3. Как устройство "отключить в данной конфигурации"?
  4. Kто в данный момент присоединен через Сеть?
  5. Как узнать количество доступной памяти?
  6. Как реализовать в RichEdit разноцветный текст?
  7. Как скрыть свое приложение от ProcessViewer
  8. Как программно нажать/скрыть/показ кнопку "Start"?
  9. Модуль работы с ресурсами в PE файлах
10. Функции вызова диалоговых окон выбора
11. Проверка граматики средствами Word'а из Delphi.
12. Модуль для упрощенного вызова сообщений
13. Функции для записи и чтение своих данных в, ЕХЕ- файле
14. Рекурсивный просмотр директорий
15. Network Traffic Monitor
16. Разные модули
17. Универсальная функция для обращения к любым экспортируем функциям DLL
18. Библиотека от VladS
19. Протектор для UPX'а
20. Еще об ICQ, сообщения по контакт листу?
21. Использование открытых интерфейсов
22. Теория и практика использования RTTI
23. Работа с TApplication
24. Примеры использования Drag and Drop для различных визуальных компонентов
25. Что такое порт? Правила для работы с портами
26. Симфония на клавиатуре
27. Загрузка DLL
28. Исправление автоинкремента
29. Взаимодействие с чужими окнами
30. Проверить дубляжи в столбце


 

 

 
 
На главную