CLOVER🍀

That was when it all began.

WildFlyのプロビジョニングをWildFly Glow × WildFly Maven Pluginで試す

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

WildFly 32.0.0.Finalのリリース時に、WildFly Glowというものが1.0.Finalになっていたようなので試してみたいなと思いまして。

WildFlyのプロビジョニングが簡単になるようなので。

WildFly Glow

WildFly Glowは、WildFlyのプロビジョニングツールであるGalleonを簡単に扱えるようにするものです。WildFly 32.0.0.Finalのリリース時に
1.0.Finalが公開されたようです。

WildFly Glow 1.0 Final
Ever since the introduction of Galleon several years back, a major WildFly focus has been tooling to improve our users' ability to easily provision an optimal WildFly installation, on-premise and particularly for the cloud. I’m very excited to announce Final availability of a major advance in this area — the set of provisioning tools we call WildFly Glow.

WildFly 32 is released!

WildFly GlowはCLIまたはWildFly Maven Pluginから利用します。アプリケーションアーティファクトを解析して、アプリケーションの実行に
必要なfeature-packやGalleonレイヤーを選択してくれるようです。カスタマイズ、WildFlyサーバー、Bootable JAR、Dockerイメージの
プロビジョニングもできるようです。

The WildFly Glow tools (a CLI application and a wildfly-maven-plugin integration) analyze your application artifact, determine what WildFly feature-packs and Galleon layers are needed to run your application, and make suggestions about other features (e.g. TLS support) that you may want to include in your optimized WildFly installation. You can take the information WildFly Glow provides and use it in your own provisioning configuration, or you can have WildFly Glow provision a server, bootable jar or Docker image for you. WildFlow Glow also provides a Maven plugin to help you automate provisioning when using Arquillian.

その他のWildFly Glowに関するブログエントリーはこちら。

WildFly Glow自体についてですが、まずGitHubリポジトリーはこちら。

GitHub - wildfly/wildfly-glow: Galleon Layers Output from War: Automatic discover of WildFly provisioning information from an application.

ドキュメントはこちらです。

WildFly Glow Documentation

WildFly GlowをWildFly Maven Pluginから使う

WildFly Glowを使うとWildFlyのプロビジョニングがどう簡単になるのかというところですが、WildFly Maven Plugin目線ではこちらの
ブログエントリーがわかりやすいです。

WildFly Glow, an evolution of WildFly provisioning

今までこういう感じでfeature-packやGalleonレイヤーを書いていたものが

...

<feature-packs>
  <feature-pack>
    <location>org.wildfly:wildfly-galleon-pack:${version.server}</location>
  </feature-pack>
</feature-packs>
<layers>
    <layer>cloud-server</layer>
    <layer>ejb</layer>
</layers>
...

こうなるそうです。

...
<discover-provisioning-info/>
...

単純に依存関係だけから類推できないようなHAやデータソース(ドライバー)などについてはこちらが

...

<feature-packs>
  <feature-pack>
    <location>org.wildfly:wildfly-galleon-pack:${version.server}</location>
  </feature-pack>
  <feature-pack>
    <location>org.wildfly.cloud:wildfly-cloud-galleon-pack:${version.cloud}</location>
  </feature-pack>
  <feature-pack>
    <location>org.wildfly:wildfly-datasources-galleon-pack:${version.ds}</location>
  </feature-pack>
</feature-packs>
<layers>
    <layer>cloud-server</layer>
    <layer>ejb</layer>
    <layer>ejb-dist-cache</layer>
    <layer>jpa-distributed</layer>
    <layer>postgresql-driver</layer>
</layers>
<excludedLayers>
    <layer>ejb-local-cache</layer>
    <layer>jpa</layer>
</excludedLayers>
...

こうなるようです。

...
<discover-provisioning-info>
  <profile>ha</profile>
  <context>cloud</context>
  <add-ons>
    <add-on>postgresql</add-on>
  </add-ons>
</discover-provisioning-info>
...

この設定が使えるのは、wildfly:、wildfly:、wildfly:

今回はWildFly Maven PluginからWildFly Glowを試してみたいと思います。

環境

今回の環境はこちら。

$ java --version
openjdk 21.0.2 2024-01-16
OpenJDK Runtime Environment (build 21.0.2+13-Ubuntu-122.04.1)
OpenJDK 64-Bit Server VM (build 21.0.2+13-Ubuntu-122.04.1, mixed mode, sharing)


