11 Replies Latest reply on Feb 24, 2010 3:56 AM by asoldano

    Providing JAX-RPC functionalities with CXF and Metro stacks

    asoldano

      As you all know, Apache CXF and Glassfish Metro do not include JAX-RPC functionalities. While this is not a major issue considering users should be moving to JAXWS for many reasons, Java EE 6 still include jaxrpc and JBoss AS needs to be certified.

      In the direction of further improving the JBossWS integration layer for running different WS stacks on top of our AS, we need to provide a way of supporting jaxrpc deployments when JBossWS-CXF or JBossWS-Metro is installed in the AS.

      During a F2F meeting at end of January, the JBossWS team discussed possible solutions for this issue and the most viable one appeared to be leveraging the JBossWS-Native stack for providing JAXRPC functionalities, while leaving JAXWS processing to the other installed stack.
      I've been prototyping an implementation for this in the last weeks and since it's basically maching my expectations, I'm describing it a bit here below along with the results before thinking about merging it upstream.

        • 1. Re: Providing JAX-RPC functionalities with CXF and Metro stacks
          asoldano

          First of all, the prototype is available here:

           

          Native stack:

          http://anonsvn.jboss.org/repos/jbossws/stack/native/branches/jaxrpc-cxf/

           

          CXF stack:

          http://anonsvn.jboss.org/repos/jbossws/stack/cxf/branches/jaxrpc-cxf/

           

          Metro stack:

          http://anonsvn.jboss.org/repos/jbossws/stack/metro/branches/jaxrpc-cxf/

           

          Framework:

          http://anonsvn.jboss.org/repos/jbossws/framework/branches/jaxrpc-cxf

           

          Common:

          http://anonsvn.jboss.org/repos/jbossws/common/branches/jaxrpc-cxf

           

          Spi:

          http://anonsvn.jboss.org/repos/jbossws/spi/branches/jaxrpc-cxf

           

          AS trunk integration:

          http://anonsvn.jboss.org/repos/jbossas/branches/jaxrpc-cxf/

           

          There's currently no container integration for already released AS versions and there's probably not going to be, as that can't be done properly for released container without breaking the JBossWS abstraction. The net result is that we'd have jaxrpc support with CXF/Metro starting from AS 6.

          • 2. Re: Providing JAX-RPC functionalities with CXF and Metro stacks
            asoldano

            Implementing the idea highlighted above basically implies being able to install multiple webservice stacks at the same time in the AS. JBossWS-Native and JBossWS-CXF/Metro need to coexist at runtime and deal with requests depending on the kind of endpoint those are meant for.

             

            In order to deploy multiple stacks on JBoss AS, we needed to:

             

            * fx the deployment process: JAXRPC deployments need to go through JBossWS-Native deployers, while JAXWS ones need to be dealt with by JBossWS-CXF deployers. There's also some kind of intersection between the two groups, as JBossWS comes with some common features that need to stay centralized (the endpoint registry, for instance)

             

            * ensure libs from the two deployed stacks can live together: this quite important speaking of WS as a *lot* of things depends on Service API loading: apart from JBossWS itself using that system for selecting the right stack implementation for things like the RequestHandler, the WebServiceContextFactory, the ServiceRefBinderFactory, etc. (which are different on different stacks), the META-INF/service/... is looked up at runtime for selecting the SOAPFactory, MessageFactory, JAXWS spi provider, etc.

             


            • 3. Re: Providing JAX-RPC functionalities with CXF and Metro stacks
              asoldano

              The deployment processing issue has been solved basically leveraging the current architecture of ws deployers in AS trunk. The webservice processing in the deployers is currently splitted in a quite fine-grained group of AS real deployers.

              In few words, adding a couple of flags (attributes) to both stacks' deployers for marking them as being able to deal with jaxrpc/jaxws deployments, we've been able to make them run just for the deployments they're meant for (the deployment type is detected early in the real phase). Thanks to the AS deployers' inputs/outputs and the current JBWS deployers' modularity, there's been no need to provide implementation of new deployers, a proper combination of the already existing one is fine.

               

              So, the JBossWS-CXF and JBossWS-Metro stacks now come with a -jboss-beans.xml descriptor that is added to jbossws-jaxrpc.deployer folder (see below) and that basically pulls in the chain 6 deployers normally used by JBossWS-Native. Those are marked forJaxWs=false in this case and hence used for jaxrpc only.

               

              The next step has been to properly factor our all the non-jaxrpc / non-jbws-native-specific META-INF/services/... from the jbossws-native-core.jar module. This allows that jar to always stay in $JBOSS_HOME/client and $JBOSS_HOME/common/lib regardless of what WS stack is installed. As a side effect, it also goes in the direction of moving most of the ws related jars out of the deployers/jbossws.deployer dir, which reduce the AS distro size ;-)

               

              Those service configuration are moved to a descriptor only jar (jbossws-native-services.jar) and that jar is installed by default in the new deployers/jbossws-jaxrpc.deployer dir, along with the factories configuration (working the same way) we already have in jbossws-native-factories.jar. A separate classloader is specified through a jboss-classloading.xml file for that jbossws-jaxrpc.deployer, to prevent those services configuration from interfering with the other deployed jbws stack. Of course those descriptor only jars are included in $JBOSS_HOME/client and $JBOSS_HOME/common/lib as usual when the native stack is installed instead.

               

              The following step has been to ensure the proper classpath is setup when creating the classloader that will be used during deploy and at runtime for a given endpoint deployment.

              I took inspiration from the Seam/Weld integration into AS 5 here. We provide a deployer that extends the org.jboss.deployers.vfs.plugins.classloader.UrlIntegrationDeployer for adding classpath entries to the DeploymentUnit during the describe phase. JAX-RPC deployments only are touched here: the jbossws-native-services.jar and jbossws-native-factories.jar are added on top of the classpath. This basically results in the Native stack implementations being configured for serving requests to jaxrpc deployments.

              There're actually 4 slightly different deployers of this kind, to deal with server deployments and client deployments (service-ref through servlet, ejb or standalone client).

              Something I've had problem with here is how to detect jaxrpc deployments at describe phase; as I mentioned before, we already do that, but in real phase. The reason for doing that at real phase is simply that jaxws endpoint can be specified through annotations hence the classes need to be loaded first.

              For server side the problem is easily solved setting org.jboss.wsf.spi.metadata.webservices.WebservicesMetadata.class as input to the new deployer, as that's attached to the DeploymentUnit only when a webservices.xml is included in the deployment (ie. we have a jaxrpc endpoint). Considering annotations are not part of the game for JAXRPC, the service-ref deployement (client side) currently works by checking the ServiceReferencesMetaData from EjbJarMetaData/WebMetaData/ApplicationClientMetaData for the existence of references to a jaxrpc-mapping. Suggestions are welcome here, if any. Anyway I'm also going to verify something more here too, as on client side the classpath change might be required just for properly looking up the ServiceObjectFactory, which we could find out another solution for.

               

              Finally, the already available StackConfig bean is injected into the new deployers, to allow them to actually run just when a non-native stack is installed, while always being provided in the AS through a -jboss-beans.xml file in jbossws-jaxrpc.deployer (since they're container specific).

              • 4. Re: Providing JAX-RPC functionalities with CXF and Metro stacks
                asoldano

                In order to test this, apart from manually running jaxrpc/**/*TestCase from Native stack against a CXF/Metro stack, we need some kind of basic jaxrpc coverage in the jbossws-framework. So I copied some of the jaxrpc samples from the native testsuite to framework and removed native stack specific stuff from them (we have some kind of extensions to the standard jaxrpc interfaces which are used extensively in the native testsuite). This way the framework is still stack independent and simply uses the jaxrpc-api.jar too.

                 

                From a client configuration point of view, using the added jaxrpc features with CXF/Metro stacks simply implies adding jbossws-native-core.jar, netty.jar and jaxrpc-api.jar to the classpath.

                 

                The jbossws testsuites are currently passing. Before writing this posts I also wanted to try the jaxrpc related modules of the Java EE 5 TCK. For doing that I manually retro-fitted the changes to AS 5.1.0.GA. jaxrpc and webservice modules all green, webservices12 has some other issues (JBWS-2935) preventing a clean run, but the mix jaxrpc-jaxws test there is passing.

                • 5. Re: Providing JAX-RPC functionalities with CXF and Metro stacks
                  ropalka
                  Just few notes/questions here:

                  Note1) instead of jbossws.deployer we should have two deployers:
                  - jaxrpc.deployer
                  - jaxws.deployer

                  Note2) This is the first initial prototype that will require further
                  cleanup in the future.

                  Note3) If we're passing all TCK5 suites with Native with this
                  JAX-RPC prototype the I don't see any reason why we couldn't merge
                  this prototype upstream.

                  Question) It's not clear to me why this JAX-RPC prototype cannot be
                  backported to AS 501, AS 510 and AS 600M2 AS IL?
                  Are we using some AS upstream features there?
                  This is important to have IMHO to verify Note3)
                  • 6. Re: Providing JAX-RPC functionalities with CXF and Metro stacks
                    ropalka

                    BTW, I really like the idea of coexisting WebServices stacks in AS

                    This is the way to go in the furure IMHO. The particular WebService stack

                    that will be used can be command line configured (see discussion on configurable AS)

                    • 7. Re: Providing JAX-RPC functionalities with CXF and Metro stacks
                      asoldano

                      Note1) instead of jbossws.deployer we should have two deployers:
                      - jaxrpc.deployer
                      - jaxws.deployer

                       

                      Perhaps that was not clear enough, that's what I have in the prototype impl.

                       

                      jbossws.deployer

                      -----------------------

                      Contains one stack (Native, CXF, Metro) used for JAXWS functionalities and also for jaxrpc ones in case of Native stack.

                      It has the stack-agnostic-jboss-beans.xml and stack-specific-jboss-beans.xml as usual.

                       

                      jbossws-jaxrpc.deployer

                      --------------------------------

                      Contains just the two descriptors only jars (jbossws-native-factories.jar, jbossws-native-services.jar), the jboss-classloading.xml, another stack-agnostic-jboss-beans.xml with the new describe stage deployers declaration only. Another stack-specific-jboss-beans.xml (with the jaxrpc only DA) is dropped here by the jbossws-cxf and jbossws-metro install scritps (that basically enable this deployer, which otherwise does nothing).

                       

                       

                      Note2) This is the first initial prototype that will require further
                      cleanup in the future.

                       

                      Sure, I'm probably doing some initial clean up today. Then, if there's no special complaint, I'll merge to trunk. That's because we need to have this go through the usual hudson runs / QA in general, to make sure it always works.

                       

                       

                      Note3) If we're passing all TCK5 suites with Native with this
                      JAX-RPC prototype the I don't see any reason why we couldn't merge
                      this prototype upstream.

                       

                      I did not re-run the TCK5 with Native, but I think there're no problems here, at most we need to verify the jbossws classpath in the porting layer configuration, the new deployers do not enter the game when Native stack is installed. Also, this is something that will probably affect TCK6 only, as we're not going to make this available to AS 5.x.

                       

                       

                      Question) It's not clear to me why this JAX-RPC prototype cannot be
                      backported to AS 501, AS 510 and AS 600M2 AS IL?
                      Are we using some AS upstream features there?
                      This is important to have IMHO to verify Note3)

                       

                      First of all it's a dependency problem. We need to have those jbossws-native-factories.jar and jbossws-native-services.jar installed in jbossws-jaxrpc.deployer. Currently the AS trunk build would put them there. To do that in the AS IL we probably need to have that depend on Native stack.

                      Moreover, we need to have the jbossws-native-core.jar installed in client and common/lib also when the CXF/Metro stacks are deployed. It's not clean to do that during install of a stack, and again if that lib is not there (immagine you have Metro 3.2.2 installed on AS5 and you want to install CXF 3.3.0), we need to depend on Native.

                      Anyway, in the long term, something similar would probably be required nevertheless. Imagine we decide to provide an AS that ships with CXF stack by default, we'll have dependency on native stack too in the component-matrix/pom.xml, which is basically the same idea. But I think going on with this on AS 6 only is pretty much acceptable ATM (AS6 is a major release, blah, blah) and reduces the complexity.

                      • 8. Re: Providing JAX-RPC functionalities with CXF and Metro stacks
                        asoldano

                        BTW, I really like the idea of coexisting WebServices stacks in AS

                        This is the way to go in the furure IMHO. The particular WebService stack

                        that will be used can be command line configured (see discussion on configurable AS)

                         

                        Well, I think we're not there yet, but this might even be a first step in that direction if that will be the future direction.

                        • 9. Re: Providing JAX-RPC functionalities with CXF and Metro stacks
                          ropalka

                          I have no complains about merging this JAX-RPC prototype upstream

                          because I can't see different viable solution. I suggest you to

                          merge before VFS3 is in AS trunk, then it will be harder to debug the problems (if any).

                          On the other hand JBossWS 3.3.0.CR1 is coming (code freeze this Friday?)

                           

                          Onward to merge!

                          • 10. Re: Providing JAX-RPC functionalities with CXF and Metro stacks
                            dimitris

                            I, too, would like to see the different stacks being able to be deployed separately/in parallel without conflicting with each other, as Richard pointed out. At the very least, one should be able to choose whether she wants jac-rpc functionality or not.

                             

                            BTW, great work!