WildFlyで実行可能Jar（UberJarともBootableJarとも言う）

# 何の記事か
直近の登壇に備えてMicroProfileの現状を調べている際に
WildflyがBootableJar対応したとのリリースノートを見かけました。
Redhatであれば、QuarkusとかThorntailだけでなくてWildflyなの？？と
衝撃覚えましたので、記事化してみました

# 誰向けか
Javaで開発したことある人向けです。
Mavenって何とかの人は、そのあたり知ってから読むと良いです。

# きっかけのリリースノート
Wildfly21のリリースノートに以下記載があります。

> Bootable JAR / Galleon Layers
>
> The biggest thing in WildFly 21 is Jean-Francois Denise and the team have added GA-level > support for the Bootable JAR feature that we’ve been working on over the last two releases.

・元文書
https://www.wildfly.org/news/2020/10/13/WildFly21-Final-Released/

なんて素晴らしいのでしょう。

# 実行可能Jar（UberJarともBootableJar）って何？

SpringBootしかやったことがない人は経験ないと思いますが、SpringBoot登場以前は、①アプリケーションサーバなるミドルウェアを起動し、その後に②アプリケーションのアーカイブファイル（warとかearとか）をデプロイすることにより、Webアプリケーションを起動させていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113217/f057b21e-4a9b-ccbe-074a-1a4ca8781e3c.png)

ここでいうアプリケーションサーバが、Wildflyだったわけです。

それが、最近だと事前にアプリケーションサーバを立ち上げる形式ではなく、アプリケーションアーカイバファイル（jar)の中にアプリケーションサーバで必要だったライブラリを包んで、いきなり立ち上げることができるようになったのです。楽ですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113217/91619fea-189b-26d1-39ff-4f51627601d4.png)

ちなみに、Wildfly公式ではBootableJarと読んでますが、世間ではUberJarと呼ぶことが多い気がします。
Uberって何というと、ドイツ語で「従事・同時性」みたいな意味があってそこから来ているそうです。
（これも今回調べて初めて知りました）

# やってみる

Wildfly公式ページからチュートリアルをやろうかとも思ったのですが、楽します。
MicroProfileのStarterにWildflyが選べましたのでそこからやります。

https://start.microprofile.io/
に行き、MP3.3(MicroProfileのバージョン3.3を使うという意味)を選ぶとMicroProfile RuntimeにWildFlyが登場するのでそれを選んでダウンロードするだけです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113217/51fbb20e-ff2f-8daa-f5c9-20c83333d071.png)

Zipファイルを解凍すると、中身は以下のとおりです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113217/4de532bf-89e8-564b-a548-45729fbc8d80.png)

Readme.mdに従って、

``` mvn package ```

を実施し、出来上がったjarファイルに対して

``` java -jar target/demo-jboss-wildfly.jar ```

をコマンドライン上から打つと、アプリが立ち上がります。簡単すぎますね。
初回は各種ライブラリのダウンロードが走るので遅いですが、アプリ立ち上げは数秒でした。
SpringBootに引けを取らないぐらい早いですね。

