如何将Jersey与TomEE / openEJB集成

时间:2012-05-14 12:41:43

标签: java java-ee jersey openejb apache-tomee

我正在升级使用Jersey JAX-RS在Apache TomEE服务器上运行的代码。不幸的是,当我尝试使用Jersey和TomEE时,它会抛出错误。

我正在使用eclipse并且打开了JAX-RS项目方面。它指向泽西图书馆。我还将Jersey库移动到/ 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服务器,但似乎没有认识到杰克逊的注释。

编辑:我认为问题在于openEJB CDI与Jersey附带的CDI相冲突。我不知道如何解决这个问题。

6 个答案:

答案 0 :(得分:11)

RESURRECTION!以防任何人仍然遇到这个问题。

我有一个运行在Tomcat peachy敏锐的Jersey应用程序,并且当我将它移动到TomEE时以这种方式爆炸。问题是TomEE已经有了自己的JAX-RS实现(在撰写本文时为tomee-jaxrs-1.5.0),这与jersey-bundle jar冲突。

我要做的就是摆脱这个问题就是删除jersey jars并在web.xml中注释掉servlet声明和映射

重启,中提琴!请记住,URL会略有不同。例如,在默认的球衣安装上,您可能有http://localhost/rest/represent/me,当您将同一个应用移动到TomEE时,它将是http://localhost/represent/me

如果您正在使用像eclipse这样的IDE,可能会因为无法找到jar而咆哮,只需进入项目属性并将目标运行时设置为TomEE(您必须添加服务器实例)和你应该好好去。

分享并享受。

答案 1 :(得分:8)

我也遇到过这个问题,但是不幸的是grauwulf的答案对我不起作用。

在我的情况下,我有Tomee + 1.5.2,Jersey 1.1x,我也使用Spring 3.x.

修复实际上非常简单:

  1. 查找Tomee system.properties文件(默认为{tomee}/conf/system.properties)。
  2. 添加com.sun.jersey.server.impl.cdi.lookupExtensionInBeanManager=true
  3. 从那以后,它对我有用。为了给予应有的信用,我在blog post上找到了它。

    有趣的是,我还希望避免使用war的依赖项来混淆我的{tomee}/lib文件夹,因此我还发现您可以通过修改{tomee}/conf/tomee.xml并添加以下节点来轻松添加额外的lib (在根<tomee />节点内):

    <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的路径或其默认值不能正常工作时才会检查此系统属性仅当Service放置在{{ 1}}文件。它的tomee.xml无关紧要。

答案 2 :(得分:1)

刚遇到这个问题:TomEE + Jersey ......问题是我在Eclipse中使用TomEE“使用工作空间元数据”......不知何故,当这样配置时,服务器配置错过了TomEE配置的几个细节(即conf / system.properties - 我们声明的地方:“com.sun.jersey.server.impl.cdi.lookupExtensionInBeanManager = true”)。当我将其更改为“使用Tomcat安装”时,问题就消失了。您可以通过在Eclipse中双击TomEE服务器并选择“使用Tomcat安装”来配置它,如下图所示:

enter image description here

答案 3 :(得分:0)

您应该将Provider类的包作为参数添加到servlet中:

<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!";
    }
}

答案 4 :(得分:0)

我追查它并且pickypg是正确的。我能够使用tomee-maven-plugin让它与TomEE 1.5.2一起使用。我还没弄清楚,但是这个问题发生在jersey之后,在java:comp / BeanManager中有一个bean管理器,并尝试查找上下文。

<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"));
}

答案 5 :(得分:0)

我能够做到这一点,如果有人正在寻找我所做的解决方案

这就是我所做的: *我正在使用NetBeans 7.3.1 *我在Tomee \ conf \ system.properties中添加了以下行 - &gt; com.sun.jersey.server.impl.cdi.lookupExtensionInBeanManager = true *我添加了NetBeans的jersey库 *请注意,这些库位于我的应用程序的WEB-INF \ lib中 *附加信息我甚至可以使用Mojarra for JSF如果有人有兴趣我可以告诉你如何