How can I integrate Jersey with TomEE / openEJB
Asked Answered
G

6

10

I am upgrading a code that uses Jersey JAX-RS to run on an Apache TomEE server. Unfortunately it throws errors when I try to use Jersey with TomEE.

I am using eclipse and have the JAX-RS project facet turned on. It points to the Jersey library. I have also moved the Jersey libraries into the /lib/ directory to try to solve the problem to no avail. The server throws the following error:

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>

Does anyone know how I might make this work? I'd also consider using the tomEE+ Jax-rs server, but it doesn't seem to recognize the Jackson annotations.

EDIT: I think the issue is that the openEJB CDI is conflicting with the CDI that comes with Jersey. I have no idea how to fix this.

Gundry answered 14/5, 2012 at 12:41 Comment(3)
could you post your web.xml file content?Parquetry
Greg - Did you ever solve this problem? I appear to be having the exact same issue.Postobit
Nope, I decided not to use TomEEGundry
U
12

RESURRECTION! Just in case anyone is still running into this problem.

I had a Jersey application that was running in Tomcat peachy keen and exploded in exactly this manner when I moved it it TomEE. The problem is that TomEE already has its own JAX-RS implementation (tomee-jaxrs-1.5.0 at the time of this writing), which conflicts with the jersey-bundle jars.

All I had to do to get rid of this problem was remove the jersey jars and comment out the servlet declaration and mapping in the web.xml

Give it a restart, and viola! Just remember that the URLs will be slightly different. For example, on a default jersey install you might have http://localhost/rest/represent/me and when you move that same app to TomEE it will be http://localhost/represent/me

If you're using an IDE like eclipse it might bark at you for not being able to find the jars, just go into the project properties and set the target runtime to TomEE (you will have to add a server instance) and you should be good to go.

Share and enjoy.

Uterus answered 26/11, 2012 at 16:30 Comment(5)
Can a few people confirm that this works? I'll mark it as the answer if they do.Gundry
I verified this fix. For expedience I simply removed the libraries from the war file and deployedPostobit
This can only be valid, if you try to use Jersey on the JAX-RS version of TomEE. The webprofile version has no JAX-RS included, so we need a different solution there.Wachter
@Jack, the profile releases are specific to their use. For the web profile you just need to include the Jersey jars, per usual. Best of luck.Uterus
I know, just pointing out you are probably using a different TomEE profile than Greg and me. I'm using the webprofile so I can add the JAX-RS implementation of my choice, but Jersey is not working (see my post below). I ended up using Resteasy on TomEE-webprofile and it's working fine now.Wachter
L
8

I too have run into this problem with that exact exception, and unfortunately grauwulf's answer did not work for me.

In my case, I have Tomee+ 1.5.2, Jersey 1.1x, and I am also using Spring 3.x.

The fix was actually quite simple:

  1. Find the Tomee system.properties file ({tomee}/conf/system.properties by default).
  2. Add com.sun.jersey.server.impl.cdi.lookupExtensionInBeanManager=true

From there, it just worked for me. To give the credit where it's due, I found it on this blog post.

Of interest, I also prefer to avoid cluttering my {tomee}/lib folder with my war's dependencies, so I have also found that you can easily add an extra lib by modifying {tomee}/conf/tomee.xml, and adding the following node (inside the root <tomee /> node):

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

With that Service, whose name is arbitrary, you can not pass a path, at which point it defaults to "additional-lib". The passed in path will be used by default, but if it is not a directory, then it will fall back to a system property, which can be added to the system.properties file. The system property is: openejb.enricher.additional-lib.

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

This system property is only checked if the path passed to Service, or its default value, does not work and only if a Service is placed in the tomee.xml file. Its id is irrelevant.

Legere answered 22/6, 2013 at 20:19 Comment(1)
I'm using Jersey 1.11 in my Maven 3 project and therefore in my packaged WAR. Using TomEE 1.5.2 webprofile I was able to add the com.sun.jersey.server.impl.cdi.lookupExtensionInBeanManager=true to my tomee system.properties and it just worked. Thanks! A shame the blog post you linked to doesn't provide more information as to how this was found and how it works. I suppose the property kind of speaks for itself.Museology
R
1

Just came across with this problem: TomEE + Jersey... the problem was that I was using TomEE in Eclipse "Use workspace metadata"... and somehow when configured like this the server configurations misses several details of the TomEE configs (namely the conf/system.properties - where we declare: "com.sun.jersey.server.impl.cdi.lookupExtensionInBeanManager=true"). When I changed it to "Use Tomcat installation", the problem went away. You can configure this by double-clicking the TomEE server in Eclipse and select "Use Tomcat installation", as seen in the following image:

enter image description here

Rochelrochell answered 4/8, 2013 at 20:44 Comment(0)
P
0

You should add the package of the Provider classes as a parameter to the 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>

Your provider classes should look like this:

package your.package.name;

@Path("/test")
public class StatsServlet {
    @PUT
    @Produces(MediaType.TEXT_HTML)
    public String doPutHtml() {
        return "Hello!";
    }
}
Parquetry answered 14/5, 2012 at 14:32 Comment(0)
T
0

I traced it down and pickypg is correct. I was able to get this to work with TomEE 1.5.2 using the tomee-maven-plugin. I haven't figured out exactly, but this problem occurs after the jersey figures out there is a bean manager at java:comp/BeanManager and tries to lookup the context.

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

Here are the excerts of jersey where it is running into the issue.

 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"));
}
Trilingual answered 6/9, 2013 at 23:31 Comment(0)
S
0

I was able to do that and if someone is looking for the solution that's what i did

This what i did: * i’m using NetBeans 7.3.1 * I added the following lines in Tomee\conf\system.properties –>com.sun.jersey.server.impl.cdi.lookupExtensionInBeanManager= true * I added jersey libraries from NetBeans that’s all * Note that the libraries are in WEB-INF\lib of my apps * Additional information i was even able to use Mojarra for JSF if someone is interested i can tell you how

Seizure answered 20/10, 2013 at 20:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.