将EJB,PersistenceContext注入@Stateless Jersey资源

时间:2014-07-02 13:46:00

标签: java-ee jpa jboss jersey jersey-2.0

@PersistenceContext和@EJB都没有注入我的EJB Jersey资源。我可以访问我的JAX-RS端点。 Jersey可以访问内置的JPA提供程序(Hibernate)吗?

我有一个简单的WAR部署到JBoss EAP 6.2(AS 7.2.2)。我从JBoss中删除了内置的RESTEasy库,并在我的应用程序中打包了Jersey 2.10.1。我在pom.xml中添加了最新的Jersey 2版本。这是我唯一声明的依赖。

<dependencies>
    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-servlet</artifactId>
        <version>2.10.1</version>
    </dependency>
</dependencies>

我有一个@Stateless JAX-RS资源,由Jersey正确提供。

@Stateless
@Path("generic")
@LocalBean
public class GenericResource {
    @PersistenceContext(unitName = "TestWebAppPU")
    private EntityManager em;

    @GET
    @Produces("text/plain")
    public String get() {
        // em is null here
        // ...

正如您可能从代码注释中猜到的那样,未注入EntityManager。在其他测试中,我也看到@PersistenceUnit和@EJB没有被注入。

我没有web.xml,我的JAX-RS Application类是org.glassfish.jersey.server.ResourceConfig的简单扩展,没有内容。它确实有@ApplicationPath注释。

我知道JPA和持久性单元在WAR中正常工作。我有一个运行的计时器EJB,并且可以使用注入的EntityManager。只有泽西资源才能注入事物。

我认为这个问题与依赖关系有关,因为我在JBoss上运行,或者我的JAX-RS Application类在某种程度上是不完整的。我一直在桌子上敲了3天(虽然在这个过程中学到了很多东西!)所以我非常感谢你的帮助。


以前我认为泽西岛创业公司的日志消息是泽西岛找不到方法javax.persistence.PersistenceContext.value()是一个很好的线索。在浏览泽西岛代码之后,这似乎并不重要。

2 个答案:

答案 0 :(得分:0)

由于您没有web.xml描述符,因此没有servlet适配器为您提供资源,您可能需要使用JAX-RS替代方案,即提供ApplicationPath

@javax.ws.rs.ApplicationPath("application")
public class RestApplication extends javax.ws.rs.core.Application {
...  
}

您可能需要覆盖getClassesgetSingletons方法。

答案 1 :(得分:0)

如果您已经在使用EJB或CDI,则应使用EJB / CDI中的EntityManager,而不是RS资源。当然,这只是一个建筑的建议。

如果将资源注入您的球衣组件,我确实在使用CDI和注射球衣和jboss时遇到了麻烦。目前我正在使用一种解决方法,仍然试图弄清楚如何使CDI正常工作。

import java.util.HashSet;
import java.util.Set;

import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import javax.naming.InitialContext;

public class CDIBeanManagerImpl {

@Override
public void destroyRequestContext() {
    //CreationalContext is handled by a containter
}

@Override
public <T> T getBean(Class<T> clazz) {
    BeanManager beanManager = null;
    try {
        beanManager = (BeanManager) new InitialContext().lookup("java:comp/BeanManager");
    } catch (Exception ex) {
        throw new RuntimeException("Could not look up BeanManager", ex);
    }
    Bean<?> bean = beanManager.resolve(beanManager.getBeans(clazz));
    if (bean == null) {
        return null;
    }
    return (T) beanManager.getReference(bean, clazz, beanManager.createCreationalContext(bean));
}

@Override
public <T> Set<T> getBeans(Class<T> clazz) {
    BeanManager beanManager = null;
    try {
        beanManager = (BeanManager) new InitialContext().lookup("java:comp/BeanManager");
    } catch (Exception ex) {
        throw new RuntimeException("Could not look up BeanManager", ex);
    }
    Set<Bean<?>> beans = beanManager.getBeans(clazz);
    Set<T> instances = new HashSet<T>();
    for (Bean<?> bean : beans) {
        CreationalContext<?> creationalContext = beanManager.createCreationalContext(bean);
        T instance = (T) beanManager.getReference(bean, clazz, creationalContext);
        instances.add(instance);
    }
    return instances;
}

@Override
public void initRequestContext() {
    //CreationalContext is handled by a containter
}

@Override
public Object newJNDIInstance(String jndiName) {
    try {
        //Class<?> clazz = Class.forName(jndiName.substring(jndiName.indexOf("!") + 1));
        //return getBean(clazz);
        return new InitialContext().lookup(jndiName);
    } catch (Exception ex) {
        throw new RuntimeException(ex);
    }
}

}

前两个方法用于查找使用CDI的bean,最后一个方法用于查找EJB。