miércoles, 12 de febrero de 2014

NoClassDefFoundError: org/apache/cxf/jaxrs/impl/MetadataMap in REST invokation from WebLogic with Jersey, CXF

Complete stack trace:

java.lang.NoClassDefFoundError: org/apache/cxf/jaxrs/impl/MetadataMap
        at org.apache.cxf.jaxrs.impl.UriBuilderImpl.(UriBuilderImpl.java:54)
        at org.apache.cxf.jaxrs.impl.RuntimeDelegateImpl.createUriBuilder(RuntimeDelegateImpl.java:87)
        at javax.ws.rs.core.UriBuilder.newInstance(UriBuilder.java:69)
        at javax.ws.rs.core.UriBuilder.fromUri(UriBuilder.java:80)
        at javax.ws.rs.core.UriBuilder.fromUri(UriBuilder.java:99)
        at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:662)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:844)
        at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:242)
        at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:216)
        at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:132)
        at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:338)
        at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:221)
        at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3284)
        at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3254)
        at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
        at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
        at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:57)
        at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2163)
        at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2089)
        at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2074)
        at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1513)
        at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:254)
        at weblogic.work.ExecuteThread.execute(ExecuteThread.java:256)
        at weblogic.work.ExecuteThread.run(ExecuteThread.java:221)

The WebLogic environment in which the error is generated contains the big bundle CXF jar (cxf-x.y.z.jar) in the classpath (which can't be removed right now).

As can be seen in the stack trace, the execution jumps from Jersey code to CXF code.

In this Jersey mailing list't thread, a similar problem is discused; one of the proposed solutions worked for me.

I created a ServletContextListener containing the following line in the contextInitialized method:

RuntimeDelegate.setInstance(new com.sun.jersey.server.impl.provider.RuntimeDelegateImpl());

Complete code:

package xyz;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.ws.rs.ext.RuntimeDelegate;

public class JerseyRuntimeDelegateEarlyRegistrationContextListener implements ServletContextListener {

@Override
public void contextDestroyed(ServletContextEvent arg0) {
}

@Override
public void contextInitialized(ServletContextEvent arg0) {
RuntimeDelegate.setInstance(new com.sun.jersey.server.impl.provider.RuntimeDelegateImpl());
}

}

Web.xml registration:

<web-app>
    <listener>
<listener-class>xyz.JerseyRuntimeDelegateEarlyRegistrationContextListener</listener-class>
</listener>