Как я могу интегрировать Джерси с TomEE/openEJB

Я обновляю код, который использует JAX-RS для запуска на сервере Apache TomEE. К сожалению, это вызывает ошибки, когда я пытаюсь использовать Джерси с TomEE.

Я использую eclipse и включаю фасет проекта JAX-RS. Это указывает на библиотеку Джерси. Я также переместил библиотеки Джерси в каталог /lib/, чтобы попытаться решить проблему безрезультатно. Сервер выдает следующую ошибку:

May 14, 2012 6:26:44 AM com.sun.jersey.api.core.ScanningResourceConfig logClasses
INFO: Provider classes found:
class org.codehaus.jackson.jaxrs.JsonParseExceptionMapper
class org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider
class org.codehaus.jackson.jaxrs.JsonMappingExceptionMapper
class org.codehaus.jackson.jaxrs.JacksonJsonProvider
May 14, 2012 6:26:44 AM org.apache.catalina.core.ApplicationContext log
SEVERE: StandardWrapper.Throwable
java.lang.RuntimeException: javax.naming.NameNotFoundException: Name [com] is not bound in this Context. Unable to find [com].
at com.sun.jersey.server.impl.cdi.CDIExtension.getInitializedExtension(CDIExtension.java:177)
at com.sun.jersey.server.impl.cdi.CDIComponentProviderFactory.<init>(CDIComponentProviderFactory.java:92)
at com.sun.jersey.server.impl.cdi.CDIComponentProviderFactoryInitializer.initialize(CDIComponentProviderFactoryInitializer.java:75)
at com.sun.jersey.spi.container.servlet.WebComponent.configure(WebComponent.java:576)
at com.sun.jersey.spi.container.servlet.ServletContainer$InternalWebComponent.configure(ServletContainer.java:311)
at com.sun.jersey.spi.container.servlet.WebComponent.load(WebComponent.java:608)
at com.sun.jersey.spi.container.servlet.WebComponent.init(WebComponent.java:210)
at com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:373)
at com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:556)
at javax.servlet.GenericServlet.init(GenericServlet.java:160)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1266)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1185)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1080)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5015)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5302)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1566)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1556)
at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: javax.naming.NameNotFoundException: Name [com] is not bound in this Context. Unable to find [com].
at org.apache.naming.NamingContext.lookup(NamingContext.java:820)
at org.apache.naming.NamingContext.lookup(NamingContext.java:168)
at org.apache.naming.SelectorContext.lookup(SelectorContext.java:158)
at javax.naming.InitialContext.lookup(Unknown Source)
at com.sun.jersey.server.impl.cdi.CDIExtension$2.stepInto(CDIExtension.java:290)
at com.sun.jersey.server.impl.cdi.CDIExtension.diveIntoJNDIContext(CDIExtension.java:267)
at com.sun.jersey.server.impl.cdi.CDIExtension.lookupJerseyConfigJNDIContext(CDIExtension.java:287)
at com.sun.jersey.server.impl.cdi.CDIExtension.getInitializedExtension(CDIExtension.java:175)
... 22 more 

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
  <display-name>tomeeTest3</display-name>

  <servlet>
    <description>JAX-RS Tools Generated - Do not modify</description>
    <servlet-name>JAX-RS Servlet</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>JAX-RS Servlet</servlet-name>
    <url-pattern>/jaxrs/*</url-pattern>
  </servlet-mapping>
</web-app>

Кто-нибудь знает, как я могу сделать эту работу? Я также хотел бы использовать сервер tomEE + Jax-rs, но он, похоже, не распознает аннотации Jackson.

EDIT: Я думаю, проблема в том, что CDI openEJB противоречит CDI, который поставляется с Джерси. Я не знаю, как это исправить.

Ответ 1

ВОСКРЕСЕНИЕ! На всякий случай кто-то все еще сталкивается с этой проблемой.

У меня было приложение с Джерси, которое работало в Tomcat, персик и сильно взорвалось именно таким образом, когда я переместил его в TomEE. Проблема в том, что TomEE уже имеет собственную реализацию JAX-RS (tomee-jaxrs-1.5.0 на момент написания этой статьи), которая конфликтует с jersey-bundle jars.

Все, что мне нужно было сделать, чтобы избавиться от этой проблемы, - это удалить jersey jars и прокомментировать выражение и сопоставление сервлета в web.xml

Дайте ему перезапустить и альта! Просто помните, что URL-адреса будут немного отличаться. Например, при установке jersey по умолчанию у вас может быть http://localhost/rest/represent/me, и когда вы переместите то же приложение в TomEE, оно будет http://localhost/represent/me

Если вы используете IDE, например eclipse, вам может показаться, что вы не можете найти банки, просто зайдите в свойства проекта и установите целевое время выполнения на TomEE (вам нужно будет добавить экземпляр сервера) и вам должно быть хорошо идти.

Поделитесь и наслаждайтесь.

Ответ 2

Я тоже столкнулся с этой проблемой с этим единственным исключением, и, к сожалению, ответ grauwulf не работал у меня.

В моем случае у меня есть Tomee + 1.5.2, Jersey 1.1x, и я также использую Spring 3.x.

Исправление было довольно простым:

  • Найти файл Tomee system.properties ({tomee}/conf/system.properties по умолчанию).
  • Добавить com.sun.jersey.server.impl.cdi.lookupExtensionInBeanManager=true

Оттуда это просто сработало для меня. Чтобы отдать должное, я нашел его в этом сообщении .

Интересно, что я также предпочитаю избегать загромождения моей папки {tomee}/lib с моими военными зависимостями, поэтому я также обнаружил, что вы можете легко добавить дополнительную библиотеку, изменив {tomee}/conf/tomee.xml и добавив следующий node (внутри корень <tomee /> node):

<tomee>
  <Service
    id="extra-libs-enricher"
    class-name="org.apache.openejb.assembler.classic.enricher.AdditionalLibClassLoaderEnricherObserver">
      path = /path/to/your/libs
  </Service>
</tomee>

С этим Service, имя которого произвольно, вы не можете передать path, в этот момент он по умолчанию равен "additional-lib". Прошедший путь будет использоваться по умолчанию, но если он не является каталогом, он возвращается к системному свойству, которое может быть добавлено в файл system.properties. Системное свойство: openejb.enricher.additional-lib.

openejb.enricher.additional-lib=/fallback/path/to/your/libs

Это системное свойство проверяется только в том случае, если путь, переданный в Service или его значение по умолчанию, не работает и только если в файле tomee.xml помещен Service. Его id не имеет значения.

Ответ 3

Просто натолкнулся на эту проблему: TomEE + Jersey... проблема в том, что я использовал TomEE в Eclipse "Использовать метаданные рабочей области"... и как-то, когда это настроено так, конфигурации сервера пропускают несколько деталей конфигураций TomEE (а именно conf/system.properties - где мы объявляем: "com.sun.jersey.server.impl.cdi.lookupExtensionInBeanManager = true" ). Когда я изменил его на "Использовать установку Tomcat", проблема исчезла. Вы можете настроить это, дважды щелкнув сервер TomEE в Eclipse и выбрав "Использовать установку Tomcat", как показано на следующем изображении:

enter image description here

Ответ 4

Вы должны добавить пакет классов Provider в качестве параметра сервлета:

<servlet>
 <servlet-name>ServletAdaptor</servlet-name>
 <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
  <init-param>
   <param-name>com.sun.jersey.config.property.packages</param-name>
   <param-value>your.package.name</param-value>
  </init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
 <servlet-name>ServletAdaptor</servlet-name>
 <url-pattern>/jaxrs/*</url-pattern>
</servlet-mapping>

Ваши классы-поставщики должны выглядеть так:

package your.package.name;

@Path("/test")
public class StatsServlet {
    @PUT
    @Produces(MediaType.TEXT_HTML)
    public String doPutHtml() {
        return "Hello!";
    }
}

Ответ 5

Я проследил его, и pickypg верен. Мне удалось заставить это работать с TomEE 1.5.2 с помощью модуля tomee-maven-plugin. Я точно не понял, но эта проблема возникает после того, как трикотаж показывает, что есть менеджер bean в java: comp/BeanManager и пытается найти контекст.

<plugin>
    <groupId>org.apache.openejb.maven</groupId>
    <artifactId>tomee-maven-plugin</artifactId>
    <version>1.0.1</version>
    <configuration>
        <tomeeHttpPort>${http.port}</tomeeHttpPort>
        <tomeeVersion>1.5.2</tomeeVersion>
        <args>-Dcom.sun.jersey.server.impl.cdi.lookupExtensionInBeanManager=true</args>
    </configuration>
</plugin>

Вот выдержки из трикотажа, где он сталкивается с проблемой.

 public CDIComponentProviderFactory(Object bm, ResourceConfig rc, WebApplication wa) {
        beanManager = (BeanManager)bm;
        // work around proxying bug in Weld
        if (CDIExtension.lookupExtensionInBeanManager) {
            extension = Utils.getInstance(beanManager, CDIExtension.class);
        }
        else {
            // NOTE THIS IS WHAT IS BEING EXECUTED WHEN FLAG IS SET TO FALSE
            extension = CDIExtension.getInitializedExtension();
        }
        extension.setWebApplication(wa);
        extension.setResourceConfig(rc);
    }

/*
 * Returns the instance of CDIExtension that was initialized previously in this same thread, if any.
 */
