You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Weld-Junit5中addPackages无法将包内所有Bean加入测试容器的问题

问题:Jakarta EE 10 + Weld JUnit 5测试中CDI无法解析依赖

正在从Java EE 8迁移到Jakarta EE 10,使用Weld进行JUnit 5测试时遇到问题:Weld无法解析被注入的ExampleHelper类,报错WELD-001408: Unsatisfied dependencies。

示例代码

Example类(注入ExampleHelper)

public class Example {
    @Inject
    ExampleHelper exampleHelper;

    public void getHelloText() {
        exampleHelper.greet();
    }
}

ExampleHelper类

public class ExampleHelper {
    public void greet() {
        System.out.println("Hello");
    }
}

JUnit 5测试类

@ExtendWith(WeldJunit5Extension.class)
class ExampleTest {

    @WeldSetup
    public WeldInitiator weld = WeldInitiator.of(WeldInitiator.createWeld()
            .addBeanClass(Example.class)
            .addPackages(false, Example.class.getPackage())
    );

    @Inject
    Example example;

    @Test
    public void test() {
        example.getHelloText();
    }
}

报错信息

org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type ExampleHelper with qualifiers @Default
  at injection point [BackedAnnotatedField] @Inject com.company.wf28test.Example.exampleHelper
  at com.company.wf28test.Example.exampleHelper(Example.java:0)

依赖版本

jakarta.jakartaee-api 10.0.0
junit-jupiter-api 5.9.3
junit-jupiter-engine 5.9.3
weld-junit5 4.0.0.Final

原本以为调用addPackages(false, Example.class.getPackage())会扫描包内所有类并识别为CDI bean(Java EE 8中这么做没问题),但只有显式用addBeanClass逐个添加被注入类才能正常运行,想知道问题出在哪。


解答

问题核心在于Weld 4.x(对应Jakarta EE 10)的JUnit扩展对addPackages方法的参数逻辑做了调整,和Java EE 8时期的Weld版本行为不同:

  1. addPackages参数的含义变化
    你传入的addPackages(false, ...)里的false,表示不扫描包内无CDI注解的类。而你的ExampleHelper是没有任何CDI注解的普通类,所以Weld不会自动把它识别为CDI bean。
    在Java EE 8的Weld版本中,addPackages默认会扫描包内所有类,不管有没有注解,但Weld 4.x为了测试轻量化,调整了这个逻辑:只有当scanAnnotated参数为true时,才会扫描包内所有类(包括无注解的隐式bean);传false时,只注册显式添加的类和带CDI注解的类。

  2. CDI 3.0的隐式bean规则
    虽然Jakarta EE 10的CDI 3.0仍然支持无注解的隐式bean,但Weld的JUnit扩展不会自动扫描这类bean,必须明确配置。

两种修复方式

  • 方式一:修改addPackages参数为true
    把addPackages(false, Example.class.getPackage())改成addPackages(true, Example.class.getPackage()),让Weld扫描包内所有类,包括无注解的ExampleHelper:
@ExtendWith(WeldJunit5Extension.class)
class ExampleTest {

    @WeldSetup
    public WeldInitiator weld = WeldInitiator.of(WeldInitiator.createWeld()
            .addBeanClass(Example.class)
            .addPackages(true, Example.class.getPackage())
    );

    @Inject
    Example example;

    @Test
    public void test() {
        example.getHelloText();
    }
}
  • 方式二:给ExampleHelper添加CDI注解
    给ExampleHelper加上@Named或@Singleton等CDI注解,这样即使scanAnnotated为false,Weld也会识别它为bean:
@Named
public class ExampleHelper {
    public void greet() {
        System.out.println("Hello");
    }
}

内容的提问来源于stack exchange,提问作者Iceplanet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 08:43:09