1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

QuarkusのCDIでBeanが見つからなかった問題の解決備忘録

Posted at

はじめに

最近、Quarkusアプリケーションの開発中にCDI1関係でハマったので、その時の解決方法を書き残しておきます。

なおKotlinQuarkusアプリケーションを開発している時に出くわした問題ですが、QuarkusKotlin特有の話ではなく、CDIの仕様に基づく挙動のため、Jakarta EE全般で同じようなことは起こり得ると思います。

Quarkus + CDI で UnsatisfiedResolutionException に出くわした

自作クラスAのインスタンスを、別の自作クラスBにコンストラクタインジェクションしようとするけれど、例外(UnsatisfiedResolutionException)がスローされて起動できない状態になりました。
ちなみにクラスAとクラスBは別のプロジェクトに配置されていました。

クラス名は伏せますが、その時のスタックトレースは以下のとおりです。
ザックリいうと「インジェクションしようとしているBeanが見つからない」と言われています。

sh
<====2025-03-18 21:34:30,234 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 [20s]
        [error]: Build step io.quarkus.arc.deployment.ArcProcessor#validate threw an exception: jakarta.enterprise.inject.spi.DeploymentException: jakarta.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type {インジェクションするクラスの完全修飾名} and qualifiers [@Default]
        - injection target: parameter '{インジェクション先クラスの変数名}' of {インジェクション先クラスの完全修飾名} constructor
        - declared on CLASS bean [types=[{インジェクション先クラスの完全修飾名}, java.lang.Object], qualifiers=[@Default, @Any], target={インジェクション先クラスの完全修飾名}]
        at io.quarkus.arc.processor.BeanDeployment.processErrors(BeanDeployment.java:1551)
        at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:338)
        at io.quarkus.arc.processor.BeanProcessor.initialize(BeanProcessor.java:167)
        at io.quarkus.arc.deployment.ArcProcessor.validate(ArcProcessor.java:490)
        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)
Caused by: jakarta.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type {インジェクションするクラスの完全修飾名} and qualifiers [@Default]
        - injection target: parameter '{インジェクション先クラスの変数名}' of {インジェクション先クラスの完全修飾名} constructor
        - declared on CLASS bean [types=[{インジェクション先クラスの完全修飾名}, java.lang.Object], qualifiers=[@Default, @Any], target={インジェクション先クラスの完全修飾名}]
        at io.quarkus.arc.processor.Beans.resolveInjectionPoint(Beans.java:545)
        at io.quarkus.arc.processor.BeanInfo.init(BeanInfo.java:667)
        at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:323)
        ... 11 more

原因と解決方法

結論から言うと、(だいぶ基礎的な部分の見落としですが、)インジェクションするクラスのプロジェクト内にbeans.xmlがなかったのが原因でした。
パスまで含めて言うとsrc/main/resources/META-INF/beans.xmlですね。

基本的にQuarkusでは@ApplicationScopedなどのスコープアノテーションが付いていれば、beans.xmlがなくてもBeanとして扱ってくれるはずです。ただ今回のケースではプロジェクトが分かれていたこともあり、beans.xmlを置いて明示的にBeanアーカイブと示さないとBeanを見つけてもらえなかったようです。

なおbeans.xmlは空ファイルで問題ありませんでした。
beans.xmlが置かれていることが「このJARファイル(ないしプロジェクト)はBeanアーカイブである」ということを示すためのマーカーとしての意味を持つので、今回はただファイルを置いただけで解決したようです。

  1. CDIについて簡単に触れておくと、DI(Dependency Injection: 依存性の注入)の仕様の一つで、Context and Dependency Injectionの略です。通常のDIに対して色々と機能が増えており、たとえばコンテキスト(オブジェクトのライフサイクル)管理がその一例です。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?