1 2 Previous Next 24 Replies Latest reply on Feb 8, 2007 8:19 AM by adrian.brock

    JAXBDeployer

      I've added initial support for a JAXB parsing deployer.
      This is currently in the deployers project.

      However, I think this should really live in a seperate JAXB integration project
      so we don't end up pulling our choice of implementation into the bootstrap classpath.

      The same is probably true of the some of the other integrations?

        • 1. Re: JAXBDeployer
          weston.price

          Lovely. So, we like JAXB now? All I can remember is getting sh*@ from you two about how we didn't like it ;-)

          • 2. Re: JAXBDeployer

            The original versions were crap, that is unless you never wanted to change
            your schema/code.

            And you also had to do a precompilation stage to generate your parser.

            The latest version has resolved many of these issues, although there
            are still a number of features missing, e.g. dynamic wildcard handling
            like JBossXB can do.

            e.g. the recent spring integration code lets you mix and match
            JBoss MC and Spring xml in the same file:

            <?xml version="1.0" encoding="UTF-8"?>
            
            <deployment xmlns="urn:jboss:bean-deployer:2.0">
            
             <!-- Microcontainer xml -->
             <bean name="oldBean" class="org.jboss.test.spring.support.OldBean">
             <property name="testBean"><inject/></property>
             </bean>
            
             <!-- Spring xml - via a wildcard binding -->
             <bean xmlns="urn:jboss:spring-beans:2.0" id="testBean" class="org.jboss.test.spring.support.SimpleBean">
             <property name="mylist">
             <list value-type="java.lang.String">
             <value>onel</value>
             <value>twol</value>
             <value>threel</value>
             </list>
             </property>
             </bean>
            
            </deployment>
            


            I'd also need to do a lot more testing before I was convinced it actually works.

            e.g. I recently filed a bug which shows Sun's impl doesn't inheritance properly.

            I've been assigned a bug number, but it hasn't appeared on the website yet
            - who knows when it will get fixed, hopefully not 4 years like the classloader
            problems :-)

            http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6516905


            • 3. Re: JAXBDeployer
              weston.price

               


              The original versions were crap, that is unless you never wanted to change
              your schema/code.


              Quite right, but as I pointed out, JAXB 2.0 seemed to mitigate this

              http://www.jboss.com/index.html?module=bb&op=viewtopic&t=86414

              and

              http://www.jboss.com/index.html?module=bb&op=viewtopic&t=95273

              Since I was originally planning on using JAXB to do the *-dsx.xml binding (note, this is not *-ds.xml but an updated and more rigorous version with an associated XSD) can I assume that we are going to allow for JAXB in our new meta model implementation(s). Because, if so, I can officially delete all the JBossXB crap I had to do up until this point. This would seem to hold for the ejb3 stuff which was done using JBossXB as well...

              You know..the code you hate ;-)





              • 4. Re: JAXBDeployer

                Incidently, if you want to use (I don't have a test for it yet :-)

                You would do something like:

                public class MyParser extends JAXBDeployer<SomeMetaData>
                {
                 public MyParser()
                 {
                 super(SomeMetaData.class);
                 }
                
                 public void deploy(DeploymentUnit unit) throws DeploymentException
                 {
                 createMetaData(unit, null, "-my-extension.xml");
                 }
                }
                


                Which will create the SomeMetaData attachment ready for the real deployer to pick up.

                • 5. Re: JAXBDeployer
                  weston.price

                  Hey, that's great...since I already wrote this about 2 months ago, I am glad that I can get around to actually using it!



                  • 6. Re: JAXBDeployer

                     

                    "weston.price@jboss.com" wrote:
                    can I assume that we are going to allow for JAXB in our new meta model implementation(s).


                    Go ahead - if it works for you.
                    You've got to maintain the code. ;-)

                    • 7. Re: JAXBDeployer
                      jason.greene

                       

                      "adrian@jboss.org" wrote:

                      I'd also need to do a lot more testing before I was convinced it actually works.

                      e.g. I recently filed a bug which shows Sun's impl doesn't inheritance properly.

                      I've been assigned a bug number, but it hasn't appeared on the website yet
                      - who knows when it will get fixed, hopefully not 4 years like the classloader
                      problems :-)

                      http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6516905


                      It works great for me. What's the inheritence problem?

                      Also, bugs for it are supposed to be opened here:
                      https://jaxb.dev.java.net/servlets/ProjectIssues

                      -Jason

                      • 8. Re: JAXBDeployer
                        jason.greene

                         

                        "adrian@jboss.org" wrote:

                        The latest version has resolved many of these issues, although there
                        are still a number of features missing, e.g. dynamic wildcard handling
                        like JBossXB can do.

                        e.g. the recent spring integration code lets you mix and match
                        JBoss MC and Spring xml in the same file:
                        <?xml version="1.0" encoding="UTF-8"?>
                        
                        <deployment xmlns="urn:jboss:bean-deployer:2.0">
                        
                         <!-- Microcontainer xml -->
                         <bean name="oldBean" class="org.jboss.test.spring.support.OldBean">
                         <property name="testBean"><inject/></property>
                         </bean>
                        
                         <!-- Spring xml - via a wildcard binding -->
                         <bean xmlns="urn:jboss:spring-beans:2.0" id="testBean" class="org.jboss.test.spring.support.SimpleBean">
                         <property name="mylist">
                         <list value-type="java.lang.String">
                         <value>onel</value>
                         <value>twol</value>
                         <value>threel</value>
                         </list>
                         </property>
                         </bean>
                        
                        </deployment>
                        


                        This is possible in JAXB, if you have the following in your root type:
                         // Array of Element or JAXB elements.
                         @XmlAnyElement(lax="true")
                         public Object[] others;
                        


                        JAXB dynamically resolves type information off of annotations. So before unmarshalling, if you pass the JAXBContext a FooType.class. and FooType has an @XmlElementRoot, and the unmarshalled value matches that declaration, then "others" would contain an instance of FooType. Unknown elements would present a DOM Element.

                        -Jason

                        • 9. Re: JAXBDeployer
                          starksm64

                          How can this be specified via schema level annotations?

                          • 10. Re: JAXBDeployer
                            jason.greene

                             

                            "scott.stark@jboss.org" wrote:
                            How can this be specified via schema level annotations?


                            It reads everything directly from the Java annotations. The schema bindings just control the Java annotations that are generated when xjc is ran on the schema. So in order to have a plugable schema extension mechanism, you would have to have a way to register annotationed JAXB objects with some kind of MC context, and that would then be used to generate the JAXBContext that is responsible for unmarshalling the deployment descriptor.

                            So the big difference here is that unlike JBossXB, there is no way to override the java annotations with schema annotations. This loss of flexibility is for performance reasons (no need to read/parse the schema at runtime).

                            -Jason

                            • 11. Re: JAXBDeployer
                              jason.greene

                               

                              "jason.greene@jboss.com" wrote:

                              So the big difference here is that unlike JBossXB, there is no way to override the java annotations with schema annotations. This loss of flexibility is for performance reasons (no need to read/parse the schema at runtime).


                              So this creates a problem if the object model needs to be fixed (public API etc), but the schema needs to change significantly. Or different schemas need to be associated with the same object model. Under these scenarios, it's better to use the JAXB object model as an intermediary that directly represents the xml (in object form), and then copy / merge this information into a more elegant public API.

                              -Jason

                              • 12. Re: JAXBDeployer

                                 


                                This is possible in JAXB, if you have the following in your root type:
                                Code:

                                // Array of Element or JAXB elements.
                                @XmlAnyElement(lax="true")
                                public Object[] others;

                                JAXB dynamically resolves type information off of annotations. So before unmarshalling, if you pass the JAXBContext a FooType.class.


                                That isn't what the example does.

                                JBossXB uses the xml namespace to determine the class to unmarshal
                                as the wildcard. You don't have to tell it a fixed number of classes/packages upfront
                                on the JAXBContext.

                                JAXB is simply not extensible to abitrary wildcards.


                                 <xsd:choice minOccurs="0" maxOccurs="unbounded">
                                 <xsd:element name="string" type="stringType" minOccurs="0"/>
                                 <xsd:element name="blah" type="blahType" minOccurs="0"/>
                                 <xsd:any namespace="##other" processContents="strict" minOccurs="0"/>
                                 </xsd:choice>
                                
                                @RootElement
                                public class MyClass
                                {
                                 // Known bindings
                                 @XmlElement(name="string" type=StringSomething.class)
                                 @XmlElement(name="blah" type=BlahSomething.class)
                                
                                 // Wildcard
                                 @XmlAnyElement(I'll accept anything that implements the interface!)
                                 public void setSomethings(List<Something> somethings) {}
                                }
                                


                                • 13. Re: JAXBDeployer

                                   

                                  "jason.greene@jboss.com" wrote:
                                  Or different schemas need to be associated with the same object model.
                                  -Jason


                                  Yes, this is also broken as well. :-)

                                  The namspace is associated with the
                                  package level annotation rather the root element.
                                  This is a basic reusability issue.

                                  e.g. It should be:

                                  public class AbstractEJBModel
                                  {
                                   @XMLElement(name="enterpriseBeans")
                                   public void setEJBs(List<EJB> ejbs);
                                  }
                                  
                                  @XmlRootElement(namespace="EJB21Namespace")
                                  public class Ejb21Model extends AbstractEJBModel
                                  {
                                  }
                                  
                                  @XmlRootElement(namespace="EJB30Namespace")
                                  public class Ejb30Model extends AbstractEJBModel
                                  {
                                  }
                                  


                                  The ejbs property should be mapped to EJB21Namespace/EJB21Model or EJB30Namespace/EJB30Model
                                  depending on the model chosen (the namespace in the xml).

                                  I have this in my prototype of bindings for JBossXB annotations -
                                  the USE_PARENT_NAMESPACE.

                                  /**
                                   * SchemaProperty.
                                   *
                                   * @author <a href="adrian@jboss.com">Adrian Brock</a>
                                   * @version $Revision: 1.1 $
                                   */
                                  @Documented
                                  @Target(ElementType.METHOD)
                                  @Retention(RetentionPolicy.RUNTIME)
                                  public @interface SchemaProperty
                                  {
                                   /** Whether it is mandatory */
                                   boolean mandatory() default true;
                                  
                                   /** The namespace, default empty */
                                   String namespace() default SchemaConstants.USE_PARENT_NAMESPACE;
                                  
                                   /** The local name, default use the property name */
                                   String name() default SchemaConstants.USE_PROPERTY_NAME;
                                  
                                   /** The implementation class */
                                   Class<?> impl() default Object.class;
                                  
                                   /** TODO remove this when groups work properly */
                                   boolean noInterceptor() default false;
                                  
                                   /** TODO combine with mandatory */
                                   boolean ignore() default false;
                                  }
                                  


                                  • 14. Re: JAXBDeployer
                                    jason.greene

                                     

                                    "adrian@jboss.org" wrote:


                                    JBossXB uses the xml namespace to determine the class to unmarshal
                                    as the wildcard. You don't have to tell it a fixed number of classes/packages upfront
                                    on the JAXBContext.


                                    Either way the mapping of namespace to classes has to be known before unmarshalling, the difference is that you can lazy load classes with JBossXB. If lazy discovery is important, we should get involved with the spec and get it added.


                                    JAXB is simply not extensible to abitrary wildcards.

                                     <xsd:choice minOccurs="0" maxOccurs="unbounded">
                                     <xsd:element name="string" type="stringType" minOccurs="0"/>
                                     <xsd:element name="blah" type="blahType" minOccurs="0"/>
                                     <xsd:any namespace="##other" processContents="strict" minOccurs="0"/>
                                     </xsd:choice>
                                    
                                    @RootElement
                                    public class MyClass
                                    {
                                     // Known bindings
                                     @XmlElement(name="string" type=StringSomething.class)
                                     @XmlElement(name="blah" type=BlahSomething.class)
                                    
                                     // Wildcard
                                     @XmlAnyElement(I'll accept anything that implements the interface!)
                                     public void setSomethings(List<Something> somethings) {}
                                    }
                                    


                                    The issue with a mapping like this is that if there is any similarity between the types that could be present on a wildcard, then using schema subtyping is more appropriate.

                                    -Jason

                                    1 2 Previous Next