7 Replies Latest reply on Jun 13, 2012 10:43 AM by asoldano

    Bizzare host re-write in JAX-WS client on JB7.0.2

    benze

      Hi,

       

      I've run into a strange issue with JB7.0.2.FINAL with a JAX-WS client that is getting its destination address rewritten.  The issue is not unsimilar to https://community.jboss.org/thread/164507?tstart=0 or https://issues.jboss.org/browse/JBWS-3260.  I don't know if this is a bug or rather if it is a configuration problem on my side.

       

      I have created a JAX-WS WebService which encompases a client to communicate with another webservice.  When my WS first calls the client, I see the following in my log file and the client connects without problems.

       

      {code}

      14:44:11,500 INFO  [org.apache.cxf.service.factory.ReflectionServiceFactoryBean] (http--0.0.0.0-8080-1) Creating Service {http://www.mydom.ca/AgmtProdOpers/LoanAgreementMgmt/V1}LoanAgreementMgmtHttpService from WSDL: http://server1.npr.local/tu/LoanAgreementMgmt/V1?wsdl

      14:44:15,377 INFO  [org.jboss.wsf.stack.cxf.transport.AddressRewritingEndpointInfo] (http--0.0.0.0-8080-1) Setting new service endpoint address in wsdl: http://10.68.30.25:80/tu/LoanAgreementMgmt/V1

      14:44:16,186 INFO  [org.apache.cxf.service.factory.ReflectionServiceFactoryBean] (http--0.0.0.0-8080-1) Creating Service {http://www.mydom.ca/AgmtProdOpers/LoanAgreementMgmt/V1}LoanAgreementMgmtHttpService from WSDL: http://server1.npr.local/tu/LoanAgreementMgmt/V1?wsdl

      14:44:16,195 INFO  [org.jboss.wsf.stack.cxf.transport.AddressRewritingEndpointInfo] (http--0.0.0.0-8080-1) Setting new service endpoint address in wsdl: http://10.68.30.25:80/tu/LoanAgreementMgmt/V1

      14:44:16,252 INFO  [org.jboss.wsf.stack.cxf.transport.AddressRewritingEndpointInfo] (http--0.0.0.0-8080-1) Setting new service endpoint address in wsdl: http://localhost:8080/tu/LoanAgreementMgmt/V1

      {code}

       

       

      However, the second (and subsequent) times I call the same client, I get the following in my logs and the client fails to connect:

       

      {code}

      14:44:26,893 INFO  [org.apache.cxf.service.factory.ReflectionServiceFactoryBean] (http--0.0.0.0-8080-1) Creating Service {http://www.mydom.ca/AgmtProdOpers/LoanAgreementMgmt/V1}LoanAgreementMgmtHttpService from WSDL: http://server1.npr.local/tu/LoanAgreementMgmt/V1?wsdl

      14:44:26,903 INFO  [org.jboss.wsf.stack.cxf.transport.AddressRewritingEndpointInfo] (http--0.0.0.0-8080-1) Setting new service endpoint address in wsdl: http://localhost:8080/tu/LoanAgreementMgmt/V1

      14:44:27,570 INFO  [org.apache.cxf.service.factory.ReflectionServiceFactoryBean] (http--0.0.0.0-8080-1) Creating Service {http://www.mydom.ca/AgmtProdOpers/LoanAgreementMgmt/V1}LoanAgreementMgmtHttpService from WSDL: http://server1.npr.local/tu/LoanAgreementMgmt/V1?wsdl

      14:44:27,579 INFO  [org.jboss.wsf.stack.cxf.transport.AddressRewritingEndpointInfo] (http--0.0.0.0-8080-1) Setting new service endpoint address in wsdl: http://localhost:8080/tu/LoanAgreementMgmt/V1

      14:44:27,625 INFO  [org.jboss.wsf.stack.cxf.transport.AddressRewritingEndpointInfo] (http--0.0.0.0-8080-1) Setting new service endpoint address in wsdl: http://localhost:8080/tu/LoanAgreementMgmt/V1

      ...

      ...

      ...

      Caused by: org.apache.cxf.transport.http.HTTPException: HTTP response '404: Not Found' when communicating with http://localhost:8080/tu/LoanAgreementMgmt/V1

                at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1554)

                at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1493)

                at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1401)

                at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)

                at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:648)

       

      {code}

       

      This time around, the client tries to connect to localhost:8080 which is obviously not the correct address/port for the destination service.

       

      If I edit the standalone-preview.xml file and change the default setting

       

      {code}

              <subsystem xmlns="urn:jboss:domain:webservices:1.0" xmlns:javaee="http://java.sun.com/xml/ns/javaee" xmlns:jaxwsconfig="urn:jboss:jbossws-jaxws-config:4.0">

                  <wsdl-host>

                      localhost

                  </wsdl-host>

                  <modify-wsdl-address>

                      true

                  </modify-wsdl-address>

      ...

      ...

      {code}

       

      to

       

      {code}

              <subsystem xmlns="urn:jboss:domain:webservices:1.0" xmlns:javaee="http://java.sun.com/xml/ns/javaee" xmlns:jaxwsconfig="urn:jboss:jbossws-jaxws-config:4.0">

                  <wsdl-host>

                      localhost

                  </wsdl-host>

                  <modify-wsdl-address>

                      false

                  </modify-wsdl-address>

      ...

      ...

      {code}

       

      then everything works as expected.

       

      {code}

      15:39:45,129 INFO  [org.apache.cxf.service.factory.ReflectionServiceFactoryBean] (http-0.0.0.0-0.0.0.0-8080-1) Creating Service {http://www.mydom.ca/AgmtProdOpers/LoanAgreementMgmt/V1}LoanAgreementMgmtHttpService from WSDL: http://server1.npr.local/tu/LoanAgreementMgmt/V1?wsdl

      15:39:45,139 INFO  [org.jboss.wsf.stack.cxf.transport.AddressRewritingEndpointInfo] (http-0.0.0.0-0.0.0.0-8080-1) Setting new service endpoint address in wsdl: http://10.68.30.25:80/tu/LoanAgreementMgmt/V1

      15:39:45,627 INFO  [org.apache.cxf.service.factory.ReflectionServiceFactoryBean] (http-0.0.0.0-0.0.0.0-8080-1) Creating Service {http://www.mydom.ca/AgmtProdOpers/LoanAgreementMgmt/V1}LoanAgreementMgmtHttpService from WSDL: http://server1.npr.local/tu/LoanAgreementMgmt/V1?wsdl

      15:39:45,637 INFO  [org.jboss.wsf.stack.cxf.transport.AddressRewritingEndpointInfo] (http-0.0.0.0-0.0.0.0-8080-1) Setting new service endpoint address in wsdl: http://10.68.30.25:80/tu/LoanAgreementMgmt/V1

      {code}

       

       

       

      Is this a configuration issue on my side, or is this still a trailing bug from the CXF stack (see above jira link)?

       

      Thanks,


      Eric

        • 1. Re: Bizzare host re-write in JAX-WS client on JB7.0.2
          asoldano

          I believe your use case might be a bit different from the JBWS-3260 one as you basically have the jaxws client running inside a jaxws endpoint business method. You are probably ending up using the server side bus that's started at deploy time for dealing with the endpoint. Just before each invocation of your endpoint business methods, the engine saves a references to the thread bus and then restores it when your business method is over. Your client should no be using the AddressRewritingEndpointInfo; that is installed by the SoapTransportFactoryExt, which is only added to the server side bus instances. One option you have to properly isolate your client environment (bus) from your server one is wrapping your client code into a try-finally block to set a different thread default bus isntance (for client only):

           

           

          Bus mybus = BusFactory.newInstance().createBus();

          ...

          try {

            Bus orig = BusFactory.getThreadDefaultBus();

            BusFactory.setThreadDefaultBus(mybus);

            ... client usage ...

          } finally {

            BusFactory.setThreadDefaultBus(orig);

            ... evaluate shutting down mybus or storing it somewhere if you don't want to rebuild it...

          }

           

           

          I'll check if there's a better solution for dealing this scenario.

          • 2. Re: Bizzare host re-write in JAX-WS client on JB7.0.2
            benze

            Alessio Soldano wrote:

             

            Bus mybus = BusFactory.newInstance().createBus();

            ...

            try {

              Bus orig = BusFactory.getThreadDefaultBus();

              BusFactory.setThreadDefaultBus(mybus);

              ... client usage ...

            } finally {

              BusFactory.setThreadDefaultBus(orig);

              ... evaluate shutting down mybus or storing it somewhere if you don't want to rebuild it...

            }

             

            Does this not start becoming  CXF specific in this case as opposed to being provider agnostic?  Currently, my code is all written using jax-ws (javax.xml.ws.*) api which allows me to use it in either JBoss (CXF) or WebSphere (Axis2) without problems.  However, this issue does not surface in websphere (axis2) - only jboss.  And I would rather keep it stack independent.

             

            Thanks,


            Eric

            • 3. Re: Bizzare host re-write in JAX-WS client on JB7.0.2
              asoldano

              Right, this makes your code cxf api dependant, one of the reasons I need to look for a better solution. I'll let you know.

              • 4. Re: Bizzare host re-write in JAX-WS client on JB7.0.2
                asoldano

                Another thing to consider as workaround, do you build up the Service each time? If you have means for storing the port instance once you get that, that should keep a reference of the bus available when it's created, so you won't need to have a valid client thread default bus anymore later if you re-use the previously contructed port.

                • 5. Re: Bizzare host re-write in JAX-WS client on JB7.0.2
                  benze

                  Alessio Soldano wrote:

                   

                  Another thing to consider as workaround, do you build up the Service each time? If you have means for storing the port instance once you get that, that should keep a reference of the bus available when it's created, so you won't need to have a valid client thread default bus anymore later if you re-use the previously contructed port.

                  At the moment yes & no.  The Service is cached, but the call to getPort is reissued every time.  Do you know if the proxy returned by getPort is thread safe?  I cannot seem to find any indication of it in any of the API docs.  If so, I can simply cache  the Port and reuse it every time.  Otherwise, I guess I will need to create a pool of Ports.  But before I start on the pool idea, I would like confirmation that it is or isn't thread safe.

                   

                  Thanks,


                  Eric

                  • 6. Re: Bizzare host re-write in JAX-WS client on JB7.0.2
                    asoldano

                    Regarding thread safety, see http://cxf.apache.org/faq.html#FAQ-AreJAXWSclientproxiesthreadsafe%3F

                     

                    Anyway, hopefully, I'm having a look at a possible fix for this issue later this week.

                    • 7. Re: Bizzare host re-write in JAX-WS client on JB7.0.2
                      asoldano

                      OK, I created https://issues.jboss.org/browse/JBWS-3513 ; I've not been able to reproduce your exact issue to be honest, however I still see the problem and committed a fix for it. The thread default bus should now be unassigned when entering the ws endpoint business methods. It will be properly assigned internally when creating a jaxws client. This also means that for performance reasons you might want to cache the client to avoid rebuilding the bus (which is time consuming).