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

@Activate方法调用ResourceResolverFactory触发RuntimeException求助

问题分析与解决方案

首先看错误栈的根因:Caused by: java.lang.NullPointerException at com.Demo.MyTest.activate(MyTest.java:75),这说明在activate方法执行时,resolverFactory字段是null,调用它的方法才触发了空指针异常。而把调用移到公共方法里能正常运行,核心原因和OSGi服务生命周期、你的单元测试环境直接相关,具体拆解如下:

为什么Activate方法里会出现NPE?

从错误栈里的org.apache.sling.testing.mock.osgi相关类能看出,这是单元测试场景下的问题。Sling Mock OSGi框架通过registerInjectActivateService注册你的MyTest服务时,逻辑是先尝试注入所有@Reference标注的依赖,再调用@Activate方法。

但如果你的测试代码里没有提前注册ResourceResolverFactory的模拟实例,框架无法找到这个依赖服务,resolverFactory就会保持null状态,此时执行activate里的调用自然会抛出NPE。

而把调用移到公共方法后能正常运行,大概率是两种情况:

  • 测试时,你在调用这个公共方法之前,已经手动注册了ResourceResolverFactory的mock,此时依赖已经被注入;
  • 你在真实AEM运行环境中测试,此时ResourceResolverFactory是OSGi容器中真实存在的服务,依赖注入流程正常。

解决步骤

1. 在单元测试中提前注册ResourceResolverFactory的Mock

用Mockito创建ResourceResolverFactory的模拟实例,先注册到OSGi测试上下文,再注册你的MyTest服务。示例代码:

@RunWith(MockitoJUnitRunner.class)
public class MyDemoTest {

    @Rule
    public OsgiContext context = new OsgiContext();

    @Mock
    private ResourceResolverFactory mockResolverFactory;

    @Mock
    private ResourceResolver mockResolver;

    @Before
    public void setUp() throws LoginException {
        // 模拟getAdministrativeResourceResolver的返回结果
        when(mockResolverFactory.getAdministrativeResourceResolver(null)).thenReturn(mockResolver);
        // 先注册ResourceResolverFactory的mock到测试上下文
        context.registerService(ResourceResolverFactory.class, mockResolverFactory);
        // 再注册MyTest服务
        context.registerInjectActivateService(new MyTest());
    }

    // 测试方法...
}

2. 替换不推荐的getAdministrativeResourceResolver调用

在AEM中,getAdministrativeResourceResolver(null)这种方式是官方不推荐的(它会使用系统管理员权限,存在安全风险),建议改用**服务用户(Service User)**来获取ResourceResolver:

  1. 在AEM中创建对应的服务用户,并配置好所需权限;
  2. 用getServiceResourceResolver方法替换原有调用,示例代码:
@Activate
protected void activate() {
    final ResourceResolver resolver;
    try {
        Map<String, Object> authInfo = new HashMap<>();
        // 替换成你配置的服务用户名称
        authInfo.put(ResourceResolverFactory.SUBSERVICE, "my-test-service-user");
        resolver = resolverFactory.getServiceResourceResolver(authInfo);
    } catch (LoginException e) {
        LOG.error("error resolving resource resolver", e);
        return;
    }
    // 后续业务逻辑...
}

3. 确保OSGi依赖注入的顺序

在真实AEM运行环境中,OSGi容器会自动处理依赖注入顺序(先确保依赖服务可用,再激活你的服务),但在测试环境中必须手动保证:先注册所有依赖服务的mock,再注册你的MyTest服务。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 04:28:12