$ mvn --version
Apache Maven 3.9.7 (8b094c9513efc1b9ce2d952b3b9c8eaedaf8cbf0)
Maven home: $HOME/.sdkman/candidates/maven/current
Java version: 21.0.2, vendor: Private Build, runtime: /usr/lib/jvm/java-21-openjdk-amd64
Default locale: ja_JP, platform encoding: UTF-8
OS name: "linux", version: "5.15.0-107-generic", arch: "amd64", family: "unix"

データベースも利用します。MySQLは8.0.37で、IPアドレスは172.17.0.2で動作しているものとします。

 MySQL  localhost:3306 ssl  practice  SQL > select version();
+-----------+
| version() |
+-----------+
| 8.0.37    |
+-----------+
1 row in set (0.0225 sec)

プロビジョニングするパターン

今回は、以下の3つのパターンで確認したいと思います。

Jakarta RESTful Web Services(JAX-RS)のみのアプリケーション。

JAX-RSとJakarta Persistence(JPA)を加え、クラスタリングも含めた以下の2パターン。

flowchart LR
    クライアント --> |curl/HTTP| A
    subgraph WildFly
    A[JAX-RS] --> B[JPA]
    end
    B --> |JDBC| D[(MySQL)]
flowchart LR
    クライアント --> |curl/HTTP| A
    クライアント --> |curl/HTTP| C
    subgraph WildFly1
    A[JAX-RS] --> B[JPA]
    end
    subgraph WildFly2
    C[JAX-RS] --> D[JPA]
    end
    WildFly1 <--> | clustering | WildFly2
    B --> |JDBC| E[(MySQL)]
    D --> |JDBC| E[(MySQL)]

また、Bootable JARとして構成することにします。

準備

Maven依存関係など。

    <groupId>org.littlewings</groupId>
    <artifactId>wildfly-glow-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>
        <failOnMissingWebXml>false</failOnMissingWebXml>
    </properties>

    <dependencies>
        <dependency>
            <groupId>jakarta.platform</groupId>
            <artifactId>jakarta.jakartaee-web-api</artifactId>
            <version>10.0.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <finalName>ROOT</finalName>
        <plugins>
            <plugin>
                <groupId>org.wildfly.plugins</groupId>
                <artifactId>wildfly-maven-plugin</artifactId>
                <version>5.0.0.Final</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>package</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <bootable-jar>true</bootable-jar>
                    <bootable-jar-name>${project.artifactId}-${project.version}-server-bootable.jar</bootable-jar-name>
                    <overwrite-provisioned-server>true</overwrite-provisioned-server>
                    <discover-provisioning-info>
                        <version>32.0.1.Final</version>

                        〜後で〜
                    </discover-provisioning-info>
                </configuration>
            </plugin>
        </plugins>

WildFly Maven Pluginの部分を先に説明しておきましょう。

mvn package時にwildfly:packageが実行されるようにします。

                <executions>
                    <execution>
                        <goals>
                            <goal>package</goal>
                        </goals>
                    </execution>
                </executions>

こちらはBootable JARを作成するための設定です。生成されるBootable JARの名前も指定しています。

                    <bootable-jar>true</bootable-jar>
                    <bootable-jar-name>${project.artifactId}-${project.version}-server-bootable.jar</bootable-jar-name>

WildFlyサーバーをプロビジョニングする際に、常に上書きするようにしています。これは、構成を変更した時にmvn cleanするのが
面倒だっただけです…。

                    <overwrite-provisioned-server>true</overwrite-provisioned-server>

discover-provisioning-infoを指定することで、WildFly GlowをWildFly Maven Pluginで使うことができるようになり、生成した
アーティファクトからプロビジョニングするWildFlyの内容を推測するようになります。

                    <discover-provisioning-info>
                        <version>32.0.1.Final</version>
                    </discover-provisioning-info>

versionでは、使用するWildFlyのバージョンを指定します。これを指定しない場合は、最新のWildFlyを使おうとします。

WildFly Glow Documentation / WildFly Maven Plugin integration / Specifying a WildFly version

あとはソースコードを追加したり、WildFly Maven Pluginの設定を変えたりして進めていきます。

簡単なJAX-RSリソースクラスのみを含むアプリケーションを書く

それでは最初は簡単なJAX-RSリソースクラスのみを含むアプリケーションを書いてみましょう。

