GAE(がえ)
% tree hellogaej
hellogaej
|-- build.xml
|-- html
|-- src
| |-- META-INF
| |-- WEB-INF
| `-- hellogaej
| `-- HelloGAEJServlet.java
`-- war
`-- WEB-INF
|-- appengine-web.xml
|-- classes
|-- lib
`-- web.xml
% vi hellogaej/src/hellogaej/HelloGAEJServlet.java
package hellogaej;
import java.io.IOException;
import javax.servlet.http.*;
public class HelloGAEJServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
resp.setContentType("text/plain");
resp.getWriter().println("Hello, GAEj!");
}
}
% vi hellogaej/war/WEB-INF/web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<display-name>Hello Google App Engine for Java</display-name>
<servlet>
<servlet-name>hellogaej</servlet-name>
<servlet-class>hellogaej.HelloGAEJServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hellogaej</servlet-name>
<url-pattern>/hellogaej</url-pattern>
</servlet-mapping>
</web-app>
GAEj固有の設定ファイル。アプリ名やバージョンを書くそうです。
% vi hellogaej/war/WEB-INF/appengine-web.xml
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<application>hellogaej</application>
<version>1</version>
</appengine-web-app>
App Engine SDKに含まれているdev_appserver.shを使って開発サーバーを起動できる。${appengine.sdk}/config/user/ant-macros.xmlに便利なantタスクがあるのでそれを利用するとなお便利。
% vi hellogaej/build.xml
<project name="hellogaej" default="war">
<property name="appengine.sdk" location="/usr/local/appengine-java-sdk-1.2.6"/> <fail message="Please define the appengine.sdk property to point to your SDK directory">
<condition>
<not> <and>
<isset property="appengine.sdk"/>
<available file="${appengine.sdk}/config/user/ant-macros.xml"/>
</and> </not>
</condition>
</fail>
<import file="${appengine.sdk}/config/user/ant-macros.xml"/>
<property name="debug.port" value="5005"/>
<property name="http.port" value="8080"/>
<property name="log.file" value="app.log"/>
<property name="log.days" value="2"/>
<property name="war.dir" location="war"/>
<target name="war" depends="enhance"
description="Assemble the application directory">
<mkdir dir="${war.dir}/WEB-INF"/>
<copy todir="${war.dir}">
<fileset dir="html">
<exclude name="**/.svn/**"/>
<exclude name="**/*~"/>
</fileset>
</copy>
<copy todir="${war.dir}/WEB-INF">
<fileset dir="src/WEB-INF">
<include name="*.xml"/>
</fileset>
</copy>
<enhance_war war="${war.dir}"/>
</target>
<target name="enhance" depends="compile"
description="Enhance the classes after compilation">
<enhance_war war="${war.dir}"/>
</target>
<target name="compile"
description="Compile the application servlet code">
<mkdir dir="${war.dir}/WEB-INF/classes"/>
<mkdir dir="${war.dir}/WEB-INF/lib"/>
<javac srcdir="src" destdir="${war.dir}/WEB-INF/classes">
<classpath>
<fileset dir="${appengine.sdk}/lib/user">
<include name="*.jar"/>
</fileset>
<fileset dir="${appengine.sdk}/lib/shared">
<include name="*.jar"/>
</fileset>
</classpath>
</javac>
</target>
<target name="clean"
description="Force a clean slate to rebuild">
<delete dir="${war.dir}"/>
</target>
<target name="runserver" depends="war"
description="Run the dev_appserver">
<dev_appserver war="${war.dir}" port="${http.port}"/>
</target>
<target name="dev_appserver" depends="runserver"/>
<target name="debug" depends="war"
description="Launches dev_appserver with remote debugging enabled">
<echo message="Launching dev_appserver on Web port ${http.port}, Java remote debug port ${debug.port}"/>
<dev_appserver war="${war.dir}" port="${http.port}">
<options>
<arg value="--jvm_flag=-Xdebug"/>
<arg value="--jvm_flag=-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=${debug.port}"/>
</options>
</dev_appserver>
</target>
<target name="update" depends="war"
description="Uploads the application, including indexes">
<appcfg action="update" war="${war.dir}"/>
</target>
<target name="update_indexes" depends="war"
description="Uploads only the application's indexes">
<appcfg action="update_indexes" war="${war.dir}"/>
</target>
<target name="rollback" depends="war"
description="Rolls back any in-progress application update">
<appcfg action="rollback" war="${war.dir}"/>
</target>
<target name="request_logs"
description="Downloads the application's logs">
<appcfg action="request_logs" war="${war.dir}">
<options>
<arg value="--num_days=${log.days}"/>
</options>
<args>
<arg value="${log.file}"/>
</args>
</appcfg>
</target>
</project>
% ant dev_appserver
面倒臭くて死にそうでしたが、どの言語もJREとServlet上で動くので知っとかないとと思って。