5 Replies Latest reply on Oct 23, 2009 9:07 AM by Alexandros Karypidis

    HTTP conduit configuration for de-coupeld end-points

    Alexandros Karypidis Novice

      Hi,

      I have a rather simple (I hope) problem trying to setup a WS-RM client as follows:

      I need a separate connection to be used for the incoming traffic (de-coupled endpoint) towards the client (the CXF configuration to do this is explained here: http://cxf.apache.org/docs/configuration-of-runtime-constructed-objects.html).

      My problem is this:

      While creating the client proxy, CXF also tries to create the endpoint for receiving replies. Unfortunately it uses Jetty (as it is not aware that it is running in JBoss) and I get a ClassNotFoundException (see log below and notice how the HTTPConduit class tries to initialize and HTTP engine using Jetty).

      11:45:57,875 INFO [ReflectionServiceFactoryBean] Creating Service {http://messaging.cmr/}AsyncMessagingService from WSDL: http://localhost:8001/wls-cxf.wsrm.recipient-war/services/AsyncMessagingService?wsdl
      11:45:58,343 INFO [HTTPConduit] creating decoupled endpoint: http://localhost:9999/decoupled_endpoint
      11:45:58,359 ERROR [[DebugServlet]] Servlet.service() for servlet DebugServlet threw exception
      java.lang.ClassNotFoundException: org.mortbay.jetty.Connector from BaseClassLoader@1816fb6{VFSClassLoaderPolicy@cd429b{...
       at org.jboss.classloader.spi.base.BaseClassLoader.loadClass(BaseClassLoader.java:448)
       at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
       at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
       at org.apache.cxf.transport.http_jetty.JettyHTTPServerEngineFactory.createJettyHTTPServerEngine(JettyHTTPServerEngineFactory.java:217)
       at org.apache.cxf.transport.http_jetty.JettyHTTPDestination.retrieveEngine(JettyHTTPDestination.java:114)
       at org.apache.cxf.transport.http_jetty.JettyHTTPDestination.finalizeConfig(JettyHTTPDestination.java:142)
       at org.apache.cxf.transport.http_jetty.JettyHTTPTransportFactory.createDestination(JettyHTTPTransportFactory.java:123)
       at org.apache.cxf.transport.http_jetty.JettyHTTPTransportFactory.getDestination(JettyHTTPTransportFactory.java:103)
       at org.apache.cxf.transport.http.HTTPConduit.getDestination(HTTPConduit.java:966)
       at org.apache.cxf.transport.http.HTTPConduit.setUpDecoupledDestination(HTTPConduit.java:943)
       at org.apache.cxf.transport.http.HTTPConduit.getBackChannel(HTTPConduit.java:747)
      


      How can I configure CXF to delegate this task to JBoss? For example, to have JAX-WS web services published on JBoss, you need to configure an invoker from the JBoss integration layer:

      <jaxws:endpoint id='AsyncMessaging'
       address='http://localhost:7180/jboss-cxf.wsrm.recipient/AsyncMessagingService'
       implementor='svc.impl.messaging.AsyncMessagingServiceImpl'>
       <jaxws:invoker>
       <bean class='org.jboss.wsf.stack.cxf.InvokerJSE' />
       </jaxws:invoker>


      I hope somebody can point me in the right direction? My jbossws-cxf.xml currenty looks like this:

      <cxf:bus>
       <cxf:features>
       <cxf:logging />
       <wsa:addressing />
       <wsrm-mgr:reliableMessaging>
       <wsrm-policy:RMAssertion>
       <wsrm-policy:BaseRetransmissionInterval
       Milliseconds="4000" />
       <wsrm-policy:AcknowledgementInterval
       Milliseconds="2000" />
       </wsrm-policy:RMAssertion>
       <wsrm-mgr:destinationPolicy>
       <wsrm-mgr:acksPolicy intraMessageThreshold="0" />
       </wsrm-mgr:destinationPolicy>
       </wsrm-mgr:reliableMessaging>
       </cxf:features>
       </cxf:bus>
      
       <http:conduit
       name="{http://messaging.cmr/}AsyncMessagingImplPort.http-conduit">
       <http:client DecoupledEndpoint="http://localhost:9999/decoupled_endpoint" />
       </http:conduit>
      


        • 1. Re: HTTP conduit configuration for de-coupeld end-points
          Richard Opalka Master

           

          "karypid" wrote:

          While creating the client proxy, CXF also tries to create the endpoint for receiving replies. Unfortunately it uses Jetty (as it is not aware that it is running in JBoss) and I get a ClassNotFoundException (see log below and notice how the HTTPConduit class tries to initialize and HTTP engine using Jetty).

          Yes, this is how CXF WS-RM client works.
          "karypid" wrote:

          How can I configure CXF to delegate this task to JBoss? For example, to have JAX-WS web services published on JBoss, you need to configure an invoker from the JBoss integration layer:

          <jaxws:endpoint id='AsyncMessaging'
           address='http://localhost:7180/jboss-cxf.wsrm.recipient/AsyncMessagingService'
           implementor='svc.impl.messaging.AsyncMessagingServiceImpl'>
           <jaxws:invoker>
           <bean class='org.jboss.wsf.stack.cxf.InvokerJSE' />
           </jaxws:invoker>



          There's no way how you could achieve it ATM :(
          Your usecase is really advanced and we don't provide SPI or integration point for it.
          JAX-WS spec tries to solve this 'usecase' with it's
          Endpoint.publish(String url, Class endpointImpl) but this usecase
          is broken for server side IMHO.

          Your only option ATM is to configure jbossws-cxf classpath properly to have myssing Jetty classes visible.

          • 3. Re: HTTP conduit configuration for de-coupeld end-points
            Alexandros Karypidis Novice

            Actually, I need a little bit more help. I though I'd easily move on by putting jetty-6.1.19.jar in WEB-INF/lib.

            However, the class-loader active at the time can't "see" that folder and I still get the ClassNotFound exception.

            I'm 100% certain the library is available to my war, because I access the class from code right before I attempt to initialize the port:

             // I put the line below to demonstrate Jetty is available
             org.mortbay.jetty.Server server = new org.mortbay.jetty.Server(1234);
             org.mortbay.jetty.Connector c[] = server.getConnectors();
             System.err.println("Connectors found: " + c.length);
            
             // The above prints that "Connectors found: 1"
            
             AsyncMessagingService ams = new AsyncMessagingService(wsdlURL, svcName);
             AsyncMessaging am = ams.getAsyncMessagingImplPort();
             // The call below throws the exception for org.mortbay.jetty.Connector
             // which was just used above
             am.deliver("This is a test");
            


            The code above is in a doGet() method of a "DebugServlet" class I put together to do a quick test. Exception is the same.

            So where would I put the jetty jars to make sure the CXF of JBoss can see them?

            Please note that I don't embed the entire CXF in my war; instead I use a JBoss 5.1 instance where the native stack has been replaced with the CXF one. Here are the relevant messages from startup:

            14:48:59,706 INFO [WebService] Using RMI server codebase: http://localhost:8183/
            14:49:04,933 INFO [AbstractServerConfig] JBoss Web Services - CXF Server
            14:49:04,933 INFO [AbstractServerConfig] 3.2.0.GA


            I took jetty jars straight from a CXF 2.2.3 download, which is the same version used by your 3.2.0 integration.


            • 5. Re: HTTP conduit configuration for de-coupeld end-points
              Alexandros Karypidis Novice

               

              "richard.opalka@jboss.com" wrote:
              Put jetty.jar to jbossws.deployer directory


              ...and of course, now it works. Thank you again!