はじめに
掲題のとおり、Mavenコマンドだけでステップ実行できる環境を構築したかったんです。
Docker とか VM とか立ち上げるほどリソースに余裕もなく、clone & checkout してビルドするとか待ってられず、それでも実行時変数確認とかバージョン差異検証とかしたくなってしまいまして。
で、古来よりある**Codehaus Cargo (以下Cargo)**を使ってやってみようかなと思い立って、この記事となります。
昔からあるツールですし「いまどきMavenかよ」って今更感のある内容ですが、参考にでもなれば。
要件
- 手元にソース置いてビルドするのが面倒
- アプリ側のソースは弄れない(pom.xml含む)、変更管理上厳しい
- バージョン違いで切り替えたり、いっそ同時起動したい
- メモリとか余裕がないから、VMとかコンテナとかはちょっと...
- IDEは別途立ち上げるとしても、1コマンドでアプリをぽこぽこ立てたい
- APサーバはJetty9.4系で、軽いし
必要なもの
予め以下を用意しておきましょう。
- Maven 3.5+
- 3系なら何でもいいかもしれない
- Java8+
- JDK8でしか試してないけど、以降でも多分大丈夫
- VSCode
- デバッグする場合に使う、動かすだけなら不要
- Java用拡張機能は入れておきましょう
で、できたものがこちらです
雑ですが、pom.xmlとJetty設定ファイルだけで構成しています。
基本はmvnコマンド実行時引数(-Dオプション)でどうにでもなるようにしてます。
とりあえず下記コマンドで org.codehaus.cargo:datasource-war というデータソースを開くだけのサンプルアプリが動きます。
git clone https://github.com/Piecemeal-Technology-Inc/cargo-jetty-launcher.git
cd cargo-jetty-launcher
mvn initialize compile cargo:run
ブラウザで http://localhost:8081/change-context-root/test にアクセスすると「Got connection!」が表示されます。
コンテキストルートは pom.xml の context.path で制御しています。
さぁデバッグしよう
VSCodeを立ち上げて、「実行」-「構成の追加」でJavaのlaunch.jsonを生成します。
そこで、以下の構成をconfigurationsへ追加します。
{
"type": "java",
"name": "Debug (Remote 9990)",
"request": "attach" , // リモートデバッグ指定
"projectName" : "cargo-jetty-launcher",
"hostName": "localhost",
"port": 9990, // pom.xml の debug.port プロパティと合わせる
// target 配下にできてるソースへの参照パスを追加
"sourcePaths": [
"${workspaceFolder}/target/sources-datasource-war.1.7.11/main",
"${workspaceFolder}/target/sources-datasource-war.1.7.11/dependency"
]
}
以上で準備が完了したので、後は適当に breakpoint 張ってデバッガ起動するとステップ実行ができます。
- mvn cargo:run でサーバを起動しておく
- target/sources-datasource-war.1.7.11/main にwarのソースが入っているので、止めたいところに breakpoint を張る
- launch.json で作った構成をデバッグで実行する
- http://localhost:8081/change-context-root/test にアクセスする
- breakpoint で止まる! アプリ側だけでなく、Jetty側のソースへもステップインできてる
おわりに
※注意
これは試行錯誤の末なので、基本的にセオリー通りではないと思います。
組み込みデータソース使うとかJetty独自拡張入れないとかなら、公式通りに普通にやれば大丈夫かと。
※今回はDBCP2を使いたかったので、多少無理やり構成している
実行時引数である程度汎用的にしてるので、上げたいアプリごとにコマンド用意しておくなどしておけば楽に上げられます。
また、ソースコードなどの実体を持たないので、軽量な形で実行環境をPJ内に展開したりもできます。
本当はCargoでハマったとこの話を書こうと思ってましたが、需要無いと思うのでとりあえず割愛。
使用にあたっての前提条件
そもそも、動かす対象のwarとsource-jarがローカルリポジトリ、またはリモートリポジトリにないとダメです。
デバッグしないなら source-jar は不要で、warだけあれば動かせますので。