#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.