1 2 Previous Next 19 Replies Latest reply on Jun 28, 2007 10:59 AM by heiko.braun

    Setting the properties on the JAXBContext

    tfennelly

      Hi.

      I need to be able to set the properties on the JAXBContext instances produced by the JAXBContextCache. See JAXBContext.newInstance javadoc.

      I need to be able to set the properties before making a call to RequestHandler.handleRequest and the JAXBContextCache needs to be able to access that properties list and use it to create the JAXBContext instance.

      What would be the best way of making these properties available to JAXBContextCache? I've been working off branches/jbossws-2.0. I have this working at the moment simply by setting and getting the properties on a ThreadLocal. I was hoping there'd be a nicer way e.g. by attaching it to the InvocationContext perhaps, but I can't seem locate it in the JAXBContextCache e.g. through the current CommonMessageContext on the executing thread.

      Any ideas?

        • 1. Re: Setting the properties on the JAXBContext
          heiko.braun

          We can defer creation of JAXBContext's to JBossWS factory. The SPI ships with a default FactoryLoader implementation that allows us to change the implementation through a /META-INF/services entry.

          IMO this would be the easiest. Another option would be indirect creation though the MC. Then the factory would become part of jbossws-beans.xml.

          • 2. Re: Setting the properties on the JAXBContext
            thomas.diesler

            We must be careful to not bind functionality to a specific stack. Otherwise the whole idea of pluggable web service stacks becomes useless.

            Why specifically do you need to interact with such low level detail as JAXB properties. A JAXWS client should not have to do that AFAIK.

            • 3. Re: Setting the properties on the JAXBContext
              tfennelly

              Sorry about the delay in replying - I was on vacation :-)

              "heiko.braun@jboss.com" wrote:
              We can defer creation of JAXBContext's to JBossWS factory. The SPI ships with a default FactoryLoader implementation that allows us to change the implementation through a /META-INF/services entry.

              IMO this would be the easiest. Another option would be indirect creation though the MC. Then the factory would become part of jbossws-beans.xml.


              How would we get the properties instance (which will be different per typeset for which the JAXBContext is being created) into this factories scope?

              "thomas.diesler@jboss.com" wrote:
              Why specifically do you need to interact with such low level detail as JAXB properties. A JAXWS client should not have to do that AFAIK.


              This forum post to the JAXB Forums should explain why we need it: http://forums.java.net/jive/thread.jspa?threadID=27591&tstart=0

              The changes I'm talking about are not really low level from a JBossWS perspective. The JAXBContext class provides 2 factory methods for creating the JAXBContext, one which takes a properties set and one which does not. From a JBossWS perspective, we're just talking about being able to specify a property set. To see how I'm doing this at the minute, see the JBossWSAdapter class - search for references to JAXBContextCache. So at the moment I relying on a hack whereby I'm setting the JAXBContext properties (for the SOAP message being processed) via a Threadlocal.

              • 4. Re: Setting the properties on the JAXBContext
                thomas.diesler

                 

                import org.jboss.ws.core.jaxws.JAXBContextCache;
                


                This already is the problem. You cannot rely on proprietary API .

                In case the SPI/standard API is not sufficiently open we might need to change that. However I need to understand your use case better in order to give you a qualified answer.

                Not every supported stack is necessarily using JAXB. So setting JAXB properties might not be the right solution anyway.

                • 5. Re: Setting the properties on the JAXBContext
                  tfennelly

                   

                  "thomas.diesler@jboss.com" wrote:
                  import org.jboss.ws.core.jaxws.JAXBContextCache;
                  


                  This already is the problem. You cannot rely on proprietary API .


                  +1 and that's why I'm here looking for the correct solution :-)

                  What I've outlined is what I had to do to get the "native" JBossWS stack (which uses JAXB, right?) to work with a set of Java bindings that are not JAXB annotated. Kohsuke Kawaguchi has confirmed that this is the correct solution from a JAXB perspective, so I guess what we need to do here is figure out how this all fits into your view of the world ala the JBossWS SPI etc

                  "thomas.diesler@jboss.com" wrote:
                  However I need to understand your use case better in order to give you a qualified answer.


                  OK. It's basically as I outlined in the JAXB forum post...
                  "... we need to be able to bind an XML message (using this JAXB based code) into an existing Java interface (not annotated for JAXB). We don't own the interface, so changing it is not an option."


                  So JAXB requires the java bindings it's trying to unmarshal the SOAP message into to have JAXB annotations. In the JBossESB usecase, this is very often going to be impossible because the interface is probably owned by something outside the ESB (i.e. we can't modify them to add the annotations).

                  An ESB example of this that we continually use is where the ESB is being used to expose a Webservice interface for a legacy EJB based Service. The EJB remote interface is already defined and is what we want to base our ESB "hosted" (interpret loosely) JSR181 endpoint - the EJB wrapper Webservice.

                  Our current solution to all this from a JBossESB + JBossWS 2.0.x perspective is as outlined in that JAXB forum post.

                  "thomas.diesler@jboss.com" wrote:
                  Not every supported stack is necessarily using JAXB. So setting JAXB properties might not be the right solution anyway.


                  How the SPI exposes this is up to you for sure.

                  • 6. Re: Setting the properties on the JAXBContext
                    marklittle

                    Let's also be clear: we're only considering this for the ESB 4.2 release, which from a WS perspective is only supporting JBossWS. If a better, more WS neutral approach comes is available now, that would be fine. But longer term we have the freedom to investigate other options. Right Tom?

                    • 7. Re: Setting the properties on the JAXBContext
                      tfennelly

                      +1

                      We need something agreed for 2.0.0 and I'd guess it's too late for a neutral SPI based solution at this stage, yes/no?

                      At the end of the day I'd imagine something like this will be required for this type of usecase, no matter what the underlying stack + marshal/unmarshal technology combo is, yeah? I know XStream has it's own non-standards based set of annotations (aliases), as well as an external XML config model that it uses for defining what is essentially the same binding metadata - namespaces, types etc. If the JBossWS SPI is going to accommodate defining these external configs ala what we've done for JAXB and what XStream has in its alias configs, will it pick one standard and map to the underlying impl or what? If it goes with one standard, would something based on JAXB and it's annotations be the natural choice?

                      Anyway, maybe that's all for another day - we need something for 2.0.0 asap :-)

                      • 8. Re: Setting the properties on the JAXBContext
                        marklittle

                         

                        "tfennelly" wrote:
                        +1

                        We need something agreed for 2.0.0 and I'd guess it's too late for a neutral SPI based solution at this stage, yes/no?


                        From a purely ESB perspective, WS neutrality is not important in 4.2. JBossWS is all we'll be supporting.

                        • 9. Re: Setting the properties on the JAXBContext
                          thomas.diesler

                          Tom, I assume this only applies to JAXWS endpoints. The JAXWS client API is not affected.

                          • 10. Re: Setting the properties on the JAXBContext
                            heiko.braun

                            I did already break up the JAXBContextCache and the JAXBContextFactory. Regardless on how we proceed, this was a good idea anyway.

                            If Thomas suggestion is correct, which means the customizations are only required for JAX-WS endpoints then we might actually go with a solutions that attaches to the InvocationContext. I.e. a Map like Interface

                            InvocationContext.addAttachment(JAXBContexCustomisation.class, <Instance>);
                            


                            that can carry JAXBRI default properties. See http://jsourcery.com/api/java.net/jaxb/2.1.2/com/sun/xml/bind/api/JAXBRIContext.html for a complete list.

                            This way at least the JBossWS RequestHandlerImpl is open to any JAXB customisation. Other RequestHandler would then just disregard these attachments.

                            Tom, would this be sufficient? Can you supply this information on a per-invocation base? Or might this better be attached to the Endpoint - on a per-deployment base? I don't really grasp the use cases yet.






                            • 11. Re: Setting the properties on the JAXBContext
                              thomas.diesler

                              I externalized construction of the JAXBContext in a JAXBHandler which is a property on the Endpoint.

                              public interface JAXBHandler
                              {
                               /** Get a JAXBContext instance.
                               */
                               JAXBContext getJAXBContext(Class[] javaTypes) throws JAXBException;
                              }
                              


                              public interface Endpoint
                              {
                               ...
                              
                               /** Get the JAXBHandler for this endpoint */
                               JAXBHandler getJAXBHandler();
                              
                               /** Set the JAXBHandler for this endpoint */
                               void setJAXBHandler(JAXBHandler handler);
                              
                               ...
                              }
                              


                              The JAXBHandler is injected like any other handler

                               <bean name="WSEndpointHandlerDeployer" class="org.jboss.wsf.spi.deployment.EndpointHandlerDeployer">
                               <property name="requestHandler">org.jboss.wsf.stack.jbws.RequestHandlerImpl</property>
                               <property name="lifecycleHandler">org.jboss.wsf.stack.jbws.LifecycleHandlerImpl</property>
                               <property name="jaxbHandler">org.jboss.wsf.spi.binding.jaxb.JAXBContextCache</property>
                               <property name="invocationHandler">
                               <map keyClass="java.lang.String" valueClass="java.lang.String">
                               <entry><key>JAXRPC_JSE</key><value>org.jboss.wsf.stack.jbws.ServiceLifecycleInvocationHandler</value></entry>
                               <entry><key>JAXRPC_EJB21</key><value>org.jboss.wsf.container.jboss42.InvocationHandlerEJB21</value></entry>
                               <entry><key>JAXRPC_MDB21</key><value>org.jboss.wsf.container.jboss42.InvocationHandlerMDB21</value></entry>
                               <entry><key>JAXWS_JSE</key><value>org.jboss.wsf.stack.jbws.ServiceLifecycleInvocationHandler</value></entry>
                               <entry><key>JAXWS_EJB3</key><value>org.jboss.wsf.container.jboss42.InvocationHandlerEJB3</value></entry>
                               </map>
                               </property>
                               </bean>
                              


                              • 12. Re: Setting the properties on the JAXBContext
                                tfennelly

                                 

                                "thomas.diesler@jboss.com" wrote:
                                Tom, I assume this only applies to JAXWS endpoints. The JAXWS client API is not affected.


                                That's right Thomas.

                                "heiko.braun@jboss.com" wrote:
                                If Thomas suggestion is correct, which means the customizations are only required for JAX-WS endpoints then we might actually go with a solutions that attaches to the InvocationContext. I.e. a Map like Interface
                                InvocationContext.addAttachment(JAXBContexCustomisation.class, <Instance>);
                                


                                that can carry JAXBRI default properties. See http://jsourcery.com/api/java.net/jaxb/2.1.2/com/sun/xml/bind/api/JAXBRIContext.html for a complete list.

                                This way at least the JBossWS RequestHandlerImpl is open to any JAXB customisation. Other RequestHandler would then just disregard these attachments.

                                Tom, would this be sufficient? Can you supply this information on a per-invocation base? Or might this better be attached to the Endpoint - on a per-deployment base? I don't really grasp the use cases yet.


                                This would be perfect Heiko and is actually what I was trying to do, but I just couldn't figure out how to get the Properties instance back from within JAXBContextCache. As I said in my original post on this thread...
                                I have this working at the moment simply by setting and getting the properties on a ThreadLocal. I was hoping there'd be a nicer way e.g. by attaching it to the InvocationContext perhaps, but I can't seem locate it in the JAXBContextCache e.g. through the current CommonMessageContext on the executing thread.


                                If I could get this properties list back from within the JAXBContextCache (or JAXBContextFactory now), this would be the ideal solution as I see it at the moment. I just couldn't see how to get it back at the time I made the original post - I'm not familiar with the JBossWS code.


                                • 13. Re: Setting the properties on the JAXBContext
                                  thomas.diesler

                                  Tom, the change to the SPI supersedes Heiko's proposal AFAICS. Injecting your own JAXBHandler on the Endpoint should allow you to create, cache, etc the JAXBContext any way you want

                                  • 14. Re: Setting the properties on the JAXBContext
                                    tfennelly

                                     

                                    "thomas.diesler@jboss.com" wrote:
                                    Tom, the change to the SPI supersedes Heiko's proposal AFAICS. Injecting your own JAXBHandler on the Endpoint should allow you to create, cache, etc the JAXBContext any way you want


                                    Ah OK, thanks Thomas. I'll have a look at that so. I assume it's in the 2.0.x codebase.

                                    1 2 Previous Next