タイトル/名前 | 更新者 | 更新日 |
---|---|---|
Java/Tomcat, Jetty と ServletContext.getRealPath() の末尾 | msakamoto-sf | 2012-04-09 23:16:13 |
Java/com.sun.tools.javac.Main, Compiler API, tools.jar 今昔メモ | msakamoto-sf | 2012-04-09 22:48:45 |
日記/2012/03/18/MavenのwarプロジェクトをEclipse上からデバッグ | msakamoto-sf | 2012-04-09 18:21:56 |
Java/Maven2メモ | msakamoto-sf | 2012-04-09 18:11:17 |
日記/2012/04/01/EGitでドハマリ中・・・ | msakamoto-sf | 2012-04-01 22:05:23 |
技術/MacOSX/テキストエディタ環境 | msakamoto-sf | 2012-03-18 14:47:28 |
日記/2012/03/12/bouncycastleのX509V3CertificateGeneratorクラス | msakamoto-sf | 2012-03-12 01:22:33 |
日記/2012/03/11/Eclipse3.7(Indigo)とm2eにMavenプロジェクトをインポートするメモ | msakamoto-sf | 2012-03-11 18:40:07 |
日記/2012/03/10/Eclipse3.7(Indigo)でMavenとSubversion環境セットアップメモ | msakamoto-sf | 2012-03-10 11:54:49 |
日記/2012/02/26/MavenでServletプログラミングを準備したメモ | msakamoto-sf | 2012-02-26 20:10:14 |
Java/Maven3/Eclipse上でサクサクWeb開発 (例:tomcat-maven-plugin) にて tomcat-maven-plugin を選択した理由に、
「実働環境はTomcatなのに、開発をJettyとすることで不要な地雷を踏み抜きそうな悪寒がした。」
と書きましたが、今思い出しました。
実際に地雷を踏み抜いていたから、わざわざTomcatを選んだのでした。
その理由は簡単で、javax.servlet.ServletContext#getRealPath("/") が返す文字列が、Tomcatの場合末尾が '/' 付きで、Jettyの場合末尾の '/' が付いてこない。で、件のEclipseプロジェクトでは
getRealPath("/") + "WEB-INF/foo/bar...";
としていたものだから(他人から引き継いだ既存プロジェクト)、Jettyに載せ替えようと思っても載せ替えられない。
実例:/work/tmp/mvntest/servlet1/src/main/webapp/WEB-INF/web.xml をdeploy
/work/tmp/mvntest/servlet1/src/main/webapp/
/work/tmp/mvntest/servlet1/src/main/webapp
まぁ他にも地雷が埋まってそうだったので、素直にTomcatで打てる手が無いか探していた結果、tomcat-maven-plugin を見つけた次第です。
これだと、
getRealPath("/") + "WEB-INF/foo/bar..."
がJettyだと
/work/tmp/mvntest/servlet1/src/main/webappWEB-INF/foo/bar...
になってしまい、ファイル操作が失敗してしまうという罠・・・。
この辺、もしかして仕様が決まってないのかな?JavaDoc確認しても、J2EE 1.3 と Java EE 6 の双方で、ディレクトリを指定した場合の末尾のPATH SEPARATORについて明確な言及がない。
JDK 1.5 時代と 1.6 時代、さらに Mac OS X 上の Java とで、だいぶ扱いが異なってきたのでメモ。
単純な解決策:
<dependencies> <dependency> <groupId>com.sun</groupId> <artifactId>tools</artifactId> <version>1.5.0</version> <scope>system</scope> <systemPath>${java.home}/../lib/tools.jar</systemPath> </dependency> </dependencies>
Macの場合だけ除外したい:
<profiles> <profile> <id>windows</id> <activation> <os> <family>windows</family> </os> </activation> <dependencies> <dependency> <groupId>com.sun</groupId> <artifactId>tools</artifactId> <version>1.5.0</version> <scope>system</scope> <systemPath>${java.home}/../lib/tools.jar</systemPath> </dependency> </dependencies> </profile> </profiles>
参考:
日記/2012/03/11/Eclipse3.7(Indigo)とm2eにMavenプロジェクトをインポートするメモ ではEclipseにMavenプロジェクトをインポートするところまでを紹介しました。
"jar"を生成するタイプのMavenプロジェクトであればm2eのおかげで"test"ゴールをEclipseからデバッグ実行できますので特に問題となることは少ないと思います。
困るのが"war"タイプのMavenプロジェクトで、デバッグ対象のServletコンテナをどこで起動するか、どうEclipseから接続するか、Maven独自のclasspathをどのように解決するか、というように解決すべき課題が多くなります。
いくつか調べた中でメリット・デメリットをまとめます。
2012-04-09 追記しました。
Maven独自のソースツリーと、Eclipse上でJava保存→即時コンパイル→コンテキストリロード、そこまでは何かしら解決策があります。どうしてもMavenのjarファイル依存関係、それがボトルネックになり、jetty:runかdeployして実行(場合によってはリモートデバッグ接続)かの分水嶺となっています。
2012-04-09 追記
tomcat-maven-plugin を使うことで、JettyだけでなくTomcatでもdeployせずにEclipse上からシームレスにデバッグまで繋げられることが出来ることが判明しました。
以前、WebLogic と Ant でJ2EEサーバの機能を使用したWebアプリを開発していたときは、外部でリモートデバッグ接続を有効にしたWebLogicを立ち上げておいて、そちらにAntからwarをdeploy→Eclipseからリモートデバッグ接続、という手順を踏んでいました。多少のタイムラグはありましたが、それでもリズムを崩す程ではなかったです。
Tomcat7のVirtual webappも「よくぞ対処してくれた」感はあるものの、やはりjarファイル依存関係のスマートな解決策が見当たらないので今ひとつな感じがあります。
他、参考:
Apache Maven メモ (Maven2系)
以下、本家やTECHSCOREを見比べつつ自分用メモ
例えば maven-compiler-plugin でコンパイラオプションを指定したい場合、以下のpluginエントリを追加するわけですが・・・
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>?.?.?</version> <configuration> ... </configuration> </plugin>
自分が使っているMavenでの"version"はどうやって調べればよいのか?
→ "help" plugin の "effective-pom" ゴールを実行し、デフォルト設定を確認する。
> mvn help:effective-pom ... <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>2.0.2</version> </plugin>
"Available Plugins"("Documentation" > "Maven Plugins"), http://maven.apache.org/plugins/index.html に載っているバージョンだと最新のバージョンになってしまいます。とりあえず自分が今使っているMaven提供pluginのバージョンを調べたい時は、effective-pom経由の方が正確だと思います。
↑だけで見つからない場合は、Maven FAQ(official) に紹介されているその他の検索サイトを使ってみましょう。
但し検索サイトによってはバージョンが古かったりしますので、複数試してみることをオススメします。
個人的には次の二つが好みです。
http://mvnrepository.com/ : 依存・非依存artifactsやlicense情報を表示してくれる。
http://mavensearch.net/ : repository情報も表示してくれる。
Eclipseプロジェクトフォルダの直下に .git がある場合はちゃんとアイコンオーバーレイも表示されるしプロジェクトアイコン右クリックのチーム("Team")メニューにEGitの用意してくれたサブメニューがちゃんと表示されて利用できる。
some_prj/ .classpath .project .git/ src/ bin/ ...
↑は問題なし。
ところが、複数Prjが.gitのある階層の下に並ぶと、EGitからインポートしてもアイコンオーバーレイ表示されないしプロジェクトアイコン右クリックしてもTeamにEGitが出てこない・・・。
some_projects/ .git/ prj1/ .classpath, .project, src/, bin/, ... prj2/ .classpath, .project, src/, bin/, ...
↑これでハマった・・・。
ちょこっとだけggrksしてみたらStackOverflowとかにも何やら似たようなトラブルが載っているっぽい・・・。まぁ、特にgitのデータベースが壊れるとかそういった現象ではない。単純に、Eclipseプロジェクトフォルダより上位階層までは .git/ の存在を確認してないだけかもしれない。なので、最悪、git操作はターミナル等のCUIからおこなっても問題ない。
ちなみに、MercurialEclipseではちゃんと上位の .hg/ ディレクトリを認識してくれました。
MacOSX (Lion, 10.7) 以降でのプログラミング向けテキストエディタ環境検討メモ。
「Software Design 2011年12月号」で紹介されていたのも参考。
独断と偏見で、Windowsで著名なエディタで言うとどれにあたるか、という基準でコメントしてます。
1.45まで:
$ jar -tf bcprov-jdk14-1.45.jar | grep X509V3CertificateGenerator org/bouncycastle/jce/X509V3CertificateGenerator.class org/bouncycastle/x509/X509V3CertificateGenerator.class
org.bouncycastle.jce.X509V3CertificateGeneratorが存在している。
1.46になり:
$ jar -tf bcprov-jdk14-146.jar | grep X509V3CertificateGenerator org/bouncycastle/x509/X509V3CertificateGenerator.class
org.bouncycastle.jce.X509V3CertificateGeneratorが無くなっていた・・・。何故に?
日記/2012/03/10/Eclipse3.7(Indigo)でMavenとSubversion環境セットアップメモ ではEclipseにMavenプラグインを導入し、既存のEclipse用Mavenプロジェクトをインポートするところまでを解説しました。
今回は、素のMavenプロジェクトをEclipseのプロジェクトに取り込む方法をメモ。ここで言う「素のMavenプロジェクト」というのは、".project"や".classpath"ファイル, ".settings"ディレクトリなどが作成されていない、Eclipseプロジェクトとは認識されないファイルセットを指します。
ということで、今回は myart3 という以下の構造のMavenプロジェクトを「Eclipse化」してみます。
/work/tmp/mvntest/myart3/ pom.xml src/main/java/foo/bar/App.java src/test/java/foo/bar/AppTest.java
※今回は "Maven Eclipse Plugin" ( http://maven.apache.org/plugins/maven-eclipse-plugin/ ) は取り上げません。また、マルチモジュール化されたMavenプロジェクトの取り込みについてはまたの機会に。
まずEclipseのインポートメニューからMavenの "Existing Maven Projects" を選択します。
続いてpom.xmlのあるディレクトリを"Root Directory"として選択すると、自動的にインポートするプロジェクトがリストアップされます。
インポートに完了後、Eclipseのナビゲータビューで確認すると".project", ".classpath", ".settings" が作成されています。
".classpath"を覗いてみると、m2e専用のコンテナが設定されていることを確認できます:
$ cat .classpath <?xml version="1.0" encoding="UTF-8"?> <classpath> <classpathentry kind="src" output="target/classes" path="src/main/java"/> <classpathentry kind="src" output="target/test-classes" path="src/test/java"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/> <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"/> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ <classpathentry kind="output" path="target/classes"/> </classpath>
SCM上に素のMavenプロジェクトが登録されている状態で、それをチェックアウト。
今回はローカルのSubversionリポジトリで以下を用意し、その直下にmyart3をコミットしています。
file:///work/SVNREPOS/test1
まずはインポートメニューからMavenの"Check out Maven Projects from SCM"を選択します。ちなみにこのメニューは、すでにEclipseプロジェクト化されたMavenプロジェクトをSCMからチェックアウトする場合も利用できます。
SCM URLでSubversionのローカルリポジトリを指定しています:
locationなどカスタマイズできます。何も入力しないデフォルトのままインポートすると、Eclipseのナビゲーションビューで以下のように".project"などのファイル・ディレクトリが作成されたことが確認されました。
一方で、以下のように"maven"で始まる適当なディレクトリにチェックアウトされてしまいましたので注意が必要です。
予めsvnコマンドやTortoiseSVN等でローカルにチェックアウトしておきます。
今回は以下のディレクトリにチェックアウトしました:
$ pwd /work/tmp/mvntest/test1/myart3 $ svn info Path: . URL: file:///work/SVNREPOS/test1/myart3 Repository Root: file:///work/SVNREPOS/test1 ...
EclipseのインポートメニューからMavenの "Existing Maven Projects" を選択し、チェックアウトした素のMavenプロジェクトのディレクトリを "Root Directory" に設定します。以降は 1. の時と同じです。
EclipseのSubversiveプラグインの方で ".svn" を認識してくれますので、 "2." と同様にSubversionの機能も利用できます。
この手順であれば、"2."のような"maven...."の中にチェックアウトされるようなことも無いので、こちらを個人的にはお勧めします。
MarketPlaceからのインストールなど、ビミョーに変わってたりするのでメモ。
MergeDocのPleiadesを使ってもいいし、eclipse.orgからGETしても良い。
Eclipse上でSubversionのリポジトリからチェックアウトしたりcommit出来るようになります。
MergeDocのPleiadesの場合、既にsubversiveが同梱されてますのでskipです。
eclipse.orgからDLした場合:
Eclipse上でMavenプロジェクトを作成したり、"mvn"コマンドのランチャーからビルドしたり出来るようになります。また、Eclipseプロジェクト用にビルドパスを調整してくれます。
Eclipse 3.6(Helios)の頃は"m2eclipse"だったんですが、3.7(Indigo)時代では単に"m2e"と呼ばれているようです。ヤヤコシイですね。
さて、これでSubversionとMavenそれぞれの環境は整いました。
ところが、これだけでは "SVN上のMavenプロジェクトをインポートする" というのが出来ません。
インポートメニューから "Check out Maven Projects from SCM" を選択しても、以下のようなダイアログになり適切なSCMを選択できません(SCMのプルダウンメニューが空っぽ)。つまり、まだMavenプラグインとSCMとの連携が取れていない状況です。
そこで、上図の右下、"Find more SCM connectors in the m2e Marketplace" をクリック。
これでようやく、m2e用のsubversiveコネクタが一覧の下の方に出てくるので、インストール。
これで無事、"Check out Maven Projects from SCM" のダイアログで "svn" をSCMとして選択できるようになりました。
動作確認用のサンプルとして、昔作成したTCP/IPの"Echo"サーバをMaven + Eclipseプロジェクト化してcodereposに上げてありますので、これで連携を確認してみます。
個人のBlog記事を参考にする場合は、必ず使っているEclipseのバージョンを確認してからにしてください。
特にm2eclipse関連では、2009年~2010年頃までの記事はほぼ全て、Eclipse 3.7 Indigo では参考にならないと考えて良いです。たった数年、数回のアップデートで、プラグインの名前やインストール方法が変わっています。昔の記事を参考に、昔のやり方でインストールするのは地雷原に何の準備もせず突っ込むような所業です。
2012-03時点(Eclipse 3.7時代)では、sonatypeの資料が一番オススメです。
しかしこれですらEclipse用の資料は3.6(Helios)時代であり、3.7では下記の差異がありましたので注意が必要です。
MavenとEclipseの連携はこのようにめまぐるしく変化していますが、Maven単体では利用者視点ではそれほど大きな変化はありません。
現在のメジャーバージョンはMaven3ですが、Maven2時代のテクニックはほぼ通用します。実際本記事で動作確認に使っている"echo_samples/act9"もMaven2時代に作成しています。
ただ、正直 Apache のMavenサイトのドキュメントは構成が分かりやすいとは言いづらいものがあり(個人的な感覚差はあると思います)、英語が読める方には上述のsonatypeの資料をお薦めします。
日本語ではTECHSCOREの記事がオススメでしょうか。
また、本記事では取り扱っていませんがMaven単体で作成したプロジェクトをEclipseに取り込むなどの作業については別途ノウハウが必要ですので、適宜調べてみてください。
Maven3, Jetty8, Eclipse 3.7(Indigo), m2eclipse 前提
mvn archetype:generate
で、org.codehaus.mojo.archetype:webapp-xxyy でプロジェクト作成。バージョンは適当に選ぶ。今回はwebapp-jee5を選択。
340: remote -> org.codehaus.mojo.archetypes:webapp-j2ee13 (-) 341: remote -> org.codehaus.mojo.archetypes:webapp-j2ee14 (-) 342: remote -> org.codehaus.mojo.archetypes:webapp-javaee6 (-) 343: remote -> org.codehaus.mojo.archetypes:webapp-jee5 (-)
codehausのarchetypeを選択するメリットとしては、src/main/java 以下のパッケージまでが展開されること。org.apache.maven.archetypes:maven-archetype-webappだと src/main/webapp/ までしか作ってくれない。
このあとEclipseで既存のMavenプロジェクトとしてインポートし、適当にServletクラス作成して、web.xmlに適当に登録する。
プロジェクト右クリックで Maven Build みたいなのを選択し、ゴールに "package" を指定して実行すれば target/ の下にwarファイルが作成される。
これを実行するためにTomcatを使うという手法もあるが、今回はJettyを使ってみる。
pom.xmlに上記ドキュメントに指定されたとおりに jetty-maven-plugin を追加し、EclipseでMavenの "jetty:run" ゴールを指定してデバッグ実行する。
ただこれだけだとソースコードが対応付けられていない。Debugパースペクティブを開きJettyのプロセスを右クリック→ "Edit Source Lookup" ソース探索パスを追加する。プロジェクト単位で追加できるし、Workspaceでごっそりと追加することも可能。
これでブレークポイントなどがソースコードと連携し、デバッグしやすくなる。
Maven + Jettyの何がよいかというと、test系と相性が良くなるようなきめ細かい設定が可能となっている。上述のドキュメントでは 「jetty:start : Starting jetty without first executing the build up to "test-compile" phase」のセクションで integration-test の前後で自動的にJettyを起動・停止するような設定例が書かれている。
またTomcat系の独立したWebApplicationServerと異なりwarファイルのデプロイ、それにともなうサーバのセットアップや設定の調整が不要な点も評価できる。
参考:Maven + Tomcatの例