Friday, February 3, 2012

Using P6 R8 Web Services in Web Applications (Weblogic)

If you are familiar with Primavera P6 development, you would know about the "P6 Web Services", which in practice, is a web application exposing the functionality of the Integration API through web services. Recently I had to consume a bunch of these web services in a Web Application (to be deployed on Weblogic AS). If you take a look at the Demo provided by the Web Services Installation (a Java swing application that creates a sample project), you would notice the libraries required to consume such services, the most important of which are cxf-bundle, p6ws-jaxws-client and osdt-*. After developing a pretty simple application and deploying it on Weblogic AS, I hit the following error:
weblogic.wsee.jaxws.spi.ClientInstanceInvocationHandler cannot be cast to org.apache.cxf.frontend.ClientProxy


After lots of googling, I finally found the problem. The CXF libraries used in the web service stubs are being overridden by Weblogic AS which causes the problem. The solution is to add the package preference setting in weblogic.xml file in your application (if you don't have one create it using File->New->Weblogic Deployment Descriptor). So your weblogic.xml should look something like:

<?xml version = '1.0' encoding = 'windows-1252'?>
<weblogic-web-app xmlns="http://xmlns.oracle.com/weblogic/weblogic-web-app" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd http://xmlns.oracle.com/weblogic/weblogic-web-app http://xmlns.oracle.com/weblogic/weblogic-web-app/1.2/weblogic-web-app.xsd">
  <context-root>yourapp</context-root>
  <container-descriptor>
  <prefer-application-packages>
    <package-name>org.apache.cxf.binding.soap.saaj.*</package-name>
    <package-name>org.apache.cxf.endpoint.*</package-name>
    <package-name>org.apache.cxf.frontend.*</package-name>
    <package-name>org.apache.cxf.transport.http.*</package-name>
    <package-name>org.apache.cxf.interceptor.*</package-name>
    <package-name>org.apache.cxf.transports.http.configuration.*</package-name>
  </prefer-application-packages>
  </container-descriptor>
</weblogic-web-app>
This should resolve the library conflict. If you get an error like this:
This class does not support SAAJ 1.1 weblogic
The Reason for the problem is Weblogic’s default SAAJ implementation, so you need to override the properties to use a better implementation weblogic.xml.saaj  package. You can do that by adding the following parameters to your Weblogic startup script:
JAVA_OPTIONS= %JAVA_OPTIONS% -Djavax.xml.soap.MessageFactory=com.sun.xml.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl -Djavax.xml.soap.SOAPConnectionFactory=weblogic.wsee.saaj.SOAPConnectionFactoryImpl

10 comments:

  1. Hi Danesh,

    I ran into the same error using Primavera CMWS. I created the weblogic.xml and placed this in my WEB-INF folder. I still see the same error. I see this message on deployment " "

    Thank you
    Rudy

    ReplyDelete
    Replies
    1. Msg was cut:
      Filtering class loader configuration ignored for web module myapp.war of application myapp

      Delete
  2. Hi Rudy,
    Can you post the full stack trace of the exception?

    ReplyDelete
  3. weblogic.wsee.jaxws.spi.ClientInstanceInvocationHandler cannot be cast to org.apache.cxf.frontend.ClientProxy
    java.lang.ClassCastException: weblogic.wsee.jaxws.spi.ClientInstanceInvocationHandler cannot be cast to org.apache.cxf.frontend.ClientProxy
    at org.apache.cxf.frontend.ClientProxy.getClient(ClientProxy.java:93)
    at com.pcm.company.CompanyServiceImpl.createCompanyServicePort(Unknown Source)
    at com.pcm.company.CompanyServiceImpl.wsRead(Unknown Source)
    at com.pcm.company.CompanyServiceImpl.readCompanies(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at weblogic.wsee.jaxws.WLSInstanceResolver$WLSInvoker.invoke(WLSInstanceResolver.java:92)
    at weblogic.wsee.jaxws.WLSInstanceResolver$WLSInvoker.invoke(WLSInstanceResolver.java:74)

    ReplyDelete
  4. Seems like the package preference has not been configured, did you add the org.apache.cxf.frontend.* to weblogic.xml? Also check whether the libraries are attached to your web app archive. Also clear the Weblogic AS cache (clear /servers//tmp) and restart the instance.

    ReplyDelete
  5. Hi Rudy,
    Have you been able to resolve the problem?

    ReplyDelete
  6. Hi I am facing same class cast issue on weblogic 10.3.6.0 server and It not getting resolved by your solution, Could you please help.

    ReplyDelete
  7. Hi Garima,
    Can you send me the stack trace of the exception? I believe its a library conflict issue.

    ReplyDelete
  8. weblogic.wsee.jaxws.spi.ClientInstanceInvocationHandler cannot be cast to org.apache.cxf.frontend.ClientProxy
    java.lang.ClassCastException: weblogic.wsee.jaxws.spi.ClientInstanceInvocationHandler cannot be cast to org.apache.cxf.frontend.ClientProxy
    at org.apache.cxf.frontend.ClientProxy.getClient(ClientProxy.java:93)
    at res.ResourceIntegrationImpl.initializeWebServices(ResourceIntegrationImpl.java:536)
    at res.ResourceIntegrationImpl.syncResource(ResourceIntegrationImpl.java:112)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at weblogic.wsee.jaxws.WLSInstanceResolver$WLSInvoker.invoke(WLSInstanceResolver.java:92)
    at weblogic.wsee.jaxws.WLSInstanceResolver$WLSInvoker.invoke(WLSInstanceResolver.java:74)
    at com.sun.xml.ws.server.InvokerTube$2.invoke(InvokerTube.java:151)
    at com.sun.xml.ws.server.sei.EndpointMethodHandlerImpl.invoke(EndpointMethodHandlerImpl.java:268)
    at com.sun.xml.ws.server.sei.SEIInvokerTube.processRequest(SEIInvokerTube.java:100)
    at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:866)
    at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:815)
    at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:778)
    at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:680)
    at com.sun.xml.ws.server.WSEndpointImpl$2.process(WSEndpointImpl.java:403)
    at com.sun.xml.ws.transport.http.HttpAdapter$HttpToolkit.handle(HttpAdapter.java:539)
    at com.sun.xml.ws.transport.http.HttpAdapter.handle(HttpAdapter.java:253)
    at com.sun.xml.ws.transport.http.servlet.ServletAdapter.handle(ServletAdapter.java:140)
    at weblogic.wsee.jaxws.WLSServletAdapter.handle(WLSServletAdapter.java:171)
    at weblogic.wsee.jaxws.HttpServletAdapter$AuthorizedInvoke.run(HttpServletAdapter.java:708)
    at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363)
    at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:146)
    at weblogic.wsee.util.ServerSecurityHelper.authenticatedInvoke(ServerSecurityHelper.java:103)
    at weblogic.wsee.jaxws.HttpServletAdapter$3.run(HttpServletAdapter.java:311)
    at weblogic.wsee.jaxws.HttpServletAdapter.post(HttpServletAdapter.java:336)
    at weblogic.wsee.jaxws.JAXWSServlet.doRequest(JAXWSServlet.java:99)
    at weblogic.servlet.http.AbstractAsyncServlet.service(AbstractAsyncServlet.java:99)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
    at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
    at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
    at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:301)
    at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:184)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3732)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3696)
    at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
    at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
    at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2273)
    at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2179)
    at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1490)
    at weblogic.work.ExecuteThread.execute(ExecuteThread.java:256)
    at weblogic.work.ExecuteThread.run(ExecuteThread.java:221)

    ReplyDelete
  9. Please check for org.apache.cxf.frontend.ClientProxy in the jars you've included in you application. The P6WS libraries probably include that class already. Off the top of my head it's cxf-bundle-*.jar. You already have the class you need in the P6WS libs, so you can remove the one you've included.

    ReplyDelete