これは、なにをしたくて書いたもの?
最近、WildFlyを使う時はWildFly Maven Pluginを使って、WildFlyを簡単にプロビジョニングしています。
WildFly Glowも使えますしね。
ただ、Apache Tomcatを使う時にはダウンロードしてきて展開して…とやっているのが面倒なので、なにかいい方法は
ないかなと思い、そういえばということでCodehaus Cargo Maven 3 Pluginを使うことにしました。
Codehaus Cargo Maven 3 Plugin
Codehaus Cargoを使うと、Java EE/Jakarta EEのアプリケーションサーバーをAPIで操作できます。
アプリケーションサーバーの起動や停止、アプリケーションのデプロイなどができます。
また、テストやApache Maven、Apache Antなどと組み合わせて使うこともできます。
Codehaus Cargo - Functional testing
Codehaus Cargo - Maven 3 Plugin
実は、以前にもこのブログで扱ったことがあります。
WildFly 25+Codehaus Cargo Maven 3 Pluginでインテグレーションテスト - CLOVER🍀
この時はWildFlyを対象にして、Arquillianを使ったインテグレーションまでやったりしていましたが、今回はApache Tomcatを
対象にして、アプリケーションをデプロイするところくらいまでをやってみます。
参考にするのはこのあたりでしょうか。
Codehaus Cargo - Maven 3 Plugin
Codehaus Cargo - Maven 3 Plugin Installation
Codehaus Cargo - Maven 3 Plugin Reference Guide
Codehaus Cargo - Maven 3 Plugin Tips
環境
今回の環境はこちら。
$ java --version openjdk 21.0.5 2024-10-15 OpenJDK Runtime Environment (build 21.0.5+11-Ubuntu-1ubuntu124.04) OpenJDK 64-Bit Server VM (build 21.0.5+11-Ubuntu-1ubuntu124.04, mixed mode, sharing) $ mvn --version Apache Maven 3.9.9 (8e8579a9e76f7d015ee5ec7bfcdc97d260186937) Maven home: $HOME/.sdkman/candidates/maven/current Java version: 21.0.5, vendor: Ubuntu, runtime: /usr/lib/jvm/java-21-openjdk-amd64 Default locale: ja_JP, platform encoding: UTF-8 OS name: "linux", version: "6.8.0-52-generic", arch: "amd64", family: "unix"
Webアプリケーションを用意する
まずはデプロイ対象のWebアプリケーションを用意します。
RESTEasy+Weld Servletで簡単なものを作りたいと思います。
pom.xml
pom.xml <?xml version="1.0" encoding="UTF-8"?> <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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.littlewings</groupId> <artifactId>tomcat-cargo-example</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <properties> <maven.compiler.release>21</maven.compiler.release> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> </properties> <dependencies> <dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> <version>6.0.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-core</artifactId> <version>6.2.11.Final</version> </dependency> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-jackson2-provider</artifactId> <version>6.2.11.Final</version> </dependency> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-servlet-initializer</artifactId> <version>6.2.11.Final</version> </dependency> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-cdi</artifactId> <version>6.2.11.Final</version> </dependency> <dependency> <groupId>org.jboss.weld.servlet</groupId> <artifactId>weld-servlet-core</artifactId> <version>5.1.5.Final</version> </dependency> </dependencies> <build> <finalName>ROOT</finalName> <plugins> <!-- 後で --> </plugins> </build> </project>
Codehaus Cargo Maven 3 Pluginについては、後で書きます。
Jakarta RESTful Web Services(JAX-RS)の有効化。
src/main/java/org/littlewings/tomcat/RestApplication.java
package org.littlewings.tomcat; import jakarta.ws.rs.ApplicationPath; import jakarta.ws.rs.core.Application; @ApplicationPath("/") public class RestApplication extends Application { }
JAX-RSリソースクラス。
src/main/java/org/littlewings/tomcat/HelloResource.java
package org.littlewings.tomcat; import java.util.Map; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.ws.rs.Consumes; import jakarta.ws.rs.GET; import jakarta.ws.rs.POST; import jakarta.ws.rs.Path; import jakarta.ws.rs.Produces; import jakarta.ws.rs.core.MediaType; @Path("/hello") @ApplicationScoped public class HelloResource { @Inject private MessageService messageService; @GET @Produces(MediaType.TEXT_PLAIN) public String message() { return "Hello World"; } @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public Map<String, String> json(Map<String, String> body) { return Map.of("message", messageService.decorate(body.get("message"))); } }
Jakarta Contexts and Dependency Injection(CDI)管理Bean。
src/main/java/org/littlewings/tomcat/MessageService.java
package org.littlewings.tomcat; import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped public class MessageService { public String decorate(String value) { return String.format("★★★%s★★★", value); } }
CDIの有効化。こちらは空のファイルです。
src/main/resources/META-INF/beans.xml
これで準備は完了です。
Codehaus Cargo Maven 3 Pluginを使ってApache TomcatにWebアプリケーションをデプロイする
では、Codehaus Cargo Maven 3 Pluginを使って、Apache TomcatにWebアプリケーションをデプロイします。
まずはプラグインの設定。
<plugin> <groupId>org.codehaus.cargo</groupId> <artifactId>cargo-maven3-plugin</artifactId> <version>1.10.17</version> <configuration> <container> <containerId>tomcat10x</containerId> <zipUrlInstaller> <url>https://archive.apache.org/dist/tomcat/tomcat-10/v10.1.34/bin/apache-tomcat-10.1.34.tar.gz</url> </zipUrlInstaller> </container> </configuration> </plugin>
最小構成はこれくらいでしょうか。
zipUrlInstallerと言いつつ、tar.gzでも指定できます。お好みで。
これでApache Tomcatを自動的にダウンロードしてくるわけですが、ダウンロード先(downloadDir)はデフォルトでは
${java.io.tmpdir}/cargo/installs、展開先(extractDir)はデフォルトでは${project.build.directory}/cargo/installsです。
今回は困らないので、このままいきます。
では、アプリケーションをパッケージングしてApache Tomcatにデプロイしてみます。
$ mvn package cargo:run
先にパッケージングすることが必要で、cargo:runでフォアグラウンドでApache Tomcatが起動します。
この時、Apache Tomcatは自動的にダウンロードしてきます。
ダウンロードしたファイルと、展開後。
$ ll /tmp/cargo/installs/apache-tomcat-10.1.34.tar.gz
-rw-rw-r-- 1 xxxxx xxxxx 13692270 12月 6 01:13 /tmp/cargo/installs/apache-tomcat-10.1.34.tar.gz
$ tree target/cargo/ -L 4
target/cargo/
├── configurations
│ └── tomcat10x
│ ├── common
│ │ ├── classes
│ │ └── lib
│ ├── conf
│ │ ├── Catalina
│ │ ├── catalina.policy
│ │ ├── catalina.properties
│ │ ├── context.xml
│ │ ├── jaspic-providers.xml
│ │ ├── jaspic-providers.xsd
│ │ ├── logging.properties
│ │ ├── server.xml
│ │ ├── tomcat-users.xml
│ │ ├── tomcat-users.xsd
│ │ └── web.xml
│ ├── logs
│ │ └── localhost_access_log..2025-02-04.txt
│ ├── shared
│ │ ├── classes
│ │ └── lib
│ ├── temp
│ ├── webapps
│ │ ├── ROOT
│ │ ├── ROOT.war
│ │ ├── cargocpc
│ │ ├── cargocpc.war
│ │ ├── host-manager
│ │ └── manager
│ ├── webapps-javaee
│ └── work
│ └── Catalina
└── installs
└── apache-tomcat-10.1.34
└── apache-tomcat-10.1.34
├── BUILDING.txt
├── CONTRIBUTING.md
├── LICENSE
├── NOTICE
├── README.md
├── RELEASE-NOTES
├── RUNNING.txt
├── bin
├── conf
├── lib
├── logs
├── temp
├── webapps
└── work
31 directories, 20 files
確認してみましょう。
$ curl localhost:8080/hello
Hello World
$ curl -XPOST -H 'Content-Type: application/json' localhost:8080/hello -d '{"message": "Hello World"}'
{"message":"★★★Hello World★★★"}
OKですね。
ここで、ソースコードを変更してみます。
@GET @Produces(MediaType.TEXT_PLAIN) public String message() { return "Hello World!!"; }
パッケージングして、再デプロイ。
$ mvn package cargo:redeploy
少し待っていると、Apache Tomcatが検出して反映してくれます。
$ curl localhost:8080/hello Hello World!!
OKですね。
その他のゴールはこちら。
Codehaus Cargo - Maven 3 Plugin
ホットデプロイ的なことをやろうとすると、Cargo Daemonというものを使うようですが、今回はパスします。
今回はとにかく簡単に使いたかったので、このくらいにしておきます。
追記)
なお、cargo:runを実行した後にCtrl-cで止めるとやたら時間がかかるのですが、こちらの対処案は別エントリーに書いて
おきました。
Codehaus Cargo Maven 3 PluginとApache Tomcat 10.1でcargo:runを使った時に、停止が遅いのをなんとかしたい - CLOVER🍀
おわりに
Codehaus Cargo Maven 3 Pluginを使って、Apache Tomcatを簡単にダウンロードしてきてWebアプリケーションを
デプロイしてみました。
アプリケーションサーバーをダウンロードしてきたりする過程が面倒だなと思っていたので、ちょうどいい感じですね。