src/main/java/org/littlewings/wildfly/glow/HelloResource.java

package org.littlewings.wildfly.glow;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;

@Path("hello")
public class HelloResource {
    @GET
    public String message() {
        return "Hello World!!";
    }
}

src/main/java/org/littlewings/wildfly/glow/RestApplication.java

package org.littlewings.wildfly.glow;

import jakarta.ws.rs.ApplicationPath;
import jakarta.ws.rs.core.Application;

@ApplicationPath("")
public class RestApplication extends Application {
}

WildFly Maven Pluginの設定は、このままにします。

            <plugin>
                <groupId>org.wildfly.plugins</groupId>
                <artifactId>wildfly-maven-plugin</artifactId>
                <version>5.0.0.Final</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>package</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <bootable-jar>true</bootable-jar>
                    <bootable-jar-name>${project.artifactId}-${project.version}-server-bootable.jar</bootable-jar-name>
                    <overwrite-provisioned-server>true</overwrite-provisioned-server>
                    <discover-provisioning-info>
                        <version>32.0.1.Final</version>
                    </discover-provisioning-info>
                </configuration>
            </plugin>

パッケージング。

$ mvn package

すると、こんな感じでアプリケーションの内容から必要なfeature-packやGalleonレイヤーを検出してくれます。

[INFO] --- wildfly:5.0.0.Final:package (default) @ wildfly-glow-example ---
[INFO] Glow is scanning...
[INFO] Glow scanning DONE.
[INFO] context: bare-metal
[INFO] enabled profile: none
[INFO] galleon discovery
[INFO] - feature-packs
   org.wildfly:wildfly-galleon-pack:32.0.1.Final
- layers
   ee-core-profile-server
   jaxrs

作成されたBootable JARはこれくらいのサイズです。

$ ll -h target/wildfly-glow-example-0.0.1-SNAPSHOT-server-bootable.jar
-rw-rw-r-- 1 xxxxx xxxxx 66M  6月  1 19:31 target/wildfly-glow-example-0.0.1-SNAPSHOT-server-bootable.jar

実行。

$ java -jar target/wildfly-glow-example-0.0.1-SNAPSHOT-server-bootable.jar

確認。

$ curl localhost:8080/hello
Hello World!!

OKですね。

JAX-RS+JPAなアプリケーションを書く

次は、このアプリケーションでJPAを使うようにしてみましょう。

JPAのエンティティ。

src/main/java/org/littlewings/wildfly/glow/Book.java

package org.littlewings.wildfly.glow;

import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;

@Entity
@Table(name = "book")
public class Book {
    @Id
    private String isbn;

    private String title;

    private Integer price;

    // getter/setterは省略
}

JPAを使うJAX-RSリソースクラス。

src/main/java/org/littlewings/wildfly/glow/BookResource.java

package org.littlewings.wildfly.glow;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.transaction.Transactional;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType;

import java.util.List;

@Transactional
@ApplicationScoped
@Path("books")
public class BookResource {
    @PersistenceContext
    EntityManager entityManager;

    @GET
    @Path("{isbn}")
    @Produces(MediaType.APPLICATION_JSON)
    @Transactional
    public Book find(@PathParam("isbn") String isbn) {
        return entityManager.find(Book.class, isbn);
    }

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public List<Book> findAll() {
        return entityManager
                .createQuery("select b from Book b order by b.price desc", Book.class)
                .getResultList();
    }

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Book register(Book book) {
        if (entityManager.find(Book.class, book.getIsbn()) != null) {
            entityManager.merge(book);
        } else {
            entityManager.persist(book);
        }

        return book;
    }
}

JPAの設定。

src/main/resources/META-INF/persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="https://jakarta.ee/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd"
             version="3.0">
    <persistence-unit name="sample.pu" transaction-type="JTA">
        <jta-data-source>java:jboss/datasources/MySqlDs</jta-data-source>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.format_sql" value="true"/>
            <property name="jakarta.persistence.schema-generation.database.action" value="drop-and-create"/>
        </properties>
    </persistence-unit>
</persistence>

テーブルはdrop-and-createでHibernateに作成してもらうことにしました。

とりあえず、パッケージングしてみます。

$ mvn package

するとこんな感じの表示になり、最終的にはエラーになりました。

