6 Replies Latest reply on Feb 12, 2012 10:19 PM by njiang

    cxf context and how cxf works when a bundle invokes code from other bundle

    marc.blomquist

      Title of this post sounds strange but I ran out of text so I had to write "other" instead of "another".

       

      So this is a question on how exactly cxf, servicemix and camel work behind the scenes. It's a high level overview and I'm trying to get a better understanding of how things work so that I can debug things faster in the future. I'll start with the following example,

       

      Bundle A is loaded into servicemix. Bundle A is a bundle that provides a new Camel Component, let's call it FOO, that will have an EndPoint, Consumer and Producer. Bundle A has a bean.xml that is loaded through spring and creates a cxf http-conduit. This http-conduit is used by Bundle A's Consumer. We now have Bundle B, which depends on Bundle A and creates a FOO Endpoint.

       

      Here comes the questions and confusion. Assume I know very little and that I might be completely misunderstanding how things work:

       

      1. How does the architecture load the cxf http-conduit from Bundle A so that Bundle B can also use it?

       

      2. Can anyone give a plain old java object (POJO) code example of how I can query the cxf/camel classes that shows what cxf beans have been loaded in my bundle?

       

      Edited by: marc.blomquist on Feb 14, 2012 2:49 PM

        • 1. Re: cxf context and how cxf works when a bundle invokes code from other bundle
          marc.blomquist

          Here's another example that I'm not sure what the outcome would look like or how the architecture would handle it. Suppose bundle A modifies the CXF bus in the following manner through spring,

           

           

           

          Then bundle B instantiates classes in bundle A that use the cxf bus. Will there be two different buses or will there be a single bus between bundle A and bundle B?

           

          The next questions then are,

          a) If there are two different buses between A and B, how can I set it up so that there is only one?

          b) If there is only one bus between A and B, how can I set it up so that there are two different buses, one for A and one only for B?

          • 2. Re: cxf context and how cxf works when a bundle invokes code from other bundle
            marc.blomquist

            So I tested some of this theory out a bit and this is what I discovered:

             

            -


            Test 1)

            Setup:

            - Bundle A has a bean file that instantiates a cxf http-conduit with name="*.http-conduit" that uses ssl and imports META-INF/cxf and so on forth.

            - Bundle A also exports a new Camel Endpoint called FOO_A that needs ssl to work.

            - Bundle B has a bean file that creates a camel route using FOO_A from Bundle A.

             

            Result:

            Everything works fine and the FOO_A endpoint is able to connect using SSL.

             

            Conclusion:

            This is as expected but I did this to make sure everything was working properly first.

             

            -


            Test 2)

            Setup:

            - Same setup as in Test 1 except bundle B's bean also imports the cxf resources (i.e. classpath:META-INF/cxf/cxf.xml and so on forth) on top of creating a camel route with FOO_A.

            Result:

            The FOO_A endpoint throws an ssl hand_shake failure because the http-conduit is being setup as plain http, which means the endpoint used Bundle B's cxf-bus.

             

            Conclusion:

            I thought that this meant the cxf architecture was setup so that the parent bundle B  would override the cxf bus of dependency bundle A... but the next test case proved this to be false.

             

            -


            Test 3)

            So this is where things get interesting

            Setup:

            - Same setup as Test 1, except we now have a bundle C that is an EXACT copy of bundle A, except Bundle C's http-conduit has no tlsClientParameters.

            - Bundle B also now has two camel routes. One with FOO_A Endpoints and one with FOO_C Endpoints.

             

            Results:

            The result is either both FOO_A and FOO_C connect properly OR they both throw a hand_shake failure. Which of these two scenarios happens is random, which would imply a race condition of which http-conduit (or I guess cxf-bus) is loaded in which order.

             

            Conclusion:

            Based on all three test cases, does this mean that there can only be a SINGLE cxf context between depending bundles? I find that hard to believe and very troubling!

             

            -


             

            I'll keep testing and checking to make sure I didn't make a mistake because if this is true it is a major problem for us because we want to create many bundles that are all used by one bundle and each of these bundles will need a different cxf-bus/http-conduit.

             

            Edited by: marc.blomquist on Feb 10, 2012 12:43 AM

            • 3. Re: cxf context and how cxf works when a bundle invokes code from other bundle
              njiang

              If you want to share the http-conduit across bundles, you need to make sure that these two bundles are using same cxf bus.

               

              You can define a service in your bundle A to export the bus for the other bundle to use.

               

              Willem

              • 4. Re: cxf context and how cxf works when a bundle invokes code from other bundle
                njiang

                To answer the question of Bus.

                 

                There are some tricks of the CXF bus which is used in container like Services.

                As the JAXWS API doesn't has the concept of Bus, CXF need to get the bus from thread local variable.

                If you are using spring-dm to initialize the bundle context(A, B, C), it is hard to tell which bus is used. So you need to manage the bus yourself, and using the bus setting API of CXF to setup the bus.

                • 5. Re: cxf context and how cxf works when a bundle invokes code from other bundle
                  marc.blomquist

                  Thanks for the answers so far! I have a few more questions based on what you said.

                   

                  So if I understood it correctly, I can have only one CXF bus between bundle B, A and C unless I turn the CXF buses into OSGI services?

                   

                  If this is true, what would happen if 1 year from now I need to include two other thirdparty bundles D and E that also have a cxf bus? Would this mean that I have to modify their cxf code/bean to get it to work with our bundle?

                   

                  This sounds like a lot of work just to get CXF to work with other bundles that have CXF : ( but if this is the only solution then I must use it. I'll research exactly how to go about doing this and post how things turn out.

                   

                  Edited by: marc.blomquist on Feb 10, 2012 5:05 PM

                  • 6. Re: cxf context and how cxf works when a bundle invokes code from other bundle
                    njiang

                    If you want to use the same bus across the bundle, you need to use the setBus API which is provided from the CXF API instead of JAXWS-API to set the bus explicitly.

                    You can use some factorybean class to wrap the bus setting work if you don't want other bundle to be effected.

                     

                    Willem