Google Code предлагается на следующих языках: English – Español – 日本語 – 한국어 – Português – Pусский – 中文(简体) – 中文(繁體)
Если вы не используете Eclipse и плагин Google для Eclipse, вам может потребоваться другой способ управления процессом создания и тестирования приложения App Engine. Apache Ant упрощает управление проектом из командной строки или других сред IDE, работающих с Ant. SDK Java содержит набор макросов Ant для выполнения распространенных задач разработки App Engine, включая запуск сервера разработки и добавление приложения на App Engine.
В данной статье описывается файл сборки Ant, полезный для множества проектов. Чтобы пропустить описание и перейти непосредственно к полному файлу для копирования и вставки, перейдите к разделу Полный файл сборки.
Если Ant еще не установлен на вашем компьютере, посетите веб-сайт Apache Ant, чтобы загрузить и установить его.
После установки Ant и добавления команды ant в путь можно выполнить следующую команду для проверки правильности работы и просмотра установленной версии:
ant -version
Как описано в Руководстве по началу работы, проект App Engine должен создавать структуру каталогов, используя стандартный шаблон WAR для веб-приложений Java. (Архивные файлы WAR пока не поддерживаются SDK.)
Для этих инструкций мы поместим все относящиеся к проекту файлы в один каталог под названием Guestbook/ (для проекта гостевой книги, описанного в Руководстве по началу работы) с подкаталогом src/ для исходного кода Java и подкаталогом war/ для готовых файлов приложения. В процессе сборки будет скомпилирован исходный код, а скомпилированный байтовый код Java будет помещен в соответствующее место в подкаталоге war/. Остальные файлы для каталога WAR будут созданы непосредственно в каталоге war/.
Полный каталог проекта должен выглядеть примерно так:
Guestbook/
src/
...Java source code...
META-INF/
...other configuration...
war/
...JSPs, images, data files...
WEB-INF/
...app configuration...
classes/
...compiled classes...
lib/
...JARs for libraries...
Для создания этой структуры каталогов из командой строки используйте следующие команды. При работе в Windows замените прямые косые черты / в этих путях на обратные косые черты \. (В самом файле Ant пути с прямыми косыми чертами / работают для всех операционных систем.)
mkdir Guestbook cd Guestbook mkdir -p src/META-INF mkdir -p war/WEB-INF/classes mkdir -p war/WEB-INF/lib
В каталоге Guestbook/ создайте файл build.xml следующего содержания:
<project>
<property name="sdk.dir" location="../appengine-java-sdk" />
<import file="${sdk.dir}/config/user/ant-macros.xml" />
</project>
Данный файл сборки пока ничего не выполняет: в нем отсутствует тег "target" с инструкциями для выполнения задач. В файле определяется два свойства Ant, которые будут использоваться для определения тегов "target" и в дальнейшем.
Свойство sdk.dir – это путь к SDK Java App Engine; каталог appengine-java-sdk был создан при распаковке Zip-файла SDK. "../appengine-java-sdk" подразумевает, что этот каталог находится в родительском каталоге в каталоге проекта. При необходимости измените это значение. (Пути являются относительными к расположению файла build.xml.)
Элемент <import> загружает набор макросов для разработки App Engine, включенный в SDK Java App Engine. Несколько из них будут использованы позже.
При компиляции классов путь к классу Java должен содержать файлы JAR для API App Engine и все остальные файлы JAR, которые вы добавляли в каталог war/WEB-INF/lib/ проекта (например, файлы JAR DataNucleus JDO/JPA). Приложение может обращаться к классам из файлов JAR, добавленных в этот каталог. Кроме того, файлы JAR в каталоге lib/shared/ SDK будут находиться по пути к классу.
Измените файл build.xml и добавьте в него следующие строки над закрывающим тегом </project> для определения пути к классу, содержащему эти файлы JAR:
<path id="project.classpath">
<pathelement path="war/WEB-INF/classes" />
<fileset dir="war/WEB-INF/lib">
<include name="**/*.jar" />
</fileset>
<fileset dir="${sdk.dir}/lib">
<include name="shared/**/*.jar" />
</fileset>
</path>
Приложение должно включать файл appengine-api-*.jar (где * – это номер версии API и SDK), файл JAR, включенный в SDK, в каталоге war/WEB-INF/lib/. App Engine проверяет классы в этом файле JAR для определения версии API, используемого приложением. Если приложение использует интерфейсы JDO или JPA для хранилища данных App Engine, приложение должно включать реализацию JDO/JPA в war/WEB-INF/lib/. Все эти файлы JAR находятся в каталоге lib/user/ SDK.
Можно скопировать эти файлы JAR в WAR вручную. Однако полезно сделать копирование этих файлов JAR частью процесса сборки. Это обеспечивает использование приложением тех же версий интерфейсов, которые включены в SDK, даже при обновлении SDK в дальнейшем.
Все файлы JAR должны находиться в каталоге war/WEB-INF/lib/, они не могут находиться в подкаталогах. Этот тег Ant "target " рекурсивно скопирует файлы JAR из подкаталога ${sdk.dir}/lib/user/, используя атрибут flatten="true" задачи copy, чтобы все файлы JAR оказались в одном каталоге.
Измените файл build.xml и добавьте в него следующие строки над закрывающим тегом </project>:
<target name="copyjars"
description="Copies the App Engine JARs to the WAR.">
<copy
todir="war/WEB-INF/lib"
flatten="true">
<fileset dir="${sdk.dir}/lib/user">
<include name="**/*.jar" />
</fileset>
</copy>
</target>
При этом будет создан тег "target" сборки под названием "copyjars", копирующий файлы JAR в соответствующее местоположение. Для проверки этого тега "target" убедитесь, что текущим рабочим каталогом является каталог проекта (Guestbook/), затем выполните следующую команду:
ant copyjars
Проверьте содержимое подкаталога war/WEB-INF/lib/, чтобы убедиться в наличии файлов JAR.
Измените файл build.xml и добавьте следующие строки над закрывающим тегом </project>:
<target name="compile" depends="copyjars"
description="Compiles Java source and copies other source files to the WAR.">
<mkdir dir="war/WEB-INF/classes" />
<copy todir="war/WEB-INF/classes">
<fileset dir="src">
<exclude name="**/*.java" />
</fileset>
</copy>
<javac
srcdir="src"
destdir="war/WEB-INF/classes"
classpathref="project.classpath"
debug="on" />
</target>
Это определяет тег "target" сборки "compile", компилирующий все исходные файлы Java, которые размещаются в каталоге src/, и сохраняющий скомпилированные классы в подкаталоге war/WEB-INF/classes/. Все остальные файлы, находящиеся в подкаталоге src/, например в каталоге META-INF/, копируются в каталог war/WEB-INF/classes/. Тег "target" зависит от "copyjars", поэтому при необходимости создаются оба тега "target".
Для компиляции исходных файлов проекта выполните следующую команду:
ant compile
В данном разделе описывается использование Ant для создания проекта с поддержкой интерфейса JDO (объекты данных Java) для хранилища данных. Если в проекте не используется интерфейс JDO, можно перейти к следующему разделу.
Как описано в Руководстве по началу работы и документации хранилища данных, интерфейс JDO позволяет сохранять экземпляры классов в хранилище данных и в дальнейшем получать их как объекты. Способ сохранения и получения экземпляров описывается с помощью аннотаций Java в определении класса.
Чтобы интерфейс JDO видел аннотации, необходимо обработать байтовый код для классов данных после их компиляции с помощью инструмента, включенного в платформу DataNucleus Access Platform, реализацию JDO, распространяемую с App Engine. DataNucleus описывает этот процесс как "расширение" классов.
SDK App Engine содержит макросы Ant для расширения классов данных JDO. Макрос <enhance_war> расширяет все классы данных JDO в проекте, используя верный путь класса для проекта. Для более точного контроля можно использовать макрос <enhance>.
Измените файл build.xml и добавьте следующие строки над закрывающим тегом </project>:
<target name="datanucleusenhance" depends="compile"
description="Performs JDO enhancement on compiled data classes.">
<enhance_war war="war" />
</target>
Этот тег "target" зависит от "compile", поэтому его создание обеспечивает компиляцию и актуальность классов до выполнения расширения.
Веб-сервер разработки можно запустить с помощью макроса Ant. Путем установки зависимости данного тега "target" от тега "target" "datanucleusenhance" (или тега "target" "compile", если DataNucleus не используется) можно создать проект и запустить сервер с помощью одной простой команды.
Измените файл build.xml и добавьте следующие строки над закрывающим тегом </project>:
<target name="runserver" depends="datanucleusenhance"
description="Starts the development server.">
<dev_appserver war="war" />
</target>
Можно предоставить серверу разработки аргументы с помощью атрибутов и элемента <options>. Например, следующий тег "target" запускает сервер, используя порт 8888, и включает удаленную отладку Java через порт 9999:
<target name="runserver" depends="datanucleusenhance"
description="Starts the development server.">
<dev_appserver war="war" port="8888" >
<options>
<arg value="--jvm_flag=-Xdebug"/>
<arg value="--jvm_flag=-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=9999"/>
</options>
</dev_appserver>
</target>
Для создания проекта и запуска сервера используйте следующую команду:
ant runserver
Для остановки сервера нажмите Control-C.
Можно определить задачи Ant для добавления приложения в App Engine и выполнения других действий, предоставленных командной AppCfg.
Макрос <appcfg> принимает название действия в качестве атрибута action и путь к WAR проекта в качестве атрибута war. Элемент может иметь дополнительные элементы <options> и <args>.
Измените файл build.xml и добавьте в него следующие строки:
<target name="update" depends="datanucleusenhance"
description="Uploads the application to App Engine.">
<appcfg action="update" war="war" />
</target>
<target name="update_indexes" depends="datanucleusenhance"
description="Uploads just the datastore index configuration to App Engine.">
<appcfg action="update_indexes" war="war" />
</target>
<target name="rollback" depends="datanucleusenhance"
description="Rolls back an interrupted application update.">
<appcfg action="rollback" war="war" />
</target>
<target name="request_logs"
description="Downloads log data from App Engine for the application.">
<appcfg action="request_logs" war="war">
<options>
<arg value="--num_days=5"/>
</options>
<args>
<arg value="logs.txt"/>
</args>
</appcfg>
</target>
Ниже приведен полный файл build.xml, описанный в этих инструкциях:
<project>
<property name="sdk.dir" location="../appengine-java-sdk" />
<import file="${sdk.dir}/config/user/ant-macros.xml" />
<path id="project.classpath">
<pathelement path="war/WEB-INF/classes" />
<fileset dir="war/WEB-INF/lib">
<include name="**/*.jar" />
</fileset>
<fileset dir="${sdk.dir}/lib">
<include name="shared/**/*.jar" />
</fileset>
</path>
<target name="copyjars"
description="Copies the App Engine JARs to the WAR.">
<copy
todir="war/WEB-INF/lib"
flatten="true">
<fileset dir="${sdk.dir}/lib/user">
<include name="**/*.jar" />
</fileset>
</copy>
</target>
<target name="compile" depends="copyjars"
description="Compiles Java source and copies other source files to the WAR.">
<mkdir dir="war/WEB-INF/classes" />
<copy todir="war/WEB-INF/classes">
<fileset dir="src">
<exclude name="**/*.java" />
</fileset>
</copy>
<javac
srcdir="src"
destdir="war/WEB-INF/classes"
classpathref="project.classpath"
debug="on" />
</target>
<target name="datanucleusenhance" depends="compile"
description="Performs JDO enhancement on compiled data classes.">
<enhance_war war="war" />
</target>
<target name="runserver" depends="datanucleusenhance"
description="Starts the development server.">
<dev_appserver war="war" />
</target>
<target name="update" depends="datanucleusenhance"
description="Uploads the application to App Engine.">
<appcfg action="update" war="war" />
</target>
<target name="update_indexes" depends="datanucleusenhance"
description="Uploads just the datastore index configuration to App Engine.">
<appcfg action="update_indexes" war="war" />
</target>
<target name="rollback" depends="datanucleusenhance"
description="Rolls back an interrupted application update.">
<appcfg action="rollback" war="war" />
</target>
<target name="request_logs"
description="Downloads log data from App Engine for the application.">
<appcfg action="request_logs" war="war">
<options>
<arg value="--num_days=5"/>
</options>
<args>
<arg value="logs.txt"/>
</args>
</appcfg>
</target>
</project>