[INFO] --- wildfly:5.0.0.Final:package (default) @ wildfly-glow-example ---
[INFO] Glow is scanning...
[INFO] Glow scanning DONE.
[INFO] context: bare-metal
[INFO] enabled profile: none
[INFO] galleon discovery
[INFO] - feature-packs
   org.wildfly:wildfly-galleon-pack:32.0.1.Final
- layers
   ee-core-profile-server
   jaxrs
   jpa

[INFO] identified errors
[ERROR] * unbound datasources error: java:jboss/datasources/MySqlDs
  To correct this error, enable one of the following add-ons:
  - mariadb
  - mssqlserver
  - mysql
  - oracle
  - postgresql

[INFO] Some suggestions have been found. You could enable suggestions with the <suggest>true</suggest> option.

データソースがないということで、データベースのいずれかのadd-onを指定しなさいと怒られています。

[ERROR] * unbound datasources error: java:jboss/datasources/MySqlDs
  To correct this error, enable one of the following add-ons:
  - mariadb
  - mssqlserver
  - mysql
  - oracle
  - postgresql

ところで、<suggest>true</suggest>とするといろいろ提案してくれるようなので1度有効にしてみましょう。

                    <discover-provisioning-info>
                        <version>32.0.1.Final</version>
                        <suggest>true</suggest>
                    </discover-provisioning-info>

この状態で再度実行すると、こんな情報が得られました。

[INFO] suggestions
[INFO] * you could enable the following add-ons:
[INFO]   - clustering add-ons:
    - infinispan : Brings in infinispan caches.
    - jgroups-aws : Brings in JBoss Modules modules required to configure the 'aws.S3_PING' discovery protocol.
    - mod_cluster : Support for mod_cluster integration.
  - database add-ons:
    - h2-database : Support for an H2 datasource.
    - mariadb : Documentation in https://github.com/wildfly-extras/wildfly-datasources-galleon-pack
    - mssqlserver : Documentation in https://github.com/wildfly-extras/wildfly-datasources-galleon-pack
    - mysql : Documentation in https://github.com/wildfly-extras/wildfly-datasources-galleon-pack
    - oracle : Documentation in https://github.com/wildfly-extras/wildfly-datasources-galleon-pack
    - postgresql : Documentation in https://github.com/wildfly-extras/wildfly-datasources-galleon-pack
  - jaxrs add-ons:
    - openapi : Support for MicroProfile OpenAPI.
  - lra add-ons:
    - lra-coordinator : Support for MicroProfile LRA Coordinator.
  - management add-ons:
    - hal-web-console : Management Web console. Make sure to add an initial user.
    - jdr : Support for the JBoss Diagnostic Reporting (JDR).
    - wildfly-cli : Server command line tools: jboss-cli, add-user, elytron-tool.
  - observability add-ons:
    - health : Support for runtime health checks.
    - metrics : Support for base metrics from the WildFly Management Model and JVM MBeans.
    - micrometer : Support for Micrometer.
  - rpc add-ons:
    - grpc : Support for gRPC.
    - iiop : Support for IIOP.
  - security add-ons:
    - ssl : Support for the Undertow HTTPS listener.
  - web add-ons:
    - load-balancer : Support for Undertow configured as a load balancer.

[INFO] * you could enable profiles:
[INFO]   - ha

利用できるadd-onすべてを確認しようと思うと、WildFly Glow CLIを使うことになりそうです。これは最後に確認します。

WildFly Glow Documentation / WildFly Maven Plugin integration / Adding add-ons

mysqlのadd-onを追加します。

                    <discover-provisioning-info>
                        <version>32.0.1.Final</version>
                        <add-ons>
                            <add-on>mysql</add-on>
                        </add-ons>
                    </discover-provisioning-info>

もう1度パッケージング。

$ mvn package

今度は成功しますが、警告も含まれています。

[INFO] --- wildfly:5.0.0.Final:package (default) @ wildfly-glow-example ---
[INFO] Glow is scanning...
[INFO] Glow scanning DONE.
[INFO] context: bare-metal
[INFO] enabled profile: none
[INFO] galleon discovery
[INFO] - feature-packs
   org.wildfly:wildfly-galleon-pack:32.0.1.Final
   org.wildfly:wildfly-datasources-galleon-pack:8.0.0.Final
- layers
   ee-core-profile-server
   jaxrs
   jpa
   mysql-datasource

[INFO] enabled add-ons
[INFO] - mysql : Documentation in https://github.com/wildfly-extras/wildfly-datasources-galleon-pack

