今回は、Apache Mavenを使ったWebアプリ作成にトライしてみます。以下のページを参考に、Webアプリ用のプロジェクトを作成。
http://maven.apache.org/guides/mini/guide-webapp.html
$ mvn archetype:generate -DgroupId=myapp.web -DartifactId=myapp-web -DarchetypeArtifactId=maven-archetype-webapp [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building Maven Stub Project (No POM) 1 [INFO] ------------------------------------------------------------------------ [INFO] [INFO] >>> maven-archetype-plugin:2.0:generate (default-cli) @ standalone-pom >>> [INFO] [INFO] <<< maven-archetype-plugin:2.0:generate (default-cli) @ standalone-pom <<< [INFO] [INFO] --- maven-archetype-plugin:2.0:generate (default-cli) @ standalone-pom --- [INFO] Generating project in Interactive mode Downloading: http://repo1.maven.org/maven2/org/apache/maven/archetypes/maven-archetype-webapp/1.0/maven-archetype-webapp-1.0.jar Downloaded: http://repo1.maven.org/maven2/org/apache/maven/archetypes/maven-archetype-webapp/1.0/maven-archetype-webapp-1.0.jar (4 KB at 8.9 KB/sec) Downloading: http://repo1.maven.org/maven2/org/apache/maven/archetypes/maven-archetype-webapp/1.0/maven-archetype-webapp-1.0.pom Downloaded: http://repo1.maven.org/maven2/org/apache/maven/archetypes/maven-archetype-webapp/1.0/maven-archetype-webapp-1.0.pom (533 B at 1.1 KB/sec) [INFO] Using property: groupId = myapp.web [INFO] Using property: artifactId = myapp-web Define value for property 'version': 1.0-SNAPSHOT: : [INFO] Using property: package = myapp.web Confirm properties configuration: groupId: myapp.web artifactId: myapp-web version: 1.0-SNAPSHOT package: myapp.web Y: : Y [INFO] ---------------------------------------------------------------------------- [INFO] Using following parameters for creating project from Old (1.x) Archetype: maven-archetype-webapp:1.0 [INFO] ---------------------------------------------------------------------------- [INFO] Parameter: groupId, Value: myapp.web [INFO] Parameter: packageName, Value: myapp.web [INFO] Parameter: package, Value: myapp.web [INFO] Parameter: artifactId, Value: myapp-web [INFO] Parameter: basedir, Value: /xxxxx [INFO] Parameter: version, Value: 1.0-SNAPSHOT [INFO] ********************* End of debug info from resources from generated POM *********************** [INFO] project created from Old (1.x) Archetype in dir: /xxxxx/myapp-web [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 16.802s [INFO] Finished at: Fri May 20 20:53:48 JST 2011 [INFO] Final Memory: 8M/107M [INFO] ------------------------------------------------------------------------
archetypeプラグインのgenerateゴール実行時に、「archetypeArtifactId=maven-archetype-webapp」を指定します。
できあがったディレクトリ。
$ find ./myapp-web ./ ./myapp-web ./myapp-web/src ./myapp-web/src/main ./myapp-web/src/main/resources ./myapp-web/src/main/webapp ./myapp-web/src/main/webapp/WEB-INF ./myapp-web/src/main/webapp/WEB-INF/web.xml ./myapp-web/src/main/webapp/index.jsp ./myapp-web/pom.xml
…srcディレクトリに、javaディレクトリがありません。どうも、Webアプリプロジェクト作成時には、Javaソースディレクトリは作ってくれないらしいです。なんで?
仕方がないので、ディレクトリを作成します。
$ mkdir src/main/java
んで、手順を見ると「mvn clean package」と書いてあるので、とりあえず実行してみます。
mvn clean package [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building myapp-web Maven Webapp 1.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ Downloading: http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-war-plugin/2.1.1/maven-war-plugin-2.1.1.pom Downloaded: http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-war-plugin/2.1.1/maven-war-plugin-2.1.1.pom (7 KB at 5.8 KB/sec) Downloading: http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-war-plugin/2.1.1/maven-war-plugin-2.1.1.jar Downloaded: http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-war-plugin/2.1.1/maven-war-plugin-2.1.1.jar (76 KB at 53.5 KB/sec) [INFO] [INFO] --- maven-clean-plugin:2.4.1:clean (default-clean) @ myapp-web --- [INFO] [INFO] --- maven-resources-plugin:2.4.3:resources (default-resources) @ myapp-web --- [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] Copying 0 resource …毎度おなじみ、ダウンロード処理 [INFO] Webapp assembled in [34 msecs] [INFO] Building war: /xxxxx/myapp-web/target/myapp-web.war [INFO] WEB-INF/web.xml already added, skipping [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 15.700s [INFO] Finished at: Fri May 20 21:00:21 JST 2011 [INFO] Final Memory: 7M/169M [INFO] ------------------------------------------------------------------------
最終的に、WARファイルができあがります。ちょっとpom.xmlを見てみましょう。
$ cat pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>myapp.web</groupId> <artifactId>myapp-web</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>myapp-web Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies> <build> <finalName>myapp-web</finalName> </build> </project>
packagingが「war」になっています。あと、さっきのパッケージング結果だと、WARファイルの名前が「myapp-web.war」となっていましたが、build/finalNameで指定下名前がWARファイルの名前になるっぽいですね。前回のコマンドラインアプリの時はバージョンまで名前に入っていましたが、Webアプリの場合はバージョンを入れるとバージョンが変わるとURLが変わってしまうからでしょう…。
続いて、サーブレットを書いてみましょう。pom.xmlに依存関係を追加します。
<dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency>
$ mkdir -p src/main/java/myapp/web $ emacs src/main/java/myapp/web/HelloServlet.java &
今回のサーブレット。
package myapp.web; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setCharacterEncoding("UTF-8"); PrintWriter writer = response.getWriter(); writer.write("Hello Web App!"); } }
<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>Archetype Created Web Application</display-name> <servlet> <servlet-name>HelloServlet</servlet-name> <servlet-class>myapp.web.HelloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> </web-app>
archetypeプラグインで用意されたデフォルトのweb.xmlを修正。ちょっとDTDが古かったので、サーブレット2.5まで引き上げました。
パッケージングします。
$ mvn clean package [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building myapp-web Maven Webapp 1.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-clean-plugin:2.4.1:clean (default-clean) @ myapp-web --- [INFO] Deleting /xxxxx/myapp-web/target [INFO] [INFO] --- maven-resources-plugin:2.4.3:resources (default-resources) @ myapp-web --- [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] Copying 0 resource [INFO] [INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ myapp-web --- [WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent! [INFO] Compiling 1 source file to /xxxxx/myapp-web/target/classes [INFO] [INFO] --- maven-resources-plugin:2.4.3:testResources (default-testResources) @ myapp-web --- [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory /xxxxx/myapp-web/src/test/resources [INFO] [INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ myapp-web --- [INFO] No sources to compile [INFO] [INFO] --- maven-surefire-plugin:2.7.2:test (default-test) @ myapp-web --- [INFO] No tests to run. [INFO] Surefire report directory: /xxxxx/myapp-web/target/surefire-reports ------------------------------------------------------- T E S T S ------------------------------------------------------- There are no tests to run. Results : Tests run: 0, Failures: 0, Errors: 0, Skipped: 0 [INFO] [INFO] --- maven-war-plugin:2.1.1:war (default-war) @ myapp-web --- [INFO] Packaging webapp [INFO] Assembling webapp [myapp-web] in [/xxxxx/myapp-web/target/myapp-web] [INFO] Processing war project [INFO] Copying webapp resources [/xxxxx/myapp-web/src/main/webapp] [INFO] Webapp assembled in [42 msecs] [INFO] Building war: /xxxxx/myapp-web/target/myapp-web.war [INFO] WEB-INF/web.xml already added, skipping [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 3.807s [INFO] Finished at: Fri May 20 21:21:30 JST 2011 [INFO] Final Memory: 9M/170M [INFO] ------------------------------------------------------------------------
servlet-api.jarのダウンロードは、今回は割愛。
では、動かしてみましょう。どうもこのところ、MavenとかsbtでWebアプリを動かすのはJettyが主流っぽいので、その流れに乗ることにします。pom.xmlを、以下のように修正。
<build> <finalName>myapp-web</finalName> <plugins> <plugin> <groupId>org.mortbay.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <version>8.0.0.M2</version> <configuration> <webAppConfig> <contextPath>/</contextPath> </webAppConfig> <scanIntervalSeconds>10</scanIntervalSeconds> </configuration> </plugin> </plugins> </build>
そして、「mvn jetty:run」でJettyに起動してもらいます。
$ mvn jetty:run [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building myapp-web Maven Webapp 1.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] >>> jetty-maven-plugin:8.0.0.M2:run (default-cli) @ myapp-web >>> [INFO] [INFO] --- maven-resources-plugin:2.4.3:resources (default-resources) @ myapp-web --- [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] Copying 0 resource [INFO] [INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ myapp-web --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-resources-plugin:2.4.3:testResources (default-testResources) @ myapp-web --- [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory /xxxxx/myapp-web/src/test/resources [INFO] [INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ myapp-web --- [INFO] No sources to compile [INFO] [INFO] <<< jetty-maven-plugin:8.0.0.M2:run (default-cli) @ myapp-web <<< [INFO] [INFO] --- jetty-maven-plugin:8.0.0.M2:run (default-cli) @ myapp-web --- [INFO] Configuring Jetty for project: myapp-web Maven Webapp [INFO] webAppSourceDirectory /xxxxx/myapp-web/src/main/webapp does not exist. Defaulting to /home/ippei/study/java/maven/myapp-web/src/main/webapp [INFO] Reload Mechanic: automatic [INFO] Classes = /xxxxx/myapp-web/target/classes [INFO] Context path = / [INFO] Tmp directory = /xxxxx/myapp-web/target/tmp [INFO] Web defaults = org/eclipse/jetty/webapp/webdefault.xml [INFO] Web overrides = none [INFO] web.xml file = file:/xxxxx/myapp-web/src/main/webapp/WEB-INF/web.xml [INFO] Webapp directory = /xxxxx/myapp-web/src/main/webapp [INFO] Starting jetty 8.0.0.M2 ... 2011-05-20 21:35:31.369:INFO::jetty-8.0.0.M2 2011-05-20 21:35:31.568:INFO::No Transaction manager found - if your webapp requires one, please configure one. 2011-05-20 21:35:31.768:INFO::Started SelectChannelConnector@0.0.0.0:8080 [INFO] Started Jetty Server
ダウンロードはやっぱり割愛。先ほど作成したディレクトリを読み取り、起動しているようです。つか、この表示を見るとパッケージングまでの必要はなさそうですね…。
※WARファイルから起動する場合は、「mvn jetty:run-war」を実行します
最後に稼働確認。
$ telnet localhost 8080 Trying 127.0.0.1... Connected to localhost.localdomain (127.0.0.1). Escape character is '^]'. GET /hello Hello Web App!Connection closed by foreign host.
動いたー。止める時は、Ctrl-Cで。設定すれば、stopゴールで止められるっぽい。
jetty-maven-pluginのその他の設定内容は、こちらを参照。
http://wiki.eclipse.org/Jetty/Feature/Jetty_Maven_Plugin