```実行ログ
\$ java -jar target/demo-jboss-bootable.jar
20:38:48,068 INFO  [org.wildfly.jar] (main) WFLYJAR0007: Installed server and application in /var/folders/1m/v_pnk3kd3hj0558d1z3nsnzh0000gn/T/wildfly-bootable-server4287071073176360181, took 1736ms
20:38:48,524 INFO  [org.wildfly.jar] (main) WFLYJAR0008: Server options: [--read-only-server-config=standalone.xml]
20:38:48,632 INFO  [org.jboss.msc] (main) JBoss MSC version 1.4.12.Final
20:38:48,641 INFO  [org.jboss.threads] (main) JBoss Threads version 2.4.0.Final
20:38:48,801 INFO  [org.jboss.as] (MSC service thread 1-3) WFLYSRV0049: WildFly Full 21.0.0.Final (WildFly Core 13.0.1.Final) starting
20:38:49,685 INFO  [org.wildfly.extension.microprofile.config.smallrye._private] (ServerService Thread Pool -- 17) WFLYCONF0001: Activating WildFly MicroProfile Config Subsystem
20:38:49,690 INFO  [org.jboss.as.naming] (ServerService Thread Pool -- 19) WFLYNAM0001: Activating Naming Subsystem
20:38:49,695 INFO  [org.wildfly.extension.microprofile.openapi.smallrye] (ServerService Thread Pool -- 18) WFLYMPOAI0001: Activating Eclipse MicroProfile OpenAPI Subsystem
20:38:49,715 INFO  [org.jboss.as.jaxrs] (ServerService Thread Pool -- 16) WFLYRS0016: RESTEasy version 3.13.2.Final
20:38:49,722 INFO  [org.xnio] (ServerService Thread Pool -- 15) XNIO version 3.8.2.Final
20:38:49,741 INFO  [org.wildfly.extension.undertow] (MSC service thread 1-7) WFLYUT0003: Undertow 2.2.2.Final starting
20:38:49,743 INFO  [org.jboss.as.naming] (MSC service thread 1-2) WFLYNAM0003: Starting Naming Service
20:38:49,773 INFO  [org.xnio.nio] (ServerService Thread Pool -- 15) XNIO NIO Implementation Version 3.8.2.Final
20:38:49,818 INFO  [org.wildfly.extension.io] (ServerService Thread Pool -- 15) WFLYIO001: Worker 'default' has auto-configured to 8 IO threads with 64 max task threads based on your 4 available processors
20:38:49,865 INFO  [org.wildfly.extension.undertow] (MSC service thread 1-6) WFLYUT0012: Started server default-server.
20:38:49,868 INFO  [org.wildfly.extension.undertow] (MSC service thread 1-8) WFLYUT0018: Host default-host starting
20:38:49,902 INFO  [org.jboss.as.server.deployment.scanner] (MSC service thread 1-3) WFLYDS0013: Started FileSystemDeploymentService for directory /var/folders/1m/v_pnk3kd3hj0558d1z3nsnzh0000gn/T/wildfly-bootable-server4287071073176360181/standalone/deployments
20:38:49,913 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-8) WFLYSRV0027: Starting deployment of "demo-jboss.war" (runtime-name: "ROOT.war")
20:38:49,996 INFO  [org.wildfly.extension.undertow] (MSC service thread 1-5) WFLYUT0006: Undertow HTTP listener default listening on 127.0.0.1:8080
20:38:50,552 INFO  [org.jboss.weld.deployer] (MSC service thread 1-8) WFLYWELD0003: Processing weld deployment ROOT.war
20:38:50,959 INFO  [org.hibernate.validator.internal.util.Version] (MSC service thread 1-8) HV000001: Hibernate Validator 6.0.21.Final
20:38:51,321 INFO  [org.jboss.weld.Version] (MSC service thread 1-1) WELD-000900: 3.1.5 (Final)
20:38:51,488 INFO  [org.jboss.weld.Bootstrap] (MSC service thread 1-3) WELD-000101: Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously.
20:38:52,237 INFO  [org.wildfly.extension.microprofile.openapi.smallrye] (MSC service thread 1-8) WFLYMPOAI0004: Registered MicroProfile OpenAPI endpoint '/openapi' for host 'default-host'
20:38:52,600 INFO  [org.jboss.resteasy.resteasy_jaxrs.i18n] (ServerService Thread Pool -- 22) RESTEASY002225: Deploying javax.ws.rs.core.Application: class com.example.demo.jboss.DemojbossRestApplication$Proxy$_$$_WeldClientProxy
20:38:52,639 INFO  [org.wildfly.extension.undertow] (ServerService Thread Pool -- 22) WFLYUT0021: Registered web context: '/' for server 'default-server'
20:38:52,641 INFO  [org.jboss.as.server] (Controller Boot Thread) WFLYSRV0010: Deployed "demo-jboss.war" (runtime-name : "ROOT.war")
20:38:52,669 INFO  [org.jboss.as.server] (Controller Boot Thread) WFLYSRV0212: Resuming server
20:38:52,671 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0025: WildFly Full 21.0.0.Final (WildFly Core 13.0.1.Final) started in 4140ms - Started 139 of 144 services (22 services are lazy, passive or on-demand)
```
→ 4140msec !!!

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113217/efe0e740-0a6a-1a37-6dab-0a16180b39a8.png)

MicroProfileのサンプルアプリトップページが無事表示できました。

実はMicroProfileのStarterで落としたものは、最初に紹介したWildfly21ではなかったです。
pom.xmlを見ると

``` 
...
<version.wildfly>19.1.0.Final</version.wildfly> 
...
```

と19.1でしたので、そのバージョンから対応していたことになりますね。
せっかく新しいバージョンが出たので21に今回は変更して動かしました。

```
...
<version.wildfly>21.0.0.Final</version.wildfly>
...
```

あと、Jarを作るプラグインについても併せて変えないといけないと思いましたがどう設定すればよいのか分からず、ひとまずバージョン指定なしにして動かしています。

```
...
      <build>
        <plugins>
          <plugin>
            <groupId>org.wildfly.plugins</groupId>
            <artifactId>wildfly-jar-maven-plugin</artifactId>
            <!-- 最新バージョンが何か分からず、一旦外して最新で実行-->
            <!--version>1.0.0.Alpha4</version-->
            <executions>
...
```

#まとめ

Wildflyで実行可能Jarが実現できるという認知度が低いかと思ったので記事化してみました。
プロダクト環境を変えるのは運用上、すぐには難しいとかあるかもしれませんが、ローカル開発環境から変えるとか
プロトタイプ開発から使ってみるとか、いろいろステップ踏みながらやっていきたいですね。

## 参考
使ったソースコードはGithubにあげています。ご参考です。
https://github.com/omix222/wildfly21demo

過去MicroProfileの概要についてまとめた記事です。
https://qiita.com/omix222/items/50804e30e43085ceb912