[INFO] identified fixes
[INFO] * unbound datasources error: java:jboss/datasources/MySqlDs is fixed
  - add-on mysql fixes the problem but you need to set the strongly suggested configuration.

[WARNING] strongly suggested configuration at runtime
[WARNING]
mysql-datasource environment variables:
 - MYSQL_DATABASE=Defines the database name to be used in the datasource’s `connection-url` property.
 - MYSQL_JNDI=java:jboss/datasources/MySqlDs
 - MYSQL_PASSWORD=Defines the password for the datasource.
 - MYSQL_USER=Defines the username for the datasource.
[WARNING]
[INFO] Some suggestions have been found. You could enable suggestions with the <suggest>true</suggest> option.

これは、実行時に必要な情報を環境変数で指定する必要があることを示しているようです。

[WARNING] strongly suggested configuration at runtime
[WARNING]
mysql-datasource environment variables:
 - MYSQL_DATABASE=Defines the database name to be used in the datasource’s `connection-url` property.
 - MYSQL_JNDI=java:jboss/datasources/MySqlDs
 - MYSQL_PASSWORD=Defines the password for the datasource.
 - MYSQL_USER=Defines the username for the datasource.

WildFly Glow Documentation / WildFly Maven Plugin integration / Configuring add-ons

実際、環境変数を指定せずに起動しても失敗します。

20:24:34,413 ERROR [org.jboss.as.controller.management-operation] (Controller Boot Thread) WFLYCTL0013: Operation ("deploy") failed - address: ([("deployment" => "ROOT.war")]) - failure description: {
    "WFLYCTL0412: Required services that are not installed:" => ["jboss.naming.context.java.jboss.datasources.MySqlDs"],
    "WFLYCTL0180: Services with missing/unavailable dependencies" => [
        "service jboss.persistenceunit.\"ROOT.war#sample.pu\" is missing [jboss.naming.context.java.jboss.datasources.MySqlDs]",
        "service jboss.persistenceunit.\"ROOT.war#sample.pu\".__FIRST_PHASE__ is missing [jboss.naming.context.java.jboss.datasources.MySqlDs]"
    ]
}
20:24:34,414 ERROR [org.jboss.as.controller.management-operation] (Controller Boot Thread) WFLYCTL0013: Operation ("add") failed - address: ([
    ("subsystem" => "datasources"),
    ("data-source" => "MySQLDS")
]) - failure description: "WFLYCTL0211: Cannot resolve expression '${org.wildfly.datasources.mysql.user-name,env.MYSQL_USER,env.OPENSHIFT_MYSQL_DB_USERNAME}'"

というわけで、環境変数を設定。

$ export MYSQL_DATASOURCE=MySqlDs
$ export MYSQL_JNDI=java:jboss/datasources/MySqlDs
$ export MYSQL_URL='jdbc:mysql://172.17.0.2:3306/practice?characterEncoding=utf-8&connectionCollation=utf8mb4_0900_bin'
$ export MYSQL_USER=kazuhira
$ export MYSQL_PASSWORD=password

起動。

$ java -jar target/wildfly-glow-example-0.0.1-SNAPSHOT-server-bootable.jar

今度は動作するようになります。

$ curl -XPOST -H 'Content-Type: application/json' localhost:8080/books -d '{"isbn": "978-4774183169", "title": "パーフェクト Java EE", "price": 3520}'
{"isbn":"978-4774183169","price":3520,"title":"パーフェクト Java EE"}


$ curl localhost:8080/books
[{"isbn":"978-4774183169","price":3520,"title":"パーフェクト Java EE"}]


$ curl localhost:8080/books/978-4774183169
{"isbn":"978-4774183169","price":3520,"title":"パーフェクト Java EE"}

OKですね。

ちなみに、JARのサイズはこうなりました。

$ ll -h target/wildfly-glow-example-0.0.1-SNAPSHOT-server-bootable.jar
-rw-rw-r-- 1 xxxxx xxxxx 112M  6月  1 20:22 target/wildfly-glow-example-0.0.1-SNAPSHOT-server-bootable.jar

クラスタリングしてみる

最後は、クラスタリングしてみましょう。

こちらを参照して

WildFly Glow Documentation / WildFly Maven Plugin integration / HA (High Availability) support

