これは、なにをしたくて書いたもの?
WildFly Bootable JARを見ていると、Galleonというものが出てきます。
- WildFly bootable JAR application development / Galleon configuration / WildFly Layers
- WildFly Bootable JAR Documentation / Composing custom server with Galleon layers / Specifying the WildFly server version to use / Providing a list of Galleon feature-packs
ここで選択できるGalleon layer、Galleon feature-packというものを、もう少し見ておきたいなと思いまして。
指定できるGalleon layerにどんなものが含まれているのか、Galleon feature-packで指定できるものは?というのと、WildFly Bootable JARで
どのようなものが指定できるのか?というあたりが知りたいと思って見てみた動機です。
結論
まず、WildFly Bootable JARで指定できるWildFly Galleon layerは、以下に書かれている「Foundational Galleon layers」および
「Basic Galleon Layers」の中から選択します。
WildFly bootable JAR application development / Galleon configuration / WildFly Layers
WildFly Galleon feature-packは、WildFly extrasにある以下の3つですね。
- GitHub - wildfly-extras/wildfly-cloud-galleon-pack: Galleon feature-pack for WildFly on the Cloud
- GitHub - wildfly-extras/wildfly-datasources-galleon-pack: WildFly Feature Pack for DataSources
- GitHub - wildfly-extras/wildfly-mp-reactive-feature-pack: A galleon feature pack to add the MicroProfile reactive subsystems to your WildFly installation
WildFlyのorganizationには、WildFly Bootable JARで指定するようなfeature-packはなさそうです。
Galleon
Galleonというのは、ひとつ以上の製品(またはコンポーネント)で構成されたソフトウェアディストリビューションを作成および
メンテナンスするために設計されたプロビジョニングツールです。
Galleon is a provisioning tool designed to create and maintain software distributions that consist of one or more products (or components).
Galleonツールを使用して、インストールまたはアンインストールできるソフトウェア(プロジェクト、製品、コンポーネントなど)の
単位を「feature-pack」と呼びます。feature-packはzipアーカイブで、feature-packの作成者によってMavenリポジトリなどにデプロイされ、
Galleonツールを介してユーザーが利用します。
Feature-pack represents a released unit of software (project, product, component, etc) that can be installed or uninstalled using Galleon tools. Feature-packs are ZIP archives that are normally deployed by the feature-pack producers to artifact repositories (such as Maven) where they can be discovered and consumed by users using Galleon tools.
Galleon Documentation / Feature-packs
Galleon feature-packの仕組みを使うと、WildFlyを自分で拡張することもできるようです。
自分でfeature-packを作成する場合は、こちらのドキュメントを参照。
WildFly Galleon Plugins Documentation
Galleonについては、以下のブログエントリーを見るのも良さそうです。
Ship Your WildFly Additions via Galleon Feature Packs
Galleonには、以下のコアとなる概念があります。
- package
- feature、feature-group
- WildFlyの構成にサブシステム構成を追加する
- feature-groupには、featureやfeature-groupを追加できる
- 他のfeatureやpackageへの依存関係を持っていることもある
- layer
- サーバーを細かい部品に分解したもので、利用者が必要なものを選択できる
そして、feature-packはpackage、feature、feature-group、layerをまとめたものです。
WildFlyのfeature-packは、以下の3つがあります。
- Core feature-pack
- Servlet feature-pack
- Full feature-pack
Jakarta EE 9用、
WildFly extraもあります。
- GitHub - wildfly-extras/wildfly-cloud-galleon-pack: Galleon feature-pack for WildFly on the Cloud
- GitHub - wildfly-extras/wildfly-datasources-galleon-pack: WildFly Feature Pack for DataSources
- GitHub - wildfly-extras/wildfly-mp-reactive-feature-pack: A galleon feature pack to add the MicroProfile reactive subsystems to your WildFly installation
ここまで見ているとわかるかと思いますが、今回はひたすらWildFly Bootable JARと絡めて書き進めるものの、GalleonはWildFly Bootable JARの
ための機能、というわけではありません。
ただ、WildFly Bootable JARを作成する時の依存関係を取捨選択するところで登場することが多いのかな、という気もしますが、
どうなのでしょうね。
まあ、今回はWildFly Bootable JARで使う、という目線で書いていきます。
WildFly Galleon layers
WildFly Bootable JARを作成する時は、主にWildFly Galleon layersを指定します。
WildFly Bootable JAR Documentation
Galleon layersについては、「Galleon Provisioning Guide」にも「Bootable JAR Guide」と同じことが書かれています。
WildFly Bootable JARを作成する際には、特定のGalleon layerを選択することになります。選択しない場合は、standalone-microprofile.xml
と
同等の構成になるようです。
If you decide not to specify Galleon layers, a server containing all MicroProfile subsystems is provisioned. (The server configuration is identical to the standalone-microprofile.xml configuration in the traditional WildFly server zip.)
WildFly bootable JAR application development / Galleon configuration
ドキュメントを見ると、「使いたいWildFly Galleon feature-packを決めたら、サーバーの構成に使用するWildFly Galleon layerを選択する」
ということになっています。
Once you have identified a WildFly Galleon feature-pack, you need to select a set of WildFly Layers that are used to compose the server.
WildFly bootable JAR application development / Galleon configuration
layerの説明をもう少し見てみましょう。
layerとはサーバーの機能や機能の集合を指す名前のようです。拡張機能、サブシステム、インターフェース、モジュールなどが含まると
されています。
A Galleon layer is a name that identifies a server capability (e.g.: jaxrs, ejb, microprofile-config, jpa) or an aggregation of such capabilities. A layer captures a server capability in the form of:
- A piece of server XML configuration (e.g.: extension, configured subsystem, interfaces) that describes the capability.
- A set of modules and other filesystem content that implements the capability.
WildFly bootable JAR application development / Galleon configuration / WildFly Layers
WildFly Galleon layerには、「Foundational Galleon layers」と「Basic Galleon Layers」と呼ばれる2つのlayer定義があります。
どのようなlayerがあるのかも、リストアップされています。
- WildFly bootable JAR application development / Galleon configuration / WildFly Layers / Foundational Galleon layers
- WildFly bootable JAR application development / Galleon configuration / WildFly Layers / Basic Galleon Layers
layerには依存関係があり、あるlayerを指定すると依存しているlayerも引き込まれます。layerの除外もできます。
基本的なlayerが、「Basic Galleon Layers」としてドキュメントにまとめられています。一方で、よく使うものをまとめたlayerとして、
「Foundational Galleon layers」があります。
たとえば、Basic Galleon Layersに「jaxrs」というlayerがありますが、この依存layerとして「web-server」と
「microprofile-rest-client(オプション)」が含まれます。
一方でFoundational Galleon layersの「jaxrs-server」を選択すると、依存するlayerとして「bean-validation」、「cdi」、「datasources-web-server」、
「jaxrs」、「jpa」とそこそこ多めのlayerが含まれることになります。
まずはFoundational Galleon layersからlayerを選び、より細かく選びたい場合はBasic Galleon Layersから選択するという感じに
なるのでしょう。
WildFly Bootable JARを作成する際にWildFly Galleon layer、WildFly Galleon feature-packを指定するには
WildFly Bootable JARのドキュメントを見ると、
WildFly Bootable JAR Documentation
layerとfeature-packそれぞれ指定できることがわかります。
- WildFly Bootable JAR Documentation / Composing custom server with Galleon layers / Specifying the set of Galleon layers to use
- WildFly Bootable JAR Documentation / Composing custom server with Galleon layers / Specifying the WildFly server version to use / Providing WildFly Galleon feature-pack location
layerを指定するかfeature-packを指定するかで書き方が変わります。
layerのみを使う場合。
<plugin> <groupId>org.wildfly.plugins</groupId> <artifactId>wildfly-jar-maven-plugin</artifactId> <version>...</version> <configuration> <feature-pack-location>wildfly@maven(org.jboss.universe:community-universe)</feature-pack-location> <layers> <layer>jaxrs-server</layer> </layers> </configuration> 〜省略〜 </plugin>
feature-packを使う場合。
<plugin> <groupId>org.wildfly.plugins</groupId> <artifactId>wildfly-jar-maven-plugin</artifactId> <version>...</version> <configuration> <feature-packs> <feature-pack> <location>wildfly@maven(org.jboss.universe:community-universe)#26.1.0.0.Final</location> </feature-pack> <feature-pack> <groupId>org.wildfly</groupId> <artifactId>wildfly-datasources-galleon-pack</artifactId> <version>...</version> </feature-pack> </feature-packs> </configuration> 〜省略〜 </plugin>
feature-packを使う場合は、feature-pack-location
の表現方法が変わります。
両方使う場合。
<plugin> <groupId>org.wildfly.plugins</groupId> <artifactId>wildfly-jar-maven-plugin</artifactId> <version>...</version> <configuration> <feature-packs> <feature-pack> <location>wildfly@maven(org.jboss.universe:community-universe)#26.1.0.0.Final</location> </feature-pack> <feature-pack> <groupId>org.wildfly</groupId> <artifactId>wildfly-datasources-galleon-pack</artifactId> <version>...</version> </feature-pack> </feature-packs> <layers> <layer>jaxrs-server</layer> <layer>mysql-datasource</layer> <layer>management</layer> </layers> </configuration> 〜省略〜 </plugin>
WildFly Galleon layer
ここまで見ていると、layerやfeature-packの種類はわかってきたものの、その定義内容についても見てみたくなりますね。
まず、layerからいきましょう。
layerは、こちらに定義があります。
- https://github.com/wildfly/wildfly-core/tree/18.1.1.Final/core-feature-pack/galleon-common/src/main/resources/layers/standalone
- https://github.com/wildfly/wildfly/tree/26.1.1.Final/servlet-feature-pack/galleon-common/src/main/resources/layers/standalone
- https://github.com/wildfly/wildfly/tree/26.1.1.Final/ee-feature-pack/galleon-common/src/main/resources/layers/standalone
たとえば、Foundational Galleon layersに書かれていた「jaxrs-server」layer。
<?xml version="1.0" ?> <layer-spec xmlns="urn:jboss:galleon:layer-spec:1.0" name="jaxrs-server"> <dependencies> <layer name="datasources-web-server"/> <!-- cloud-server depends on jaxrs-server, jaxrs could be excluded from cloud-server, this is why jaxrs is an optional dependency --> <layer name="jaxrs" optional="true"/> <layer name="bean-validation" optional="true"/> <layer name="cdi" optional="true"/> <layer name="jpa" optional="true"/> </dependencies> </layer-spec>
他のlayerに依存していることがわかります。
続いて、Basic Galleon Layersに書かれていた「jaxrs」 layer。
<?xml version="1.0" ?> <layer-spec xmlns="urn:jboss:galleon:layer-spec:1.0" name="jaxrs"> <dependencies> <layer name="web-server"/> </dependencies> <feature-group name="jaxrs"/> </layer-spec>
他のlayerに依存しているのと、「feature-group」も参照しています。
他も見てみましょう。「cdi」layerだと、featureも参照しています。
<?xml version="1.0" ?> <layer-spec xmlns="urn:jboss:galleon:layer-spec:1.0" name="cdi"> <dependencies> <layer name="base-server"/> <layer name="bean-validation" optional="true"/> </dependencies> <feature spec="subsystem.weld"/> </layer-spec>
ざっくり、layerの定義を見ると依存しているものが具体的にわかりそうですね。
このあたりの定義内容は、Galleonのドキュメントを見るのが良さそうです。
ちなみに、WildFly Bootable JARにlayerを指定すればよいという話までであれば、このブログエントリーはここまで読めばもういいのではと
思ったりします。
以下、延々と調べたことや補足が続きます。
Galleon feature-packの説明を読む
Galleon layerの構成内容は、feature-packの構成の説明を見るのがよさそうです。
Galleon Documentation / Generic configuration model
こちらを見ると、feature、feature-group、layerともにfeature-packの構成要素ということになっています。
- Galleon Documentation / Generic configuration model / Features
- Galleon Documentation / Generic configuration model / Feature groups
- Galleon Documentation / Generic configuration model / Layers
最初の方にも書きましたが、feature-groupはfeatureを含めたり、別のfeature-groupを含めたりできるものです。
一方で、layerについては「layer自体、または他のlayerと組み合わせて最終的な構成を作成するために使用できる特定の構成フレーバーを
表すことを目的としている」そうです。
A layer is meant to represent a certain configuration flavor that can be used on its own or in combination with other layers to produce the final configuration.
両者、似たような印象を受けるのですが、feature-groupとlayerの違いはこちらに書かれています。
Galleon Documentation / Generic configuration model / Layers / Layers vs feature groups
feature-groupの定義
feature-groupは、このあたりに定義がありますね。
- https://github.com/wildfly/wildfly-core/tree/18.1.1.Final/core-feature-pack/galleon-common/src/main/resources/feature_groups
- https://github.com/wildfly/wildfly/tree/26.1.1.Final/servlet-feature-pack/galleon-feature-pack/src/main/resources/feature_groups
- https://github.com/wildfly/wildfly/tree/26.1.1.Final/ee-feature-pack/galleon-common/src/main/resources/feature_groups
- https://github.com/wildfly/wildfly/tree/26.1.1.Final/ee-feature-pack/galleon-content/src/main/resources/feature_groups
たとえば、「jaxrs」feature group。
<?xml version="1.0" encoding="UTF-8"?> <feature-group-spec name="jaxrs" xmlns="urn:jboss:galleon:feature-group:1.0"> <feature spec="subsystem.jaxrs"/> </feature-group-spec>
「undertow-servlet」feature-group。
<?xml version="1.0" encoding="UTF-8"?> <feature-group-spec name="undertow-servlet" xmlns="urn:jboss:galleon:feature-group:1.0"> <!-- ejb over http and servlet-container --> <feature spec="subsystem.undertow"> <feature spec="subsystem.undertow.server"> <param name="server" value="default-server" /> <feature spec="subsystem.undertow.server.host"> <param name="host" value="default-host" /> <param name="alias" value="[localhost]"/> <feature spec="subsystem.undertow.server.host.setting.http-invoker"/> <!-- TODO Should this be here? --> </feature> </feature> <feature spec="subsystem.undertow.servlet-container"> <param name="servlet-container" value="default" /> <feature spec="subsystem.undertow.servlet-container.setting.jsp"/> <feature spec="subsystem.undertow.servlet-container.setting.websockets"> <unset param="buffer-pool" /> <unset param="worker" /> </feature> </feature> </feature> </feature-group-spec>
サブシステムへの参照を含んでいそうなことはわかりますね。
WildFlyのstandalone.xmlなどの構成を見る
こんな感じで、layerやfeature-groupを見ていくと、WildFlyの機能の構成がなんとなくわかりそうですね。
実際、standalone.xml
等は以下をベースに作られているようです。
- https://github.com/wildfly/wildfly/tree/26.1.1.Final/ee-feature-pack/galleon-content/src/main/resources/configs
- https://github.com/wildfly/wildfly/tree/26.1.1.Final/servlet-feature-pack/galleon-common/src/main/resources/configs
- https://github.com/wildfly/wildfly/tree/26.1.1.Final/galleon-pack/galleon-content/src/main/resources/configs
たとえば、standalone-ha.xml
。
<?xml version="1.0" ?> <config xmlns="urn:jboss:galleon:config:1.0" name="standalone-ha.xml" model="standalone"> <feature-group name="standalone-ha"/> </config>
<?xml version="1.0" encoding="UTF-8"?> <feature-group-spec name="standalone-ha" xmlns="urn:jboss:galleon:feature-group:1.0"> <feature spec="server-root"> <param name="server-root" value="/" /> </feature> <feature-group name="interfaces"/> <feature spec="interface"> <param name="interface" value="private"/> <param name="inet-address" value="${jboss.bind.address.private:127.0.0.1}"/> </feature> <feature spec="socket-binding-group"> <param name="socket-binding-group" value="standard-sockets" /> <param name="port-offset" value="${jboss.socket.binding.port-offset:0}"/> <param name="default-interface" value="public"/> <feature-group name="standalone-sockets"/> <feature-group name="ha-sockets"/> </feature> <feature-group name="management-audit"/> <feature-group name="management-interfaces"/> <feature-group name="access-control"/> <feature-group name="health"/> <feature-group name="metrics" /> <feature-group name="servlet-standalone-profile"/> <feature-group name="basic-ha-profile"/> </feature-group-spec>
<?xml version="1.0" encoding="UTF-8"?> <feature-group-spec name="standalone-ha" xmlns="urn:jboss:galleon:feature-group:1.0"> <origin name="org.wildfly:wildfly-ee-galleon-pack"> <feature-group name="standalone-ha"/> </origin> <feature spec="subsystem.microprofile-config-smallrye"/> <feature spec="subsystem.microprofile-jwt-smallrye"/> <feature spec="subsystem.elytron-oidc-client"/> <feature-group name="microprofile-opentracing-jaeger"/> </feature-group-spec>
なんとなく、どんなfeature-group、featureで構成するか読めそうな気がしますね。
WildFly Galleon feature-packとWildFly extras feature-pack
ところで、feature-packという言葉が全然出てきませんね。
WildFly Galleon feature-packは、以下があります。
これらは、Mavenリポジトリーにデプロイはされているものの、WildFlyサーバーのディストリビューションに含まれているわけでは
ありません。
というか、これらの範囲はWildFlyサーバーのディストリビューションの範囲そのものなので、これをWildFly Bootable JARのfeature-packに
指定しようものならWildFlyサーバーをそのまま使えばいいのでは?という感じになるでしょうね。
また、feature-packはWildFly extrasというorganizationでも提供されています。
以下の4つです(実質3つ)。
- GitHub - wildfly-extras/wildfly-cloud-galleon-pack: Galleon feature-pack for WildFly on the Cloud
- GitHub - wildfly-extras/wildfly-datasources-galleon-pack: WildFly Feature Pack for DataSources
- GitHub - wildfly-extras/wildfly-mp-reactive-feature-pack: A galleon feature pack to add the MicroProfile reactive subsystems to your WildFly installation
- WildFlyに統合済み
- GitHub - wildfly-extras/wildfly-grpc-feature-pack: WildFly gRPC feature pack
WildFly提供外のfeature-packを使う場合を除き、WildFly Bootable JARのfeature-packに指定するとしたら、これらですね。
featureは?
ここまで、まったく出てこなかったのがfeatureです。WildFlyのリポジトリーのどこを見てもfeatureの定義は見当たりません。
どうやら、自動生成しているみたいです。
<generate-feature-specs> <extensions> <standalone> <extension>org.jboss.as.deployment-scanner</extension> <extension>org.jboss.as.jmx</extension> <extension>org.jboss.as.logging</extension> <extension>org.jboss.as.remoting</extension> <extension>org.wildfly.extension.core-management</extension> <extension>org.wildfly.extension.discovery</extension> <extension>org.wildfly.extension.elytron</extension> <extension>org.wildfly.extension.io</extension> <extension>org.wildfly.extension.request-controller</extension> <extension>org.wildfly.extension.security.manager</extension> </standalone> <domain> <extension>org.jboss.as.jmx</extension> <extension>org.jboss.as.logging</extension> <extension>org.jboss.as.remoting</extension> <extension>org.wildfly.extension.core-management</extension> <extension>org.wildfly.extension.discovery</extension> <extension>org.wildfly.extension.elytron</extension> <extension>org.wildfly.extension.io</extension> <extension>org.wildfly.extension.request-controller</extension> <extension>org.wildfly.extension.security.manager</extension> </domain> <host> <extension>org.jboss.as.jmx</extension> <extension>org.wildfly.extension.core-management</extension> <extension>org.wildfly.extension.discovery</extension> <extension>org.wildfly.extension.elytron</extension> </host> </extensions> </generate-feature-specs>
<generate-feature-specs> <extensions> <standalone> <extension>org.jboss.as.deployment-scanner</extension> <extension>org.jboss.as.ee</extension> <extension>org.jboss.as.jmx</extension> <extension>org.jboss.as.logging</extension> <extension>org.jboss.as.naming</extension> <extension>org.jboss.as.remoting</extension> <extension>org.jboss.as.security</extension> <extension>org.wildfly.extension.core-management</extension> <extension>org.wildfly.extension.discovery</extension> <extension>org.wildfly.extension.elytron</extension> <extension>org.wildfly.extension.io</extension> <extension>org.wildfly.extension.request-controller</extension> <extension>org.wildfly.extension.security.manager</extension> <extension>org.wildfly.extension.undertow</extension> </standalone> <domain> <extension>org.jboss.as.ee</extension> <extension>org.jboss.as.jmx</extension> <extension>org.jboss.as.logging</extension> <extension>org.jboss.as.naming</extension> <extension>org.jboss.as.remoting</extension> <extension>org.jboss.as.security</extension> <extension>org.wildfly.extension.core-management</extension> <extension>org.wildfly.extension.discovery</extension> <extension>org.wildfly.extension.elytron</extension> <extension>org.wildfly.extension.io</extension> <extension>org.wildfly.extension.request-controller</extension> <extension>org.wildfly.extension.security.manager</extension> <extension>org.wildfly.extension.undertow</extension> </domain> <host> <extension>org.jboss.as.jmx</extension> <extension>org.wildfly.extension.core-management</extension> <extension>org.wildfly.extension.discovery</extension> <extension>org.wildfly.extension.elytron</extension> </host> </extensions> </generate-feature-specs>
<generate-feature-specs> <extensions> <standalone> <extension>org.jboss.as.clustering.infinispan</extension> <extension>org.jboss.as.clustering.jgroups</extension> <extension>org.jboss.as.connector</extension> <extension>org.jboss.as.deployment-scanner</extension> <extension>org.jboss.as.ee</extension> <extension>org.jboss.as.ejb3</extension> <extension>org.jboss.as.jaxrs</extension> <extension>org.jboss.as.jdr</extension> <extension>org.jboss.as.jmx</extension> <extension>org.jboss.as.jpa</extension> <extension>org.jboss.as.jsf</extension> <extension>org.jboss.as.jsr77</extension> <extension>org.jboss.as.logging</extension> <extension>org.jboss.as.mail</extension> <extension>org.jboss.as.modcluster</extension> <extension>org.jboss.as.naming</extension> <extension>org.jboss.as.pojo</extension> <extension>org.jboss.as.remoting</extension> <extension>org.jboss.as.sar</extension> <extension>org.jboss.as.security</extension> <extension>org.jboss.as.transactions</extension> <extension>org.jboss.as.webservices</extension> <extension>org.jboss.as.weld</extension> <extension>org.jboss.as.xts</extension> <extension>org.wildfly.extension.batch.jberet</extension> <extension>org.wildfly.extension.bean-validation</extension> <extension>org.wildfly.extension.clustering.singleton</extension> <extension>org.wildfly.extension.clustering.web</extension> <extension>org.wildfly.extension.core-management</extension> <extension>org.wildfly.extension.discovery</extension> <extension>org.wildfly.extension.ee-security</extension> <extension>org.wildfly.extension.elytron</extension> <extension>org.wildfly.extension.health</extension> <extension>org.wildfly.extension.io</extension> <extension>org.wildfly.extension.messaging-activemq</extension> <extension>org.wildfly.extension.metrics</extension> <extension>org.wildfly.extension.opentelemetry</extension> <extension>org.wildfly.extension.request-controller</extension> <extension>org.wildfly.extension.rts</extension> <extension>org.wildfly.extension.security.manager</extension> <extension>org.wildfly.extension.undertow</extension> <extension>org.wildfly.iiop-openjdk</extension> </standalone> <domain> <extension>org.jboss.as.clustering.infinispan</extension> <extension>org.jboss.as.clustering.jgroups</extension> <extension>org.jboss.as.connector</extension> <extension>org.jboss.as.ee</extension> <extension>org.jboss.as.ejb3</extension> <extension>org.jboss.as.jaxrs</extension> <extension>org.jboss.as.jdr</extension> <extension>org.jboss.as.jmx</extension> <extension>org.jboss.as.jpa</extension> <extension>org.jboss.as.jsf</extension> <extension>org.jboss.as.jsr77</extension> <extension>org.jboss.as.logging</extension> <extension>org.jboss.as.mail</extension> <extension>org.jboss.as.modcluster</extension> <extension>org.jboss.as.naming</extension> <extension>org.jboss.as.pojo</extension> <extension>org.jboss.as.remoting</extension> <extension>org.jboss.as.sar</extension> <extension>org.jboss.as.security</extension> <extension>org.jboss.as.transactions</extension> <extension>org.jboss.as.webservices</extension> <extension>org.jboss.as.weld</extension> <extension>org.jboss.as.xts</extension> <extension>org.wildfly.extension.batch.jberet</extension> <extension>org.wildfly.extension.bean-validation</extension> <extension>org.wildfly.extension.clustering.singleton</extension> <extension>org.wildfly.extension.clustering.web</extension> <extension>org.wildfly.extension.core-management</extension> <extension>org.wildfly.extension.discovery</extension> <extension>org.wildfly.extension.ee-security</extension> <extension>org.wildfly.extension.elytron</extension> <extension>org.wildfly.extension.io</extension> <extension>org.wildfly.extension.messaging-activemq</extension> <extension>org.wildfly.extension.opentelemetry</extension> <extension>org.wildfly.extension.picketlink</extension> <extension>org.wildfly.extension.request-controller</extension> <extension>org.wildfly.extension.rts</extension> <extension>org.wildfly.extension.security.manager</extension> <extension>org.wildfly.extension.undertow</extension> <extension>org.wildfly.iiop-openjdk</extension> </domain> <host> <extension>org.jboss.as.jmx</extension> <extension>org.wildfly.extension.core-management</extension> <extension>org.wildfly.extension.discovery</extension> <extension>org.wildfly.extension.elytron</extension> </host> </extensions> </generate-feature-specs>
<generate-feature-specs> <extensions> <standalone> <extension>org.wildfly.extension.elytron-oidc-client</extension> <extension>org.wildfly.extension.microprofile.config-smallrye</extension> <extension>org.wildfly.extension.microprofile.fault-tolerance-smallrye</extension> <extension>org.wildfly.extension.microprofile.health-smallrye</extension> <extension>org.wildfly.extension.microprofile.jwt-smallrye</extension> <extension>org.wildfly.extension.microprofile.metrics-smallrye</extension> <extension>org.wildfly.extension.microprofile.openapi-smallrye</extension> <extension>org.wildfly.extension.microprofile.opentracing-smallrye</extension> <extension>org.wildfly.extension.microprofile.reactive-messaging-smallrye</extension> <extension>org.wildfly.extension.microprofile.reactive-streams-operators-smallrye</extension> </standalone> <domain> <extension>org.wildfly.extension.microprofile.config-smallrye</extension> <extension>org.wildfly.extension.microprofile.fault-tolerance-smallrye</extension> <extension>org.wildfly.extension.microprofile.jwt-smallrye</extension> <extension>org.wildfly.extension.microprofile.openapi-smallrye</extension> <extension>org.wildfly.extension.microprofile.opentracing-smallrye</extension> <extension>org.wildfly.extension.microprofile.reactive-messaging-smallrye</extension> <extension>org.wildfly.extension.microprofile.reactive-streams-operators-smallrye</extension> </domain> </extensions> </generate-feature-specs>
これらのMavenアーティファクトである、wildfly-core-galleon-pack
、wildfly-servlet-galleon-pack
、wildfly-ee-galleon-pack
、
wildfly-galleon-pack
の中身を見ると、大量のpackage、feature、feature-group、layer、そしてfeature-packとしての定義が
含まれていることを確認できます。
というわけで
WildFly Galleon layerに含まれる内容をざっくり知りたかったらlayer-spec.xml
を読めばよいですし、feature-groupであれば[feagure-group名].xml
を
読むとなにが含まれているのか、ある程度雰囲気がわかるのではないかと思います。
あとは、最後に軽くWildFly Bootable JARを作って遊んでおきましょう。
お題
今回のお題は、こちらをWildFly Bootable JARで実現することにします。WildFlyのHTTPセッションの保存先をInfinispan Serverに変更したもの
ですね。
WildFlyのHTTPセッションの保存先をInfinispan Serverに変更する - CLOVER🍀
こちらのエントリーで作ったソースコードはServletを使ったものだったので、今回はJAX-RSとCDIを使うことにしましょう。
WildFly Bootable JARでパッケージングする際に、必要なGalleon layerを組み込み、WildFly CLIでDistributable Webサブシステムの設定を行う
感じでいきたいと思います。
環境
今回の環境は、こちらです。
$ java --version openjdk 17.0.3 2022-04-19 OpenJDK Runtime Environment (build 17.0.3+7-Ubuntu-0ubuntu0.20.04.1) OpenJDK 64-Bit Server VM (build 17.0.3+7-Ubuntu-0ubuntu0.20.04.1, mixed mode, sharing) $ mvn --version Apache Maven 3.8.6 (84538c9988a25aec085021c365c560670ad80f63) Maven home: $HOME/.sdkman/candidates/maven/current Java version: 17.0.3, vendor: Private Build, runtime: /usr/lib/jvm/java-17-openjdk-amd64 Default locale: ja_JP, platform encoding: UTF-8 OS name: "linux", version: "5.4.0-121-generic", arch: "amd64", family: "unix"
Infinispan Serverは13.0.10.Finalを使用し、172.18.0.2で動作しているものとします。
$ bin/server.sh \ -b 0.0.0.0 \ -Djgroups.tcp.address=`hostname -i`
ユーザーも作成しておきます。Cacheは、WildFly側の起動時に作成することにします。
$ bin/cli.sh user create -g admin -p password web-session-user
アプリケーションを作成する
それでは、アプリケーションを作成してきましょう。
<groupId>org.littlewings</groupId> <artifactId>wildfly-bootable-jar-layer</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>jakarta.platform</groupId> <artifactId>jakarta.jakartaee-bom</artifactId> <version>8.0.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>jakarta.ws.rs</groupId> <artifactId>jakarta.ws.rs-api</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>jakarta.enterprise</groupId> <artifactId>jakarta.enterprise.cdi-api</artifactId> <scope>provided</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>3.3.2</version> </plugin> <plugin> <groupId>org.wildfly.plugins</groupId> <artifactId>wildfly-jar-maven-plugin</artifactId> <version>7.0.2.Final</version> <configuration> <!-- 後で --> </configuration> <executions> <execution> <goals> <goal>package</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
WildFly Jar Maven Pluginの部分は、また後で載せます。
続いて、ソースコード。
SessionScopedなCDI管理Bean。
src/main/java/org/littlewings/wildfly/bootable/Counter.java
package org.littlewings.wildfly.bootable; import java.io.Serializable; import java.util.concurrent.atomic.AtomicInteger; import javax.enterprise.context.SessionScoped; @SessionScoped public class Counter implements Serializable { private static final long serialVersionUID = 1L; AtomicInteger value = new AtomicInteger(); public int incrementAndGet() { return value.incrementAndGet(); } }
JAX-RSリソースクラス。SessionScopedなCDI管理Beanは、このクラスで使います。
src/main/java/org/littlewings/wildfly/bootable/CounterResource.java
package org.littlewings.wildfly.bootable; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; @ApplicationScoped @Path("counter") public class CounterResource { @Inject Counter counter; @GET @Produces(MediaType.TEXT_PLAIN) public String get() { return String.format("count = %d", counter.incrementAndGet()); } }
JAX-RSの有効化。
src/main/java/org/littlewings/wildfly/bootable/JaxrsActivator.java
package org.littlewings.wildfly.bootable; import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; @ApplicationPath("") public class JaxrsActivator extends Application { }
web.xml
。<distributable/>
を入れておきます。
src/main/webapp/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee webapp_4_0.xsd" version="4.0"> <distributable/> </web-app>
これで、アプリケーションの準備は完了です。
WildFly Jar Maven Pluginの設定をする
では、WildFly Jar Maven Pluginの設定をしていきます。
<plugin> <groupId>org.wildfly.plugins</groupId> <artifactId>wildfly-jar-maven-plugin</artifactId> <version>7.0.2.Final</version> <configuration> <!-- 後で --> </configuration> <executions> <execution> <goals> <goal>package</goal> </goals> </execution> </executions> </plugin>
とりあえず、mvn package
でWildFly Bootable JARを作成するようにはしておきました。
まずはGalleon layerを選択しましょう。
<feature-pack-location>wildfly@maven(org.jboss.universe:community-universe)#26.1.1.Final</feature-pack-location> <layers> <layer>jaxrs-server</layer> <layer>web-clustering</layer> </layers>
feature-pack-location
でWildFly 26.1.1.Finalをプロビジョニングすることを指定。
選択するWildFly Galleon layerですが、まずはFoundational Galleon layerから「jaxrs-server」を選択。含まれているものがちょっと多いですが、
これで「bean-validation」、「cdi」、「datasources-web-server」、「jaxrs」、「jpa」が利用できることになります。
「jaxrs-server」は「datasources-web-server」を、「datasources-web-server」は「core-server」を依存するlayerとしているため、
やっぱりそれなりに含まれますね。
「jaxrs」と「cdi」があれば良いのではないかと思いますが、今回はFoundational Galleon layers、Basic Galleon Layersそれぞれから
layerを選択するようにしたいと思います。
「jaxrs-server」だけではInfinispan Server(Hot Rod)によるセッション管理は実現できません。こちらを使うには、
Distributable Webサブシステムが必要になります。
WildFlyのHTTPセッションの保存先をInfinispan Serverに変更する - CLOVER🍀
Distributable Webサブシステムが含まれるlayerはというと…パッと見ではわかりませんが、「web-clustering」が該当します。
こちらは、Basic Galleon Layersから選択。
「web-clustering」の依存するlayerは「transactions」と「web-server」ということになっていて、あんまりクラスタリング感はありません。
ここで、「web-clustering」layerのlayer-spec.xml
を見てみます。
<?xml version="1.0" ?> <layer-spec xmlns="urn:jboss:galleon:layer-spec:1.0" name="web-clustering"> <dependencies> <layer name="web-server"/> <layer name="transactions"/> </dependencies> <feature-group name="private-interface"/> <feature-group name="jgroups-all"/> <feature-group name="distributable-web"/> <feature-group name="infinispan-dist-web"/> <packages> <!-- The distributable-web subsystem doesn't assume undertow, and undertow subysystem doesn't assume clustering, but the combination requires the clustering<->undertow integration package --> <package name="org.wildfly.clustering.web.undertow"/> </packages> </layer-spec>
「distributable-web」と「infinispan-dist-web」という2つのfeature-groupを参照しています。
「infinispan-dist-web」feature-groupは、Infinispanサブシステムが定義されているようです。
「distributable-web」feature-groupの方はどうでしょうか。
<?xml version="1.0" encoding="UTF-8"?> <feature-group-spec name="distributable-web" xmlns="urn:jboss:galleon:feature-group:1.0"> <feature spec="subsystem.distributable-web"> <param name="default-session-management" value="default"/> <param name="default-single-sign-on-management" value="default"/> <feature spec="subsystem.distributable-web.infinispan-session-management"> <param name="infinispan-session-management" value="default"/> <param name="cache-container" value="web"/> <param name="granularity" value="SESSION"/> <feature spec="subsystem.distributable-web.infinispan-session-management.affinity.primary-owner"/> </feature> <feature spec="subsystem.distributable-web.infinispan-single-sign-on-management"> <param name="infinispan-single-sign-on-management" value="default"/> <param name="cache-container" value="web"/> <param name="cache" value="sso"/> </feature> <feature spec="subsystem.distributable-web.routing.infinispan"> <param name="cache-container" value="web"/> <param name="cache" value="routing"/> </feature> </feature> </feature-group-spec>
こちらには、Distributable Webサブシステムが含まれていそうです。
というわけで、今回はこの2つのlayerを選択することにしました。
<layers> <layer>jaxrs-server</layer> <layer>web-clustering</layer> </layers>
続いては、Remote Cache ContainerとDistributable Webサブシステムの設定を行う必要があります。
こちらには、WildFly CLIでセットアップすることにしましょう。
WildFly CLIは、パッケージング時、実行時のどちらでも利用できますが、今回はパッケージング時とします。
こんなスクリプトを用意。
cli-scripts/hotrod-session.cli
/socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=infinispan-server:add(host=172.18.0.2, port=11222) batch /subsystem=infinispan/remote-cache-container=remote-infinispan:add(default-remote-cluster=remote-infinispan-cluster) /subsystem=infinispan/remote-cache-container=remote-infinispan/remote-cluster=remote-infinispan-cluster:add(socket-bindings=[infinispan-server]) run-batch /subsystem=infinispan/remote-cache-container=remote-infinispan:write-attribute(name=modules,value=[org.wildfly.clustering.web.hotrod]) /subsystem=infinispan/remote-cache-container=remote-infinispan:write-attribute(name=properties,value={infinispan.client.hotrod.auth_username=web-session-user,infinispan.client.hotrod.auth_password=password}) /subsystem=infinispan/remote-cache-container=remote-infinispan:write-attribute(name=marshaller,value=PROTOSTREAM) /subsystem=distributable-web/hotrod-session-management=remote-session:add(remote-cache-container=remote-infinispan, cache-configuration=org.infinispan.DIST_SYNC, granularity=SESSION) /subsystem=distributable-web/hotrod-session-management=remote-session/affinity=none:add() /subsystem=distributable-web:write-attribute(name=default-session-management,value=remote-session)
こちらを実行するように設定。
<cli-sessions> <cli-session> <script-files> <script>cli-scripts/hotrod-session.cli</script> </script-files> </cli-session> </cli-sessions>
全体としては、このようになりました。
<plugin> <groupId>org.wildfly.plugins</groupId> <artifactId>wildfly-jar-maven-plugin</artifactId> <version>7.0.2.Final</version> <configuration> <feature-pack-location>wildfly@maven(org.jboss.universe:community-universe)#26.1.1.Final</feature-pack-location> <layers> <layer>jaxrs-server</layer> <layer>web-clustering</layer> </layers> <cli-sessions> <cli-session> <script-files> <script>cli-scripts/hotrod-session.cli</script> </script-files> </cli-session> </cli-sessions> </configuration> <executions> <execution> <goals> <goal>package</goal> </goals> </execution> </executions> </plugin>
あとはパッケージングして完成です。
$ mvn package
パッケージングすると、CLIの実行が行われている様子が確認できます。
[INFO] CLI executions are done in forked process [INFO] Executing CLI, Server configuration [INFO] CLI scripts execution done. [INFO] Executing CLI, CLI Session, scripts=[cli-scripts/hotrod-session.cli], resolve-expressions=true, properties-file=null [INFO] CLI scripts execution done.
ちなみに、「web-clustering」layerを入れていない場合は、以下のようにCLIの実行に失敗します。
[ERROR] Exception in thread "main" java.lang.reflect.InvocationTargetException [ERROR] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [ERROR] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) [ERROR] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [ERROR] at java.base/java.lang.reflect.Method.invoke(Method.java:568) [ERROR] at org.wildfly.plugins.bootablejar.maven.cli.CLIWrapper.handle(CLIWrapper.java:82) [ERROR] at org.wildfly.plugins.bootablejar.maven.cli.CLIForkedExecutor.main(CLIForkedExecutor.java:49) [ERROR] Caused by: org.jboss.as.cli.CommandFormatException: Failed to get the list of the operation properties: "WFLYCTL0030: No resource definition is registered for address [ [ERROR] ("subsystem" => "distributable-web"), [ERROR] ("hotrod-session-management" => "remote-session") [ERROR] ]" [ERROR] at org.jboss.as.cli.Util.retrieveDescription(Util.java:1637) [ERROR] at org.jboss.as.cli.Util.validateRequest(Util.java:1655) [ERROR] at org.jboss.as.cli.handlers.OperationRequestHandler.handle(OperationRequestHandler.java:83) [ERROR] at org.jboss.as.cli.impl.CommandContextImpl.handleOperation(CommandContextImpl.java:1917) [ERROR] at org.jboss.as.cli.impl.CommandContextImpl.handle(CommandContextImpl.java:875) [ERROR] ... 6 more
動作確認する
では、動作確認してみましょう。Infinispan Serverは起動済みとします。
パッケージングして、できあがったJARファイルを実行。
$ java -jar target/wildfly-bootable-jar-layer-0.0.1-SNAPSHOT-bootable.jar
起動すると、Infinispan Server側にROOT.war
というCacheがないことが表示されつつ、Infinispan Serverを認識します。
01:45:51,025 INFO [org.infinispan.HOTROD] (ServerService Thread Pool -- 46) ISPN004021: Infinispan version: Infinispan 'Triskaidekaphobia' 13.0.10.Final 01:45:51,026 INFO [org.jboss.as.clustering.infinispan] (ServerService Thread Pool -- 46) WFLYCLINF0029: Started remote cache container 'remote-infinispan'. 01:45:51,034 WARN [org.infinispan.HOTROD] (HotRod-client-async-pool-0) ISPN004005: Error received from the server: org.infinispan.server.hotrod.CacheNotFoundException: Cache with name 'ROOT.war' not found amongst the configured caches 01:45:51,139 INFO [org.infinispan.HOTROD] (HotRod-client-async-pool-0) ISPN004006: Server sent new topology view (id=1, age=0) containing 1 addresses: [172.18.0.2/<unresolved>:11222]
一方でInfinispan Server側では、Cacheが作成されたことが確認できます。
2022-06-29 16:45:51,069 WARN (blocking-thread--p3-t1) [org.infinispan.encoding.impl.StorageConfigurationManager] ISPN000599: Configuration for cache 'ROOT.war' does not define the encoding for keys or values. If you use operations that require data conversion or queries, you should configure the cache with a specific MediaType for keys or values.
CLIでも確認。
[infinispan-server-34838@cluster//containers/default]> describe caches/ROOT.war { "distributed-cache" : { "mode" : "SYNC", "remote-timeout" : "17500", "statistics" : true, "locking" : { "concurrency-level" : "1000", "acquire-timeout" : "15000", "striping" : false }, "state-transfer" : { "timeout" : "60000" } } }
動作確認。
$ curl -c cookie.txt -b cookie.txt localhost:8080/counter count = 1 $ curl -c cookie.txt -b cookie.txt localhost:8080/counter count = 2 $ curl -c cookie.txt -b cookie.txt localhost:8080/counter count = 3 $ curl -c cookie.txt -b cookie.txt localhost:8080/counter count = 4 $ curl -c cookie.txt -b cookie.txt localhost:8080/counter count = 5
この状態で、WildFly Bootable JARで作られたアプリケーションを再起動しても、HTTPセッションが失われていないことが確認できます。
$ curl -c cookie.txt -b cookie.txt localhost:8080/counter count = 6
OKですね。
まとめ
WildFly Bootable JARを作成する際に指定する、Galleon layer、Galleon feature-packというものを少し見てみました。
軽い気持ちで始めてみたら思ったよりも追うところが大変だったのですが、その分いろいろ情報が追えた&理解が進んだ気がするので、
まあいいかなと思います。