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

Jersey 3.x注入ServiceLocator遇空指针异常求助

Jersey 3.x + Wildfly 33:ResourceConfig中获取ServiceLocator的正确方式

核心问题

Jersey 3.x(适配Jakarta EE 9+)调整了DI初始化流程,ResourceConfig构造方法执行时,HK2的InjectionManager还未完成注入,直接在无参构造里访问注入字段会触发空指针异常。同时Wildfly 33内置Jersey版本可能和自定义依赖冲突,也会导致注入失败。


解决方案1:构造方法注入InjectionManager(推荐)

将InjectionManager作为构造方法参数注入,Jersey会在DI容器就绪后调用该构造方法,避免空指针:

import jakarta.inject.Inject;
import jakarta.ws.rs.ApplicationPath;
import org.glassfish.hk2.api.ServiceLocator;
import org.glassfish.jersey.internal.inject.InjectionManager;
import org.glassfish.jersey.server.ResourceConfig;

@ApplicationPath("/")
public class MyJerseyConfig extends ResourceConfig {

    @Inject
    public MyJerseyConfig(InjectionManager injectionManager) {
        logger.info(() -> "Bootstrapping Jersey 3.1.x");

        packages("...");

        // 从InjectionManager获取ServiceLocator
        ServiceLocator serviceLocator = injectionManager.getInstance(ServiceLocator.class);

        // 配置HK2 DI
        register(new MyHk2Config());

        // 建立HK2-Guice双向桥接
        createBiDirectionalGuiceBridge(serviceLocator, getServletModules(...));
    }
}

解决方案2:利用事件监听器延迟初始化

如果构造方法注入仍有问题,可通过监听应用初始化完成事件,在容器完全启动后获取ServiceLocator:

import jakarta.ws.rs.ApplicationPath;
import org.glassfish.hk2.api.ServiceLocator;
import org.glassfish.jersey.internal.inject.InjectionManager;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.monitoring.ApplicationEvent;
import org.glassfish.jersey.server.monitoring.ApplicationEventListener;
import org.glassfish.jersey.server.monitoring.RequestEvent;

@ApplicationPath("/")
public class MyJerseyConfig extends ResourceConfig {

    public MyJerseyConfig() {
        logger.info(() -> "Bootstrapping Jersey 3.1.x");
        packages("...");
        register(new MyHk2Config());
        
        // 注册应用初始化监听器
        register(new ApplicationEventListener() {
            @Override
            public void onEvent(ApplicationEvent event) {
                // 等待初始化完成后执行桥接
                if (event.getType() == ApplicationEvent.Type.INITIALIZATION_FINISHED) {
                    InjectionManager injectionManager = event.getInjectionManager();
                    ServiceLocator serviceLocator = injectionManager.getInstance(ServiceLocator.class);
                    createBiDirectionalGuiceBridge(serviceLocator, getServletModules(...));
                }
            }

            @Override
            public RequestEventListener onRequest(RequestEvent requestEvent) {
                return null;
            }
        });
    }
}

关键注意事项

  • 依赖版本对齐:Wildfly 33内置Jersey 3.x,需将项目中Jersey相关依赖设为provided范围,避免版本冲突:
    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-servlet-core</artifactId>
        <version>3.1.5</version> <!-- 与Wildfly内置版本保持一致 -->
        <scope>provided</scope>
    </dependency>
    
  • Guice与HK2桥接兼容:Guice 7.0.0需搭配hk2-guice-bridge 2.6.1及以上版本,确保桥接逻辑正常:
    <dependency>
        <groupId>org.glassfish.hk2</groupId>
        <artifactId>hk2-guice-bridge</artifactId>
        <version>2.6.1</version>
    </dependency>
    
  • Jakarta EE包迁移:确保所有javax.*包替换为jakarta.*(如javax.inject.Inject→jakarta.inject.Inject),混合使用会导致注入失效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 12:58:16