Java 使用JAX-RS和Glassfish进行CDI和资源注入

Java 使用JAX-RS和Glassfish进行CDI和资源注入,java,jakarta-ee,glassfish,jax-rs,cdi,Java,Jakarta Ee,Glassfish,Jax Rs,Cdi,我目前正在开发一个JAX-RSservlet,然后我想将其部署在Glassfish 4.1服务器中(因此JAX-RS运行时是Jersey 2.x) 我不想使用Spring进行配置和DI,而是想尝试一下JavaEE的方法。但是,CDI和我在Glassfish服务器中配置的数据源的注入都不起作用。但首先,这里是关于servlet的相关内容 依赖项(在父pom中以版本和范围声明,而不是您在此处看到的版本和范围): SQLDataProvider.java: @Default @ApplicationS

我目前正在开发一个JAX-RSservlet,然后我想将其部署在Glassfish 4.1服务器中(因此JAX-RS运行时是Jersey 2.x)

我不想使用Spring进行配置和DI,而是想尝试一下JavaEE的方法。但是,CDI和我在Glassfish服务器中配置的数据源的注入都不起作用。但首先,这里是关于servlet的相关内容

依赖项(在父pom中以版本和范围声明,而不是您在此处看到的版本和范围):

SQLDataProvider.java:

@Default
@ApplicationScoped
@Singleton
@Path("singleton-bean")
public class SQLDataProvider implements DataProvider {

    @Resource(name = "jdbc/db_1")
    private DataSource dataSource;

    private SQLQueryFactory factory;

    @Override
    public List<Article> getArticles() {
        if(factory == null){
            factory = new SQLQueryFactory(new Configuration(new MySQLTemplates()), dataSource);
        }

        QArtikel artikel = QArtikel.artikel;
        List<String> names = factory.select(artikel.artikeltyp).from(artikel).fetch();

        return names.stream().map(Article::new).collect(Collectors.toList());
    }
}
如您所见,我已经尝试了用户G.Demecki的解决方案,将两个Jersey依赖项包含在我的servlet中,但没有成功。我还尝试了Oracle发布的,发布在。但这对我来说并不管用

我还看到了一个解决方案,您可以在中为HK2运行时指定从类型到实例的绑定。我承认我没有尝试过,因为我认为必须通过编程注册要注入的实例,这完全是对DI背后的想法的胡说八道

但还有另一个问题。如果我将服务类中的DataProvider声明修改为

private DataProvider dataProvider = new SQLDataProvider();
CDI的问题消失了,但是抛出了一个NPE,因为我试图从JNDI获取的数据源没有注入到SQLDataProvider的实例中。因此,JavaEE的资源注入似乎在JAX-RS容器中也不起作用。对于这个问题,我在研究期间没有找到任何可能的解决办法

我希望有人能告诉我,为了使CDI和资源注入与JAX-RS一起工作,我需要在配置中更改什么,因为目前,这对我来说似乎是不可能的

问候 帕斯卡参见以下问题:

按照上述问题的建议,尝试查找您的
资源
其他属性,如
mappedName

 @Resource(mappedName = "jdbc/db_1")
 private DataSource dataSource;

实际上是JNDI中的jdbc/db_1。我想您已经在GlassFish上设置了数据源。您是否已通过GlassFish JNDI浏览器验证这是正确的JNDI地址?我对
@Path
注释
SQLDataProvider
有点困惑。另外,
@ApplicationScoped
@Singleton
似乎有点多余。是的,数据源在该名称下可用。我只是在JDBC资源下的管理控制台中检查了它。在相应的列表中,会出现我的数据源,并声明它在JNDI名称jdbc/db_1下可用。我还使用“asadmin list jndi entries--context jdbc”命令检查了它。@Path注释来自Oracle在此链接下发布的解决方案,感谢您的提示!但是,它似乎不适合我使用注释(当我显式打开上下文并加载数据源时,它工作得很好-但我仍然希望使用注释使其工作)。。。目前,我认为Jersey的ServletContainer完全把事情搞砸了,但我很高兴有一位这方面的专家纠正我,并告诉我它不起作用的真正原因。o为什么您使用Jersey ServletContainer,甚至包括Jersey 1.x。GlassFish 4.*与Jersey 2一起发货。参见第29.2.7节,我没有使用Jersey 1.x的东西。ServletContainer仍然包含在Jersey 2.x中,正如您在这里看到的关于Servlet容器的使用:该容器只是一种Servlet2+兼容方式,用于在web.xml()中连接Jersey。我这样做是因为如果我还可以在web.xml文件中指定资源类,我不想创建应用程序子类。您是否尝试过坚持使用JavaEEAPI并使用它来引导REST应用程序:
javax.ws.rs.core.application/*
@Path("/")
@RequestScoped
public class Service {

    @Inject
    private DataProvider dataProvider;

    @Path("test")
    @GET
    @Produces({MediaType.APPLICATION_JSON})
    public Response test(){
        return Response.ok(dataProvider.getArticles()).build();
    }

}
@Default
@ApplicationScoped
@Singleton
@Path("singleton-bean")
public class SQLDataProvider implements DataProvider {

    @Resource(name = "jdbc/db_1")
    private DataSource dataSource;

    private SQLQueryFactory factory;

    @Override
    public List<Article> getArticles() {
        if(factory == null){
            factory = new SQLQueryFactory(new Configuration(new MySQLTemplates()), dataSource);
        }

        QArtikel artikel = QArtikel.artikel;
        List<String> names = factory.select(artikel.artikeltyp).from(artikel).fetch();

        return names.stream().map(Article::new).collect(Collectors.toList());
    }
}
javax.servlet.ServletException: A MultiException has 3 exceptions.  They are:
    1. org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=DataProvider,parent=SkiBazaarService,qualifiers={},position=-1,optional=false,self=false,unqualified=null,158365417)
    2. java.lang.IllegalArgumentException: While attempting to resolve the dependencies of org.skiclub.service.SkiBazaarService errors were found
    3. java.lang.IllegalStateException: Unable to perform operation: resolve on org.skiclub.service.SkiBazaarService
private DataProvider dataProvider = new SQLDataProvider();
 @Resource(mappedName = "jdbc/db_1")
 private DataSource dataSource;