Quarkusのバージョンを上げたら"Quarkus REST"と"RESTEasy Classic"の混在で怒られた

## はじめに

Quarkusのバージョンを上げた（`3.4.1`から`3.15.2`まで上げた）あと、`quarkusDev`でのアプリケーション起動時に↓のエラーが発生しました。

```sh
> :ma2025-03-02 16:00:35,049 ERROR [io.qua.dep.dev.IsolatedDevModeMain] (main) Failed to start quarkus: java.lang.RuntimeException: io.quarkus.builder.BuildException: Build failure: Build failed due to errorsUTING [18s]
        [error]: Build step io.quarkus.resteasy.reactive.common.deployment.ResteasyReactiveCommonProcessor#checkMixingStacks threw an exception: jakarta.enterprise.inject.spi.DeploymentException: Mixing Quarkus REST and RESTEasy Classic server parts is not supported
        at io.quarkus.resteasy.reactive.common.deployment.ResteasyReactiveCommonProcessor.checkMixingStacks(ResteasyReactiveCommonProcessor.java:108)
        at java.base/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:733)
        at io.quarkus.deployment.ExtensionLoader$3.execute(ExtensionLoader.java:856)
        at io.quarkus.builder.BuildContext.run(BuildContext.java:256)
        at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
        at org.jboss.threads.EnhancedQueueExecutor$Task.doRunWith(EnhancedQueueExecutor.java:2516)
        at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2495)
        at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1521)
        at java.base/java.lang.Thread.run(Thread.java:1583)
        at org.jboss.threads.JBossThread.run(JBossThread.java:483)
```

これを解決したときの書き残しです。

## 原因

エラーメッセージにある`Mixing Quarkus REST and RESTEasy Classic server parts is not supported`が原因です。

つまり、従来の`RESTEasy Classic`と、より新しい実装である`Quarkus REST`の混在はサポートされていないよ、ということです。
`Quarkus REST`への移行について、詳しいことはQuarkus公式のドキュメントにも書いてあります

https://ja.quarkus.io/guides/rest-migration


登場人物を整理しておきます。

| name  | artifact id  | description |
|-------|--------------|-------------|
| RESTEasy Classic  | [quarkus-resteasy](https://quarkus.io/extensions/io.quarkus/quarkus-resteasy/) | 従来のJakarta REST（JAX-RS）仕様の実装 |
| Quarkus REST      | [quarkus-rest](https://quarkus.io/extensions/io.quarkus/quarkus-rest/)     | 新しいJakarta REST仕様の実装          |
| RESTEasy Reactive | [quarkus-resteasy-reactive](https://quarkus.io/extensions/io.quarkus/quarkus-resteasy-reactive/) | 新しいJakarta REST仕様の実装。 今はQuarkus RESTに名前が変わっている |

### 混在の禁止

`RESTEasy Classic`と`Quarkus REST`の混在が明確に禁止されたのは`Quarkus 3.9`からです。ちなみに`RESTEasy Reactive`が`Quarkus REST`にリネームされたのもこのタイミングです。

https://quarkus.io/blog/quarkus-3-9-1-released/

今回のバージョンアップでは`3.9`をまたいでいるので、禁止に引っかかってエラーが出たんですね。


## 修正方法

混在しているのがいけないので、その状態を正します。

その時書いていた依存関係（GradleのKotlin DSL）はこうでした。

```kotlin
    implementation("io.quarkus:quarkus-rest-client")
    implementation("io.quarkus:quarkus-rest-client-jackson")
    implementation("io.quarkus:quarkus-resteasy")
    implementation("io.quarkus:quarkus-resteasy-jackson")
```

`quarkus-resteasy`系は古いので、「`Quarkus REST`への移行」の[ドキュメント](https://ja.quarkus.io/guides/rest-migration)にも記載されていた通り、新しい`quarkus-rest`に置き換えます。
つまりこうですね。

```diff
    implementation("io.quarkus:quarkus-rest-client")
    implementation("io.quarkus:quarkus-rest-client-jackson")
-   implementation("io.quarkus:quarkus-resteasy")
-   implementation("io.quarkus:quarkus-resteasy-jackson")
+   implementation("io.quarkus:quarkus-rest")
+   implementation("io.quarkus:quarkus-rest-jackson")
```

これで、新しい`quarkus-rest`だけが使われるようになるので、問題解決しました！

### それでも直らない場合は?

同じことをやったけど直らないんですが？というケースもあるかもしれません。
私は前述の対応で問題解消できているので、ここからは想像で書くことをお許しください。

考えられるのは、プロジェクトで直接指定している依存関係だけでなく、それに付随して自動的に追加されるライブラリ（つまり間接的に依存しているライブラリ）の中に、古い`quarkus-resteasy`が含まれている可能性があるということです。

どういうことか、というのは、下記のコマンドで`dependencies`のタスクを実行してもらうのが分かりやすいと思います。

```sh:sh
$ ./gradlew dependencies --configuration runtimeClasspath
```

なお、プロジェクトの規模が大きいと依存関係ツリーは膨大になり、見るのが結構大変なので、例えば`quarkus`あたりでgrepすれば少し楽になるかもしれません。この辺りのキーワードは適宜調整してください。

```sh:sh
$ ./gradlew dependencies --configuration runtimeClasspath | grep quarkus
```

出力された依存関係のツリーの中に、新しいもの（`quarkus-rest`または`quarkus-resteasy-reactive`）と古いもの（`quarkus-resteasy`）がどちらも存在していたら、やはり混在しているということが確認できます。

そこが確認できれば、どのライブラリが`quarkus-resteasy`を間接的に引き込んでいるのかを特定し、そのライブラリのバージョンを上げる、もしくは不要なものを削除することで解決できるはずです。

新しいライブラリへの移行の際は、（冒頭で示したドキュメントと同じですが、）「Quarkus RESTへの移行」も参考にしてみてください。

https://ja.quarkus.io/guides/rest-migration