Внедрение EJB, PersistenceContext в ресурс Джерси без состояния

#jakarta-ee #jpa #jboss #jersey #jersey-2.0

#джакарта-ee #jpa #jboss #джерси #джерси-2.0

Вопрос:

Ни @PersistenceContext, ни @EJB не вводятся в мой ресурс Джерси EJB. Я могу получить доступ к своим конечным точкам JAX-RS. Может ли Джерси не получить доступ к встроенному поставщику JPA (спящий режим)?

У меня есть простая война, развернутая в JBoss EAP 6.2 (КАК 7.2.2). Я удалил встроенные библиотеки RESTEasy из JBoss и упаковал Jersey 2.10.1 с моим приложением. Я включил последнюю версию Джерси 2 в свой pom.xml . Это моя единственная объявленная зависимость.

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

У меня есть @Stateless ресурс JAX-RS, который правильно обслуживается Джерси.

 @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 — это простое расширение из org.glassfish.jersey.server.ResourceConfig без содержимого. У него есть аннотация @ApplicationPath.

Я знаю, что JPA и модуль сохранения корректно работают в WAR в целом. У меня есть таймер EJB, который запускается и корректно может использовать введенный EntityManager. Это только в пределах ресурса Джерси, что вещи не вводятся.

Я полагаю, что проблема связана с зависимостями, потому что я работаю на JBoss или, возможно, мой класс приложений JAX-RS каким-то образом неполон. Я бился головой о стол в течение 3 дней (многому учась в процессе!), Поэтому я действительно ценю помощь.


Ранее я думал, что сообщение журнала при запуске Джерси о том, что Джерси не может найти метод javax.persistence.PersistenceContext.value() , было хорошей подсказкой. После просмотра кода Джерси кажется, что это действительно не важно.

Комментарии:

1. Я подтвердил, что точная война корректно работает в Glassfish 3.1.2.2, и EntityManager введен, как и ожидалось. Так что это просто не работает с JBoss EAP 6.2 (или 6.1)

2. Я отказался от этого пути. Я так и не смог ввести свои ресурсы в Джерси в рамках EAP. Вместо этого я перешел на RESTEasy, который работает так, как ожидалось.

Ответ №1:

Поскольку у вас нет web.xml дескриптора, поэтому нет адаптера сервлета для обслуживания ваших ресурсов, вам может потребоваться использовать альтернативу JAX-RS, которая предоставляет ApplicationPath :

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

Возможно, вам потребуется переопределить методы getClasses и getSingletons .

Комментарии:

1. Спасибо за предложение. Тем не менее, у меня есть эта аннотация (и я соответствующим образом отредактировал свой вопрос). Я могу войти в URI (т. Е. Получить работу), но EntityManager просто не введен

Ответ №2:

Если вы уже используете EJBS или CDI, вам следует использовать EntityManager из EJBs / CDI, но не из ресурса 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, а последний метод используется для поиска EJB.