CLOVER🍀

That was when it all began.

Codehaus Cargo Maven 3 Pluginを使って、Apache Tomcatをダウンロードしてきてデプロイする

これは、なにをしたくて書いたもの?

最近、WildFlyを使う時はWildFly Maven Pluginを使って、WildFlyを簡単にプロビジョニングしています。
WildFly Glowも使えますしね。

ただ、Apache Tomcatを使う時にはダウンロードしてきて展開して…とやっているのが面倒なので、なにかいい方法は
ないかなと思い、そういえばということでCodehaus Cargo Maven 3 Pluginを使うことにしました。

Codehaus Cargo Maven 3 Plugin

Codehaus Cargoを使うと、Java EEJakarta EEのアプリケーションサーバーをAPIで操作できます。

Codehaus Cargo - Home

アプリケーションサーバーの起動や停止、アプリケーションのデプロイなどができます。

また、テストやApache MavenApache Antなどと組み合わせて使うこともできます。

Codehaus Cargo - Functional testing

Codehaus Cargo - Maven 3 Plugin

Codehaus Cargo - Ant support

実は、以前にもこのブログで扱ったことがあります。

WildFly 25+Codehaus Cargo Maven 3 Pluginでインテグレーションテスト - CLOVER🍀

この時はWildFlyを対象にして、Arquillianを使ったインテグレーションまでやったりしていましたが、今回はApache Tomcat
対象にして、アプリケーションをデプロイするところくらいまでをやってみます。

使うのはApache Tomcat 10.xとします。

Codehaus Cargo - TomEE 10.x

参考にするのはこのあたりでしょうか。

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というものを使うようですが、今回はパスします。

Codehaus Cargo - 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アプリケーションを
デプロイしてみました。

アプリケーションサーバーをダウンロードしてきたりする過程が面倒だなと思っていたので、ちょうどいい感じですね。

Apache Tomcatのこのブログでの登場頻度はだいぶ下がっていますが、覚えておいてもよいかなと思います。