Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Java tools & IDE's > Ant |
Автор: batigoal 12.9.2005, 16:16 | ||||||||||||||||||||||
В течение долгого времени мне хватало для сборки приложения волшебной кнопочки «Build» с зеленой стрелочкой. Однако, по мере роста задач, она перестала удовлетворять моим нуждам, и я обратил свое внимание на утилиту ant. И вот что из этого получилось... Цели Имеем следующую ситуацию. Приложение крутится на сервере Sun под управлением OC Solaris. Для внесения изменений в какой-либо из классов необходимо произвести следующие действия:
Разумеется, выполнять все эти действия вручную – занятие утомительное. Очень хочется выполнять всю последовательность одним кликом или одной командой. Тогда я вспомнил про Ant. Покопавшись в информации по нему, я с удивлением узнал, что он может выполнить и эти операции, и множество других заданий. Hello, world Начнем с начала. Ant представляет из себя утилиту, предназначенную для построения готовой build-версии приложения. Работа утилиты определяется XML-документом, состоящим из отдельных заданий (tasks). Обычно этот файл называется build.xml. Пример простейшего файла build.xml:
project – это корневой тег. Он обязательно должен присутствовать в файле build.xml. Он содержит энное количество тегов <target>, каждый из которых определяет одно задание. Каждое задание должно иметь уникальное (в пределах файла) имя. И, наконец, delete – конкретное действие, выполняющееся при запуске задания. В данном случае это удаление каталога build, находящегося в текущем каталоге. Запуск Запустить ant с этим файлом можно командой ant -buildfile build.xml clean Соответственно, в данном случае опция –buildfile указывает, что после нее будет идти имя xml-файла. clean – имя запускаемого задания. Кроме того, существует опция –lib. Она нужна, чтобы подключать к антовскому classpath’у дополнительные библиотеки и классы. Второй шаг Расширим наш файл дополнительными параметрами:
Тег project. name – имя проекта. default – имя того задания, которое будет запускаться по умолчанию, если не будет указан конкретный таск. basedir – директория, которая будет считаться корневой при сборке, все пути будут указываться относительно нее. Все три параметра являются необязательными, их можно безболезненно опустить. Тег property. Этот тег позволяет нам объявить поле с каким-либо значением, и использовать его затем по всему скрипту. Соответственно, если впоследствии нам нужно будет поменять это значение, это нужно будет делать в одном месте, а не во всем коде. name – название переменной, value – ее значение. Теперь мы можем использовать такую конструкцию: ${build.dir}, вместо нее будет подставлено значение «build». К тегу target мы добавили атрибут description. Никакой смысловой нагрузки он не несет, просто дополнительное описание. Поехали дальше. Сделаем несколько типовых тасков, а потом соберем их в итоговый документ. Некоторые задания требуют использования дополнительных библиотек. Но сначала определим свойства, которые мы будем использовать по ходу дальнейшей работы:
src.dir – каталог исходных java-файлов build.dir – каталог для результатов компиляции и упаковки build.classes – class-файлы lib – каталог для сторонних библиотек. Здесь я использовал абсолютный путь, т.к. у меня один каталог на несколько проектов. Создание новой директории
Новая директория создается тегом mkdir. Как мы видим из этого примера, задание может содержать несколько директив. Компиляция
Вот тут в теге target впервые появляется очень важный атрибут – depends. Запись depends="prepare" означает, что при запуске этого задания будет предварительно выполнено задание prepare. Если необходимо выполнить несколько тасков, они перечисляются через запятую, и выполняются в том порядке, в котором они указаны. Тег javac, как нетрудно догадаться, выполняет компиляцию java-файлов. Атрибутами srcdir и destdir мы указываем каталоги исходных и скомпилированных файлов. Для указания classpath существует одноименный тег, каждый элемент пути указывается отдельным тегом pathelement с атрибутом location. Упаковка в JAR-архив
Здесь мы сначала указываем, что упаковке должна предшествовать компиляция. Затем осуществляем архивацию с помощью тега jar. jarfile – имя архива, basedir – каталог, который мы будем паковать, metainf – тег для указания дополнительных файлов, которые мы желаем включить в папку META-INF. Компиляция JSP
(необходимы библиотеки jasper.jar и jasper-runtime.jar) Компиляция JSP-страниц выполняется с помощью задания jspc. Указывается исходная директория (srcdir), конечная директория (destdir), пакет (package), компилятор jasper (package). Директива include name="**/*.jsp" указывает, что должны быть откомпилированы все файлы с расширением .jsp, находящиеся в исходной директории. Работа с FTP
(необходима библиотека 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-скрипта
(необходима библиотека jsch-0.1.21.jar) Запуск shell-скрипта можно осуществить с помощью тега sshexec. Этот тег отвечает за открытие SSH-соединения с удаленным сервером. host – имя удаленного сервера. trust – этот параметр показывает, «доверяет» ли сервер неизвестным хостам. Я с ним так до конца и не разобрался, но без этого не работало ![]() username – имя пользователя password – пароль command – директория, в которую будет производиться аплоад. Работа с БД
(для запуска необходимо подключить библиотеку ojdbc14.jar) Вновь все очевидно. Формат параметров соответствует обычной JDBCшной нотации. Тег sql имеет атрибуты driver (JDBC-драйвер для базы), url (URL, по которому доступна база), userid (имя пользователя) и password (пароль). Кроме того, можно еще использовать атрибут src и указать sql-файл с выполняемым скриптом (sql=”my_script_file.sql”). Но я делаю это прямо в теле тега, как показано выше. Итог Все задания описаны. Теперь мы можем написать, например, такой таск:
и получим задание, позволяющее одной-единственной командой выполнить достаточно разноплановую последовательность действий. Вся справочная информация получена из официального мануала, который можно найти по адресу http://ant.apache.org/manual/index.html. На официальном сайте ant (http://ant.apache.org) можно найти описания форматов всевозможных заданий, как базовых, так и сторонних. Возможности ant поистине огромны, и все это – при такой простоте управления! Кроме того, мы сохраняем преимущество кроссплатформенности и отвязываемся от среды-сборщика. Кстати, ant отлично интегрируется с современными IDE. P.S. Большая просьба ко всем, кто работал с ant из командной строки. Я пробовал все это из-под IDE (Idea & Eclipse), с командной строкой у меня не срослось. PATH, CLASSPATH и ANT_HOME прописан, но получаю такую же ошибку командной строки, как если бы виртуальная машина была запущена с неправильными параметрами. Может, кто-нибудь может что-то посоветовать? |
Автор: allex 12.9.2005, 16:50 |
Командную строку и сообщение об ошибке в студию! |
Автор: batigoal 12.9.2005, 18:38 |
Строка проста, как валенок. Пользовал несколько вариантов: ant ant -buildfile build.xml ant stop ant -buildfile build.xml stop А ошибка такая же, какую выдает команда java без параметров: |
Автор: аЛексус 20.3.2006, 09:28 |
Кто нить подскажите где можно достать мануал по ANT на русском?! ПЛИЗ! |
Автор: batigoal 20.3.2006, 10:00 |
http://www.javable.com/javaworld/10_00/03/ |
Автор: аЛексус 20.3.2006, 11:24 |
Thanx! |
Автор: аЛексус 21.3.2006, 06:47 |
Кстати, разобрался с той ошибкой? У меня есть еще один вопрос! В общем ситуация такая: у меня есть база данных со всеми хранимками и процедурами, но некоторорые хранимки и процедуры надо регулярно обновлять из CVS. Сейчас это все приходится делать в ручную, но как известно лень! Есть предложение сделать это с помощью ANT. У кого-нибудь есть соображения как? |
Автор: tux 21.3.2006, 09:14 | ||
Да проще простого. Получится что-то такое:
Заменяешь свойства db.* и название скрипта sql на то, что тебе нужно и все должно работать. Естественно, если у тебя несколько скриптов, выполняешь тэг <sql> для каждого. |
Автор: tux 21.3.2006, 09:50 |
Можно конечно ![]() |
Автор: аЛексус 21.3.2006, 09:50 |
Спасибо, попробую! Мне кажется удобней делать через fileset потому что скриптов много! Да и еще, не подскажите где взять драйвер для MS SQL Server 2000?! я просто недавно этим занимаюсь, поэтому не знаю где что! ![]() |
Автор: tux 21.3.2006, 10:02 |
Здесь драйвер от самой Microsoft - http://msdn.microsoft.com/data/jdbc/default.aspx. Здесь драйвер стороннего производства, open-source - http://jtds.sourceforge.net/. Судя по рассказам второй работает лучше, сам не пользовался. |
Автор: vaz 5.4.2006, 13:13 |
To Lamer George по поводу ошибки "А ошибка такая же, какую выдает команда java без параметров". Посмотри не установлен ли у тебя ант в каталог, содержащий пробелы. Например, D:\Program files\Ant. Ант не работает с путями, содержащими пробелы. И еще очень насущный вопрос: С помощью <javac> таска можно компилить исходные файлы проекта. А как получить имена только компилируемых исходников? Насколько я понял ант компилит не все исходники подряд, а только измененные исходники. Или как дополнительно обработать исходник с помощью другой программы непосредственно в ходе компиляции с помощью таска <javac>. То есть нужно обрабатывать другой программой только измененные исходники, которые определил ант. |
Автор: batigoal 5.4.2006, 14:30 | ||||
А он заработал уже давно. Я так и не понял, в чем было дело.
А ты уверен, что он компилит только измененные? Ведь Ant даже отследить этого не может - никакой иcтории изменений не ведется. |
Автор: jer1 5.4.2006, 19:12 | ||
ant/docs/manual/CoreTasks/javac.html Javac Description Compiles a Java source tree. The source and destination directory will be recursively scanned for Java source files to compile. Only Java files that have no corresponding .class file or where the class file is older than the .java file will be compiled. // выделено мною jer1 |
Автор: chief39 5.4.2006, 21:08 | ||||
на всяк случ. мож кому легче будет ![]() вместо -buildfile можно -f :
если есть в текущей папке файл build.xml - то ант сам его хватанёт. ant stop Если такого нету - тогда следует файл явно указать. то есть
В общем та же идеология замечательной утилитки make (которую, я, дурак, раньше недолюбливал) По поводу частичной сборки: так же как и make - компилит несуществующие или "освежает" старые. Зачастую clean можно не делать. Когда пересобирал проект - очень пригодилось - поменял мааахонький кусочек - оно его перекомпилило - и всё ![]() ![]() |
Автор: аЛексус 6.4.2006, 06:30 | ||
Другие программы можно запускать с помощью таска <apply>. Я например запускаю компилятор делфи.
|
Автор: jer1 6.4.2006, 08:59 |
hi, вот хочу аЛексус первый плюсик поставить, как это можно сделать? |
Автор: tux 6.4.2006, 09:04 |
Не вопрос. |
Автор: аЛексус 6.4.2006, 10:40 | ||
Кстати есть одно дополнение для тех кто собирает проекты делфи на Анте. Если ваш файл сборки будет не в той же директории где и *.dpr, то он не будет нормально компилировать в том случае если есть dcc32.cfg. Я эту проблему решил путем разделения файла сборки на два: один основной, а другой только для компиляции. Основной файл выглядит примерно так:
А второй, который копируется в раб. директории я указал выше. если у кого-нить есть какие-нибудь замечания или советы, жду! да и обратите внимание на <parallel> и <sequential>, очень полезные штуки, значительно уменьшает время сборки! |
Автор: tux 12.4.2006, 02:10 |
В дополнение ссылка на статью по Ant - http://www.opennet.ru/base/dev/ant_10.txt.html. |
Автор: vaz 18.4.2006, 11:15 | ||||
Все таки не могу решить проблему. Мне необходимо с помощью другой программы обработать исходник и поменять содержимое doclet тега. Проблема состоит в том, что данную операцию нужно сделать только для изменившихся исходников, которые определит ant и делать мне это нужно непосредственно перед компиляцией каждого из изменившихся исходников. В принципе в <javac> task можно включить опцию debug="on" и вывести в файл результаты компиляции, где и будут перечислены компилирующиеся файлы. Но во-первых, его парсить нужно и во-вторых, получаешь набор исходников, которые уже откомпилированы. А мне необходимо непосредственно перед компиляцией обработать изменившийся исходник.
Есть одна маленькая загвоздка, на которую никто из осваивающих ant не обращает внимание, а потом теряет время. !!! Если структура каталогов в точности не соответствует структуре пакетов, то ant будет компилить все подряд вне зависимсоти от того каких ты опций в task'e не понаставишь. Другими словами, дерево каталогов, в которые будут ложиться классы будет сформировано согласно структуре пакетов, а исходники могут лежать в дереве каталогов, которое не соответствует в точности дереву каталогов классов. Ведь сравнение изменившегося исходника ведется по классу, который должен лежать в подобной структуре каталогов. Поэтому нужно обязательно проверить соответствие дерева каталогов классов и дерево каталогов исходников на соответствие. Тогда ant будет компилировать только изменившиеся исходники. И еще хорошо бы воспользоваться task'ом <depend>.
не хочется лезть в документацию, но интересно знать за счет чего это происходит. |
Автор: sandello 18.4.2006, 14:40 | ||||||
Можешь описать задачу, которая привела к такой необходимости?
Меняешь файлы и компилируешь повторно. Идея плохая, но работать должно. Хотелось бы дополнить начинателя: Тег property: однажды сознанная property уже никогда не меняет своего значения. Это, в принципе, есть в статье на opennet Тег condition: позволяет реализовать ветвление. Пример:
В случае успешной провеки условия в теле элемента condition будет установлена переменная name (значение "ok_value"). Если условие не верно, переменная установлена не будет. Поэтому, если нужно построить конструкцию if ... else ..., то для этого достаточно после condition добавить тег proprety, в котором установить значение для неверного условия. |
Автор: vaz 19.4.2006, 10:46 | ||||
Задача следующая: есть increaseVersion.jar который увеличивает версию в java исходнике, в теге @version. Увеличивает по заданному правилу для определеленного формата x.xx или x.x. Если в какой-то исходник вносится изменение, то его версию нужно увеличить при следующей компиляции. Естественно ant найдет все изменившиеся исходники и скомпилирует только их. Но мне нужно перед тем как он их найдет увеличить версию. Если увеличивать версию после компиляции, то эти файлы снова окажутся измененными и ant их будет компилировать вечно. Можно ли каким-то образом вклинить запуск этого jar'ника в таск <javac> и непосредственно перед компиляцией увеличивать версию только тех исходников, в которые вносились изменения? Система контроля версий в данном случае не подходит по нескольким причинам: - версия класса должна меняться в исходнике после каждого изменения/компиляции а не после коммита - библиотека небольшая и разрабатывается и собирается одним человеком, т.е. отсутствуют там всякие мерджи версионные ветки - откаты тоже не нужны - ну и система контроля версий и место дополнительное ест и время потихоньку тоже. |
Автор: sandello 19.4.2006, 11:57 | ||||
Ты немного не понял. Я предлагал сделать что-то вроде:
А вот на счет системы контроля версии - ты не прав. Именно она очень удобна для этой задачи. На примере Subversion могу предложить несколько вариантов: 1. С использованием Keywords - тогда в каждый файл можно затолкать номер ревизии 2. С использованием svn status можно получить список изменных файлов без компиляции Я реализовал 3 вариант :-) Основная особенность - выбор, что будем увеличивать (version.subversion.patch.bugfix), решаю я. Для этого у ant'овского скрипта торчат наружу одноименные цели. Каждая такая цель увеличивает цифирку в определенной строке специального файла. Дальше - дело техники :-) |
Автор: vaz 19.4.2006, 15:57 |
svn только начинаю осваивать и толком данную задачу быстро не решу. Попробую третий вариант :-), может у тебя есть простой пример? |
Автор: sandello 20.4.2006, 06:19 | ||
Лови работающий скрипт
Добавлено @ 06:19 Он еще много чего интересного делает :-) |
Автор: vaz 20.4.2006, 10:37 |
Хороший пример, попробую обстричь его для своих целей. |
Автор: drHip 27.9.2007, 17:09 | ||||||
Все добавил, нашел еще и commoms-logging.jar но
смотрю в jasper, package org.apache.juli.logging существует, а самого LogFactory нет И где его искать? Tomcat 6.0, Ant 1.7.0 Добавлено через 11 минут и 19 секунд http://tomcat.apache.org/tomcat-6.0-doc/api/org/apache/juli/logging/package-summary.html
|
Автор: batigoal 29.9.2007, 18:53 |
drHip, я пробовал тогда под Ant 1.6. В понедельник поэкспериментирую с семеркой, попробуем разобраться. |
Автор: drHip 1.10.2007, 17:19 |
batigoal, ждем-с |
Автор: batigoal 2.10.2007, 11:01 | ||
drHip, у меня сейчас скомпилировать не получилось, но с другой ошибкой (ArrayIndexOutOfBounds). Я добавлял еще jasper-compiler.jar.
Поиск утверждает, что в Томкат 5.5 он есть. Может, у тебя по версиям несинхрон? Откуда ты брал джасперовские библиотеки? Добавлено через 4 минуты и 21 секунду В шестерке тоже должен быть, судя по доке... |
Автор: drHip 2.10.2007, 12:15 |
я использую из Tomcat 5 jasper-compiler-jdt.jar jasper-compiler.jar jasper-runtime.jar потому как в 6-ке не нашел jasper-runtime.jar catalina-ant.jar у меня из 6-ки (поменяв на 5-ку ничего не изменилось) |
Автор: dive 25.10.2007, 14:34 |
может пригодится кому. утилита для сборки Ant скриптов из командной строки http://divehome.blogspot.com/2007/10/ant.html |
Автор: LSD 25.10.2007, 18:42 |
Не понял зачем эта утилита вообще нужна? |
Автор: dive 25.10.2007, 18:47 | ||||
к примеру, у меня build.xml содержит в себе 42 цели сборки (например по моделям телефонов, ибо ресурсы и код разнятся), чтобы запустить сборку конкретной модели мне необходимо писать следующее :
помнить все 42 цели мне не очень то хочется, а если проект не один то и не получится, поэтому я запускаю в каталоге со сриптом эту утилиту, она выводит на экран все таргеты для сборки, я выбираю нужную и жму Enter. |
Автор: LSD 25.10.2007, 19:07 |
Хм, весьма экзотическая ситуация. Я бы ограничился батником или разными билдами. |