#navi_header|Java|
''2013-07更新''
2013-02に Apache Tomcat Maven Plugin の 2.1 がリリースされ、nexus.codehaus.org のリポジトリから 1.2 が削除されました。現在はMavenのCentralリポジトリから 2.1 を直接ロード出来ます。
- Apache Tomcat - Tomcat Maven Plugin
-- http://tomcat.apache.org/maven-plugin.html
- Apache Tomcat Maven Plugin - About Apache Tomcat Maven Plugin
-- http://tomcat.apache.org/maven-plugin-2.1/
pom.xmlへの組み込み例:
#pre||>
...
org.apache.tomcat.maven
tomcat6-maven-plugin
2.1
8090
/tomcat6-demo
org.apache.tomcat.maven
tomcat7-maven-plugin
2.1
8090
/tomcat7-demo
...
||<
Tomcat6とTomcat7用に分離されています。ゴールも"tomcat6:xxxx"と"tomcat7:xxxx"で分かれているため、両方同時に組み込んでもゴール指定で使い分けることができるため、衝突問題も発生しません。
実際のサンプルコードについては [[1150]] を参照してください。
----
MavenプロジェクトでのServletプログラミングで、Eclipse上で「サクサク」、つまりJavaソース修正→Eclipse上で保存→Eclipseによる自動コンパイル→即座にServletContainer上に反映という素早い開発サイクルを実現するためのメモです。
対象:フルスペックのJ2EEサーバ機能を用いない、TomcatやJettyなどの軽量ServletContainer上で動作するWebアプリケーション。
環境:Maven3, Eclipse 3.6 or 3.7 以上, m2e プラグイン, Tomcat 5 以上
#more||
#outline||
----
* Java Servlet プログラミングにおける「サクサク開発」の基本方針
Java Servlet プログラミングで何がプログラマを苛立たせるか。それは "deploy" 作業であると思います。Java Servlet プログラミングで根強い人気を誇る Sysdeo Eclipse Tomcat Launcher Plugin は、Plugin側でTomcatを起動して、Plugin側でEclipseプロジェクトにあわせてContextを自動設定してくれます。これによりプログラマは "deploy" について一切気にする必要が無くなり、Eclipse上でJavaソースを修正→即座にTomcatがContextをリロード→ブラウザ上から動作確認することが出来ます。また、Seasar2 による SAStruts フレームワークではhot deploy機能により、classファイルの更新を検知して自動的に最新のclassファイルをロードしてくれます。これによりプログラマは修正する度に "deploy" する必要は無くなります。
ここまでであれば特に難しい問題はありません。Eclipseプロジェクトの出力ディレクトリを"WEB-INF/classes/"に設定し、Servlet Container側で適切にContextのドキュメントベースを設定し、最後にServlet Container側でclassファイルが更新されれば自動的にContextをリロードする設定して準備完了です。
問題が出てくるのはMavenプロジェクトの場合で、WEB-INFを含めたWebコンテンツは "src/main/webapp/" 以下に、ビルドされたclassファイルは "target/classes/" 以下に、と分断されてしまいます。そのままですとどうしても一度warまでパッケージングした後、ServletContainerにdeployさせる必要が出てきます。
この問題を解決するためには jetty-maven-plugin や tomcat-maven-plugin を導入します。これらを使うことで、"src/main/webapp/" と "target/classes/" の分断をplugin側で適切にハンドリングしてそれぞれのServlet Containerをデバッグ起動することが可能となります。
ここまでで、"deploy" を省略するためのアプローチを以下に整理します。
: Sysdeo Eclipse Tomcat Launcher Plugin :#block||>
- http://www.eclipsetotale.com/tomcatPlugin.html
- Eclipse上からTomcatをデバッグモードで起動し、Java Servletのデバッグを可能にする。
- 老舗プラグインで使いやすさもあります。ただし、Mavenプロジェクト(m2eプラグイン)と組み合わせるには "DevLoader" をTomcat側にセットアップする必要があるようです。
- 参考:DevLoaderとMaven/m2e連携時のトラブルなど
-- http://www.eclipsetotale.com/tomcatPlugin/readmeDevLoader.html
-- http://bagineer.blog59.fc2.com/blog-entry-98.html
-- http://d.hatena.ne.jp/Ewigkeit/20071122/1195658893
||<
: SAStruts (Seasar 2.4 SMART deploy) :#block||>
- http://sastruts.seasar.org/
- StrutsのXML地獄から開発者を解放するSAStruts (1/3) - @IT
-- http://www.atmarkit.co.jp/fjava/rensai4/saweb02/saweb02_1.html
- crossroad's Blog Eclipse + Maven2 + Tomcat + Seasar2 の開発環境ベスト!?プラクティス
-- http://bagineer.blog59.fc2.com/blog-entry-98.html
||<
: jetty-maven-plugin :#block||>
Jettyは軽量のJava Servlet Containerです。jetty-maven-pluginをMavenプロジェクトに組み込むことで、"mvn jetty:run" でMavenのディレクトリ構成に従ってServletContainerが起動します。これにより、Mavenでビルド or m2eプラグイン導入済みのEclipse側で自動コンパイルされたclassがJetty側でも間を置かずに自動リロードしてくれるようになります。
- Jetty 7 or 8以降
-- http://wiki.eclipse.org/Jetty/Feature/Jetty_Maven_Plugin
- Jetty 6以前 ("maven-jetty-plugin"という名前だった)
-- http://docs.codehaus.org/display/JETTY/Maven+Jetty+Plugin
||<
: tomcat-maven-plugin :#block||>
Mavenのplugin内部でTomcatをLaunch可能にします。当初は codehaus で開発されていましたが、バージョン 2.0 以降は Tomcat プロジェクト側に開発が移ったようです。
- 2.0以降:2.0-SNAPSHOTは開発中、Maven Central Repositry に登録されているのは 2.0-beta-1 までです。
-- http://tomcat.apache.org/maven-plugin.html
-- http://tomcat.apache.org/maven-plugin-2/
-- http://tomcat.apache.org/maven-plugin-2.0-SNAPSHOT/
- 1.0, 1.1, 1.2:codehausのドキュメント参照。
-- http://mojo.codehaus.org/tomcat-maven-plugin/index.html
- 5. Maven による実アプリケーション開発 | TECHSCORE(テックスコア)
-- http://www.techscore.com/tech/Java/ApacheJakarta/Maven/5/
以下注意点です。
- GroupId : 1.2 までは "org.codehaus.mojo", 2.0 以降は "org.apache.tomcat.maven" に変更されています。
- どのリポジトリを使えば良いのか?
-- 1.1 と 2.0 については Central(repo1) に登録されているのを使えば良いと思います。
-- 1.2 については codehaus リポジトリにのみ登録されているため、1.2を使う場合は settings.xml か pom.xml にcodehausのリポジトリ設定を追加する必要があります。
- 利用するTomcatのバージョンを選択できるか?
-- 2.0以降は Tomcat6 : tomcat6-maven-plugin, Tomcat7 : tomcat7-maven-plugin というようにTomcatのバージョンごとに分かれているようです。
-- Tomcat Maven Plugin - Adjust Tomcat Version
--- http://mojo.codehaus.org/tomcat-maven-plugin/examples/adjust-embedded-tomcat-version.html
--- http://tomcat.apache.org/maven-plugin-2/tomcat6-maven-plugin/examples/adjust-embedded-tomcat-version.html
||<
本記事では、以下の理由から バージョン 1.2 のtomcat-maven-plugin を使ってみます。
- Jetty版については公式サイトにかなり詳しく色々なバリエーションと応用技法が載っているのに対し、Tomcat版はあまり情報が豊富でない気がした。
- たまたま本記事を書くきっかけとなったEclipseプロジェクトの本番deploy環境がTomcatだったため、環境を合せておきたかった。実働環境はTomcatなのに、開発をJettyとすることで不要な地雷を踏み抜きそうな悪寒がした。
- pom.xmlにリポジトリ設定を記述する練習をしたかったので、あえてcodhausのsnapshotリポジトリの追記が必要な 1.2 を選択。
* サンプルコード
環境:
MacOS X 10.7.3
$ mvn -version
Apache Maven 3.0.3 (r1075438; 2011-03-01 02:31:09+0900)
Maven home: /usr/share/maven
Java version: 1.6.0_31, vendor: Apple Inc.
Java home: /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
Default locale: ja_JP, platform encoding: SJIS
OS name: "mac os x", version: "10.7.3", arch: "x86_64", family: "mac"
Eclipse 3.7 Java EE
M2E - Maven Integration for Eclipse 1.0
archetypeとしてcodehausのwebapp-jee5を使って "Hello, World" のServletサンプルコードを作成します。
#pre||>
$ mvn archetype:generate
…
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): : org.codehaus.mojo.archetypes:webapp-jee5
Choose archetype:
1: remote -> org.codehaus.mojo.archetypes:webapp-jee5 (-)
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): : 1
Choose version:
1: 1.0
2: 1.0.1
3: 1.1
4: 1.2
5: 1.3
Choose a number: 5:
Define value for property 'groupId': : test
Define value for property 'artifactId': : servlet1
Define value for property 'version': 1.0-SNAPSHOT: :
Define value for property 'package': test: : test.servlet1
Confirm properties configuration:
groupId: test
artifactId: servlet1
version: 1.0-SNAPSHOT
package: test.servlet1
…
$ cd servlet1/
$ find .
.
./pom.xml
./src
./src/main
./src/main/java
./src/main/java/test
./src/main/java/test/servlet1
./src/main/webapp
./src/main/webapp/index.jsp
./src/main/webapp/WEB-INF
./src/main/webapp/WEB-INF/web.xml
||<
とりあえずEclipseにインポートし、以下のJavaクラスを追加します。
src/main/java/test/servlet1/Hello.java:
#code|java|>
package test.servlet1;
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 Hello extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
out.println("");
out.println("
");
out.println("Hello, World!");
out.println("");
out.println("");
out.close();
}
}
||<
src/main/webapp/WEB-INF/web.xml に以下のようにservlet設定を追加します。
#pre||>
servlet1
30
index.jsp
Hello
test.servlet1.Hello
Hello
/hello
||<
"mvn package" で target/servlet1-1.0-SNAPSHOT.war が生成されれば、一旦適当なTomcatのwebappsディレクトリにコピーし、deployして動作確認しておきます。
* codehausのリポジトリURLとtomcat-maven-pluginの組み込み
まずcodehausのsnapshotリポジトリURLをpom.xmlに組み込みます。
2012-04現在、codehausではsonatypeのNexus ( http://www.sonatype.com/Products/Nexus-Professional ) を運用していますので、以下のURLからsnapshotリポジトリのURLを確認できます。
+ https://nexus.codehaus.org/
+ サイドメニューの "Views/Repositories" から "Repositories" 選択 -> "Snapshots Group" の "Repository Path" をコピー。
+ 上でコピーしたURLを以下のようにpom.xmlに組み込みます。要素の順番はあまり気にしなくて良いようです。不安であれば http://maven.apache.org/pom.html#Quick_Overview の順に配置すればよいでしょう。
#pre||>
...
true
codehaus-snapshots-group
Codehaus Snapshot Repositry
https://nexus.codehaus.org/content/groups/snapshots-group/
true
codehaus-snapshots-group
Codehaus Snapshot Repositry
https://nexus.codehaus.org/content/groups/snapshots-group/
...
||<
続いてtomcat-maven-pluginを組み込みます。
+ "Snapshots Group" 選択
+ "Browse Storage" の "Path Lookup:" で "org/codehaus/mojo/tomcat-maven-plugin" を選択
+ "1.2-SNAPSHOT" から適当な jar を選択
+ "Maven Information" の "XML" に、そのままpom.xmlにコピペ出来る "" タグが表示されるので、pom.xmlに以下のようにコピペ。
#pre||>
...
org.apache.maven.plugins
maven-compiler-plugin
2.0.2
1.5
1.5
org.codehaus.mojo
tomcat-maven-plugin
1.2-SNAPSHOT
/
...
||<
では "mvn tomcat:run" を実行してみます。依存jarのDLが終わった後、Tomcatの起動メッセージが表示されます。
"Starting Coyote HTTP/1.1 on http-8080" のメッセージが表示されたら、ブラウザでlocalhostの8080番にアクセスしてみます。""要素にて、ContextPathを "/" にしていますので、
http://localhost:8080/hello
にアクセスすれば Hello クラスのServletが実行されます。
上手く動かない場合は、すでに8080番をListenしているサービスがいないか、pom.xmlの記述をtypoしていないかなど確認してみてください。
また起動されたTomcatは、Ctrl-Cで終了できます。
* Eclipseからのデバッグ実行
ここまで確認できれば、あとはEclipse上からMaven Buildの "tomcat:run" ゴールをデバッグ実行します。この時、デバッグビューにて実行中のMaven Buildを右クリックしてソースルックアップパスを適切に設定しておきましょう。
あとはブレークポイントを設定するなどして、自由にデバッグ実行が可能です。また、Eclipse上でJavaソースを編集して保存すると、即座にTomcat側にも反映されます。
tomcat-maven-pluginには他にも、warをTomcatにdeployしたり、deploy中のアプリ一欄を表示したりと色々便利なゴールが用意されています。また "tomcat:run" ゴール自体にも"fork"を始めとするオプションパラメータを設定できますので、CIサーバ上で結合テストを実施するなどにも活用できます。
本記事をきっかけとして、実際の現場でtomcat-maven-pluginを活用していただければ幸いです。
#navi_footer|Java|