public static CDIExtension getInitializedExtension() {
    try {
        InitialContext ic = InitialContextHelper.getInitialContext();
        if (ic == null) {
            throw new RuntimeException();
        }
        return (CDIExtension)lookupJerseyConfigJNDIContext(ic).lookup(JNDI_CDIEXTENSION_NAME);
    } catch (NamingException ex) {
        throw new RuntimeException(ex);
    }
}

...

/*
 * Setting this system property to "true" will force use of the BeanManager to look up the bean for the active CDIExtension,
 * rather than going through a thread local.
 */
private static final String LOOKUP_EXTENSION_IN_BEAN_MANAGER_SYSTEM_PROPERTY = "com.sun.jersey.server.impl.cdi.lookupExtensionInBeanManager";

public static final boolean lookupExtensionInBeanManager = getLookupExtensionInBeanManager();

private static boolean getLookupExtensionInBeanManager() {
    return Boolean.parseBoolean(System.getProperty(LOOKUP_EXTENSION_IN_BEAN_MANAGER_SYSTEM_PROPERTY, "false"));
}

Ответ 6

Я смог это сделать, и если кто-то ищет решение, что я сделал

Это то, что я сделал: * im с использованием NetBeans 7.3.1 * Я добавил следующие строки в Tomee\conf\system.properties - > com.sun.jersey.server.impl.cdi.lookupExtensionInBeanManager = true * Я добавил библиотеки трикотажа из NetBeans, которые все * Обратите внимание, что библиотеки находятся в WEB-INF\lib моих приложений * Дополнительная информация я даже мог использовать Mojarra для JSF, если кто-то заинтересован, я могу рассказать вам, как