profileにhaを指定するだけです。

                    <discover-provisioning-info>
                        <version>32.0.1.Final</version>
                        <profile>ha</profile>
                        <add-ons>
                            <add-on>mysql</add-on>
                        </add-ons>
                    </discover-provisioning-info>

なのですが、これだけだとクラスタリングできているかどうかわからないので、HttpSessionを使うプログラムを書くことにします。

アクセスに応じてカウントアップするJAX-RSリソースクラス。

src/main/java/org/littlewings/wildfly/glow/SessionResource.java

package org.littlewings.wildfly.glow;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

@ApplicationScoped
@Path("session")
public class SessionResource {
    @Inject
    private HttpServletRequest request;

    @GET
    @Path("counter")
    @Produces(MediaType.TEXT_PLAIN)
    public int incrementCounter() {
        HttpSession session = request.getSession();

        Integer counter = (Integer) session.getAttribute("counter");

        if (counter == null) {
            counter = 0;
        }

        counter++;

        session.setAttribute("counter", counter);

        return counter;
    }
}

web.xmlを作成して、distributableを定義します。

src/main/webapp/WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee
                             https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
         version="6.0">
    <distributable/>
</web-app>

パッケージング。

$ mvn package

結果。

[INFO] --- wildfly:5.0.0.Final:package (default) @ wildfly-glow-example ---
[INFO] Glow is scanning...
[INFO] Glow scanning DONE.
[INFO] context: bare-metal
[INFO] enabled profile: ha
[INFO] galleon discovery
[INFO] - feature-packs
   org.wildfly:wildfly-galleon-pack:32.0.1.Final
   org.wildfly:wildfly-datasources-galleon-pack:8.0.0.Final
- layers
   ee-core-profile-server
   jaxrs
   mysql-datasource
   jpa-distributed
   web-clustering

[INFO] enabled add-ons
[INFO] - mysql : Documentation in https://github.com/wildfly-extras/wildfly-datasources-galleon-pack

[INFO] identified fixes
[INFO] * unbound datasources error: java:jboss/datasources/MySqlDs is fixed
  - add-on mysql fixes the problem but you need to set the strongly suggested configuration.

[WARNING] strongly suggested configuration at runtime
[WARNING]
mysql-datasource environment variables:
 - MYSQL_DATABASE=Defines the database name to be used in the datasource’s `connection-url` property.
 - MYSQL_JNDI=java:jboss/datasources/MySqlDs
 - MYSQL_PASSWORD=Defines the password for the datasource.
 - MYSQL_USER=Defines the username for the datasource.
[WARNING]
[INFO] Some suggestions have been found. You could enable suggestions with the <suggest>true</suggest> option.

Profileがhaになり

[INFO] enabled profile: ha

Galleonレイヤーにweb-clustering、jpa-distributedが追加されました。

[INFO] - feature-packs
   org.wildfly:wildfly-galleon-pack:32.0.1.Final
   org.wildfly:wildfly-datasources-galleon-pack:8.0.0.Final
- layers
   ee-core-profile-server
   jaxrs
   mysql-datasource
   jpa-distributed
   web-clustering

あとは起動すればいいのですが、ひとつ目のインスタンスは問題ありません。

$ java -jar target/wildfly-glow-example-0.0.1-SNAPSHOT-server-bootable.jar

2つ目のインスタンスはそのままだとポートが重複するのでずらしたいです。

ヘルプを見てみましょう。

$ java -jar target/wildfly-glow-example-0.0.1-SNAPSHOT-server-bootable.jar --help

Usage: java -jar <bootable jar> [args...]
where args include:
    --deployment=<value>                Path to deployment artifact
                                        (war,jar,ear or exploded deployment
                                        dir) to deploy in hollow jar


    -b=<value>                          Set system property jboss.bind.address
                                        to the given value


    -b<interface>=<value>               Set system property
                                        jboss.bind.address.<interface> to the
                                        given value


    -D<name>[=<value>]                  Set a system property


    --cli-script=<value>                Path to a CLI script to execute when
                                        starting the Bootable JAR


    --display-galleon-config            Display the content of the Galleon
                                        configuration used to build this
                                        bootable JAR


    --help                              Display this message and exit


    --install-dir=<value>               Path to directory in which the server
                                        is installed. By default the server is
                                        installed in TEMP directory.


    --properties=<url>                  Load system properties from the given
                                        url


    -secmgr                             Activate the SecurityManager


    --stability=<value>                 Runs the server using a specific
                                        stability level. Possible values:
                                        [default, community, preview,
                                        experimental], Default = community


    -S<name>[=<value>]                  Set a security property


    -u=<value>                          Set system property
                                        jboss.default.multicast.address to the
                                        given value


    --version                           Print version and exit


    --yaml=[<paths>], -y=[<paths>]      The yaml configuration files for
                                        customizing the configuration. Paths
                                        can be absolute, relative to the
                                        current execution directory or relative
                                        to the standalone configuration
                                        directory.

というわけで、-Djboss.socket.binding.port-offsetをつけて起動します。

$ java -jar target/wildfly-glow-example-0.0.1-SNAPSHOT-server-bootable.jar -Djboss.socket.binding.port-offset=100

アプリケーションの起動引数として-Dを受け付けるようになっているので、この指定で大丈夫です。

    -D<name>[=<value>]                  Set a system property

なお、起動前にMySQL向けの環境変数を指定することをお忘れなく…。

$ export MYSQL_DATASOURCE=MySqlDs
$ export MYSQL_JNDI=java:jboss/datasources/MySqlDs
$ export MYSQL_URL='jdbc:mysql://172.17.0.2:3306/practice?characterEncoding=utf-8&connectionCollation=utf8mb4_0900_bin'
$ export MYSQL_USER=kazuhira
$ export MYSQL_PASSWORD=password

さらに今回のアプリケーションの設定で複数のノードを起動すると、ノードが起動するたびに都度テーブルがdrop&createされるので
ご注意を…。

確認してみます。ひとつ目のノードと2つ目のノードに交互にアクセスします。

$ curl -c cookie.txt -b cookie.txt localhost:8080/session/counter
1


$ curl -c cookie.txt -b cookie.txt localhost:8180/session/counter
2


$ curl -c cookie.txt -b cookie.txt localhost:8080/session/counter
3


$ curl -c cookie.txt -b cookie.txt localhost:8180/session/counter
4

OKですね。

ちなみに、サイズはJAX-RS+JPAの時より6MB大きくなった程度です。

$ ll -h target/wildfly-glow-example-0.0.1-SNAPSHOT-server-bootable.jar
-rw-rw-r-- 1 xxxxx xxxxx 118M  6月  1 21:18 target/wildfly-glow-example-0.0.1-SNAPSHOT-server-bootable.jar

その他の機能

今回は使いませんでしたが、追加するGalleonレイヤーを明示的に指定したり、特定の対象をdiscover-provisioning-infoで検出する対象外に
設定できるようです。

追加のレイヤーを設定できるといっても、なにが選択できるかわかりませんね…。

WildFly Maven Pluginのpackageゴールでの記載を見ると、JNDIを使うGalleonレイヤーみたいですね…。

layersForJndi: List of Galleon layers required by some JNDI calls located in your application.

WildFly Maven Plugin – wildfly:package

選ぶとしたら、ここからということになるんでしょうね。

Bootable JAR Guide / Galleon configuration / WildFly Layers

また、verboseを指定することで、選択したGalleonレイヤーなどの情報を表示できます。

                    <discover-provisioning-info>
                        <version>32.0.1.Final</version>
                        <profile>ha</profile>
                        <add-ons>
                            <add-on>mysql</add-on>
                        </add-ons>
                        <verbose>true</verbose>
                    </discover-provisioning-info>

WildFly Glow Documentation / WildFly Maven Plugin integration / Printing matching rules

今回だと、こんな結果になります。

[INFO] --- wildfly:5.0.0.Final:package (default) @ wildfly-glow-example ---
[INFO] Glow is scanning...
[INFO] Glow scanning DONE.
[INFO] context: bare-metal
[INFO] enabled profile: ha
[INFO] galleon discovery
[INFO] - feature-packs
   org.wildfly:wildfly-galleon-pack:32.0.1.Final
   org.wildfly:wildfly-datasources-galleon-pack:8.0.0.Final
- layers
   ee-core-profile-server
   jaxrs
   mysql-datasource
   jpa-distributed
   web-clustering

[INFO]
layers inclusion rules
* ee-core-profile-server
  - BASE_LAYER
* jaxrs
  - JAVA_TYPE: [jakarta.ws.rs.core.*]
  - ANNOTATION: [jakarta.ws.rs.*]
* mysql-datasource
  - ADD_ON
* jpa-distributed
  - PROFILE_INCLUDED
* web-clustering
  - PROFILE_INCLUDED

[INFO] enabled add-ons
[INFO] - mysql : Documentation in https://github.com/wildfly-extras/wildfly-datasources-galleon-pack

[INFO] identified fixes
[INFO] * unbound datasources error: java:jboss/datasources/MySqlDs is fixed
  - add-on mysql fixes the problem but you need to set the strongly suggested configuration.

この部分ですね。

[INFO]
layers inclusion rules
* ee-core-profile-server
  - BASE_LAYER
* jaxrs
  - JAVA_TYPE: [jakarta.ws.rs.core.*]
  - ANNOTATION: [jakarta.ws.rs.*]
* mysql-datasource
  - ADD_ON
* jpa-distributed
  - PROFILE_INCLUDED
* web-clustering
  - PROFILE_INCLUDED

WildFly Glow CLIで利用できるadd-onの一覧を確認する

最後にWildFly Glow CLIを使って、利用できるadd-onの一覧を確認してみましょう。

WildFly Glow CLIをダウンロードして展開。

$ curl -LO https://github.com/wildfly/wildfly-glow/releases/download/1.0.6.Final/wildfly-glow-1.0.6.Final.zip
$ unzip wildfly-glow-1.0.6.Final.zip

add-onの一覧を表示。

$ wildfly-glow-1.0.6.Final/wildfly-glow show-add-ons
Wildfly Glow is retrieving add-ons...
* clustering add-ons:
 - infinispan: Brings in infinispan caches.
 - jgroups-aws: Brings in JBoss Modules modules required to configure the 'aws.S3_PING' discovery protocol.
 - mod_cluster: Support for mod_cluster integration.
* database add-ons:
 - h2-database: Support for an H2 datasource.
 - mariadb (supported by openshift/mariadb deployer): Documentation in https://github.com/wildfly-extras/wildfly-datasources-galleon-pack
 - mssqlserver: Documentation in https://github.com/wildfly-extras/wildfly-datasources-galleon-pack
 - mysql (supported by openshift/mysql deployer): Documentation in https://github.com/wildfly-extras/wildfly-datasources-galleon-pack
 - oracle: Documentation in https://github.com/wildfly-extras/wildfly-datasources-galleon-pack
 - postgresql (supported by openshift/postgresql deployer): Documentation in https://github.com/wildfly-extras/wildfly-datasources-galleon-pack
* ejb add-ons:
 - http-invoker: Support for invoking Jakarta Enterprise Beans over HTTP.
* jaxrs add-ons:
 - openapi: Support for MicroProfile OpenAPI.
* jsf add-ons:
 - myfaces: Support for MyFaces.
* lra add-ons:
 - lra-coordinator: Support for MicroProfile LRA Coordinator.
* management add-ons:
 - hal-web-console: Management Web console. Make sure to add an initial user.
 - jdr: Support for the JBoss Diagnostic Reporting (JDR).
 - wildfly-cli: Server command line tools: jboss-cli, add-user, elytron-tool.
* messaging add-ons:
 - embedded-activemq: Support for an embedded Apache Activemq Artemis Jakarta Messaging broker.
 - remote-activemq: Support for connections to a remote Apache Activemq Artemis Jakarta Messaging broker.
* observability add-ons:
 - health: Support for runtime health checks.
 - metrics: Support for base metrics from the WildFly Management Model and JVM MBeans.
 - micrometer: Support for Micrometer.
* reactive-messaging add-ons:
 - amqp: Support for the MicroProfile Reactive Messaging AMQP connector.
 - kafka: Support for the MicroProfile Reactive Messaging Kafka connector.
* rpc add-ons:
 - grpc: Support for gRPC.
 - iiop: Support for IIOP.
* security add-ons:
 - ssl: Support for the Undertow HTTPS listener.
* web add-ons:
 - load-balancer: Support for Undertow configured as a load balancer.

Add-ons can be set using the --add-ons=<list of add-ons> option of the scan command

おわりに

WildFlyのプロビジョニングをWildFly Glowの機能を組み込んだWildFly Maven Pluginで試してみました。

前にGalleonレイヤーを使ってBootable JARを作ったりしていたからもしれませんが、割と簡単に使えましたね。

feature-packやGalleonレイヤーの指定など、今までそこそこ面倒な部分もあったのでWildFlyのプロビジョニングの際に手段として
押さえておくと便利かもしれません。