Yesterday we saw a bunch of articles from BEA on XMLBeans. Today we see an article on the state of JAXB. Satya Komatineni discusses working with JAXB, the class generation process, programming examples using JAXB, and a comparison to how .NET handles the same issues.
Read The State of JAXB: Availability, Suitability, Analysis, and Architecture
-
Article: The State of JAXB (10 messages)
- Posted by: Dion Almaer
- Posted on: May 06 2004 09:51 EDT
Threaded Messages (10)
- Object Factory of JAXB by suresh thalluri on May 06 2004 10:43 EDT
- I've done it using ObjectFactory directly by peter lin on May 06 2004 11:08 EDT
-
I've done it using ObjectFactory directly by suresh thalluri on May 06 2004 11:58 EDT
-
I'd have to agree on the benefit of interface by peter lin on May 06 2004 12:12 EDT
-
Trouble With Anonymous Types by Michael Gilbode on May 06 2004 02:06 EDT
- Schema has serious limitations by peter lin on May 06 2004 04:30 EDT
- Trouble With Anonymous Types by John Davies on May 06 2004 06:05 EDT
-
Trouble With Anonymous Types by Michael Gilbode on May 06 2004 02:06 EDT
-
I'd have to agree on the benefit of interface by peter lin on May 06 2004 12:12 EDT
-
I've done it using ObjectFactory directly by suresh thalluri on May 06 2004 11:58 EDT
- Object Factory of JAXB by random fletch on May 06 2004 18:43 EDT
- I've done it using ObjectFactory directly by peter lin on May 06 2004 11:08 EDT
- Article: The State of JAXB by John Davies on May 06 2004 11:36 EDT
- David Bau wrote some insightful JAXB comments by Web Master on May 06 2004 15:14 EDT
-
Object Factory of JAXB[ Go to top ]
- Posted by: suresh thalluri
- Posted on: May 06 2004 10:43 EDT
- in response to Dion Almaer
'Due to the nature of the interfaces, one cannot new content objects: you have to use a factory. This can be very tedious, as your content hierarchy involves getting new objects all the time. For every object creation you have to go to the factory.'
If you open the object factory and look at the code what it doesn't do anything more than creating a new instance. You can instantiate new object if you prefer that way.. -
I've done it using ObjectFactory directly[ Go to top ]
- Posted by: peter lin
- Posted on: May 06 2004 11:08 EDT
- in response to suresh thalluri
'Due to the nature of the interfaces, one cannot new content objects: you have to use a factory. This can be very tedious, as your content hierarchy involves getting new objects all the time. For every object creation you have to go to the factory.'If you open the object factory and look at the code what it doesn't do anything more than creating a new instance. You can instantiate new object if you prefer that way..
Not sure if that is recommended, since you're suppose to lookup the context and use the context to serializ/deserialize. When jaxb1.0 came it there was problems doing the context lookup depending on the libraries were being loaded and when you do the lookup. to get around that with jaxb1.0, I just used ObjectFactory directly. I'm sure the RI team will say "bad boy", since it's not really a good idea to do that. -
I've done it using ObjectFactory directly[ Go to top ]
- Posted by: suresh thalluri
- Posted on: May 06 2004 11:58 EDT
- in response to peter lin
Ofcourse you can use the object factory directly and it's not given anywhere in JAXB documentation to do without object factory.
If you actually look at the code what it does is nothing more that maintaing a has map for interface to implementation and instantiate accordingly. And you will not have any issues in serializing/deserializing the jaxb classes.
In fact the point I am trying to make is that Object factory is making the job easy by maintining the map and what it does is to create new instances. I don't understand why using the object factory is tedious and why is it not good to have interfaces for hiding the implementation. If I have the interfaces through out the code I can switch to any other implementation of interfaces rather than locking up with vendors like MS -
I'd have to agree on the benefit of interface[ Go to top ]
- Posted by: peter lin
- Posted on: May 06 2004 12:12 EDT
- in response to suresh thalluri
Ofcourse you can use the object factory directly and it's not given anywhere in JAXB documentation to do without object factory. If you actually look at the code what it does is nothing more that maintaing a has map for interface to implementation and instantiate accordingly. And you will not have any issues in serializing/deserializing the jaxb classes.In fact the point I am trying to make is that Object factory is making the job easy by maintining the map and what it does is to create new instances. I don't understand why using the object factory is tedious and why is it not good to have interfaces for hiding the implementation. If I have the interfaces through out the code I can switch to any other implementation of interfaces rather than locking up with vendors like MS
There are many cases where I want different types of classes implementing the same interface. Say I want to use the same model in a GUI, Webserver and Middle tier. In the gui I want the classes to implement propertyChangeListener and other more specific listeners. On the webserver tier, I might want to have it implement lazy loading. On the middle tier, I may want it to fit into an EJB. Having interfaces in my mind makes it cleaner and allows the implementation to change. But I guess if you only need to use the model in one big monolithic application, you can just have concrete classes. I prefer interfaces myself. -
Trouble With Anonymous Types[ Go to top ]
- Posted by: Michael Gilbode
- Posted on: May 06 2004 14:06 EDT
- in response to peter lin
I've used JAXB fairly successfully, and do like quite a bit about it. But I find that it's best when I have complete control over the schema.
When using externally defined schemas, I've run into some problems. The most tedious being how JAXB creates inner classes for anonymous complex types. Given a schema with multiple levels of anonymous types and fairly long element names, the code gets very messy.
Look to see what JAXB generates from this schema:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema
targetNamespace="http://myns"
xmlns="http://myns"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
version="1.0">
<xsd:complexType name="MyFirstLevelComplex">
<xsd:sequence>
<xsd:element name="MySecondLevelComplex">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="MyEnumerated" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
Code gets messy calling object factory methods like this:
import myns.MyFirstLevelComplex;
import myns.ObjectFactory;
class foo {
void foo() {
ObjectFactory of = new ObjectFactory();
MyFirstLevelComplex.MySecondLevelComplexType myObj =
of.createMyFirstLevelComplexMySecondLevelComplexType();
...
}
} -
Schema has serious limitations[ Go to top ]
- Posted by: peter lin
- Posted on: May 06 2004 16:30 EDT
- in response to Michael Gilbode
I've used JAXB fairly successfully, and do like quite a bit about it. But I find that it's best when I have complete control over the schema.When using externally defined schemas, I've run into some problems. The most tedious being how JAXB creates inner classes for anonymous complex types. Given a schema with multiple levels of anonymous types and fairly long element names, the code gets very messy.Look to see what JAXB generates from this schema:<?xml version="1.0" encoding="UTF-8"?><xsd:schema targetNamespace="http://myns" xmlns="http://myns" xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" version="1.0"> <xsd:complexType name="MyFirstLevelComplex"> <xsd:sequence> <xsd:element name="MySecondLevelComplex"> <xsd:complexType> <xsd:sequence> <xsd:element name="MyEnumerated" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType></xsd:schema>Code gets messy calling object factory methods like this:import myns.MyFirstLevelComplex;import myns.ObjectFactory;class foo { void foo() { ObjectFactory of = new ObjectFactory(); MyFirstLevelComplex.MySecondLevelComplexType myObj = of.createMyFirstLevelComplexMySecondLevelComplexType(); ... }}
I wouldn't consider that a limitation of JAXB personally. I consider it an aweful result of schema specification. One of the many limitations of schema is that you can't define interfaces and have objects implement them or have a complexType extend a type which is outside of the schema. Obviously, that makes it hard to validate the schema, but it can be an optional feature so that by default implement/extend is ignored. Using the previous example, say I have a base class for my GUI application and I want my schema classes to extend the base class. When the schema is used on the server, it can choose to ignore the extension. The schema group has acknowledged that limitation isn't easily solved, but when they will solve it is anyone's guess. -
Trouble With Anonymous Types[ Go to top ]
- Posted by: John Davies
- Posted on: May 06 2004 18:05 EDT
- in response to Michael Gilbode
This is the code, (1 of 5) java files we generate from your example, I've cut off the header and JavaDoc to save space.
I could have generated a dozen different versions, including with interfaces, without getters and setters, no custom serialization, any package names you like, any header, custom extention, schema versioning (so that version n+1 extends version n etc.). If you're interested I'll send you the tar of the deployed code, you can test it out. You even get ANT tasks to deploy this from ANT without having to use the GUI.
package myns;
public class MyFirstLevelComplex extends biz.c24.io.api.data.ComplexDataObject
{
private myns.MyFirstLevelComplex.MySecondLevelComplex mySecondLevelComplex;
public MyFirstLevelComplex(biz.c24.io.api.data.Element definingElementDecl)
{
super(definingElementDecl);
}
public MyFirstLevelComplex(biz.c24.io.api.data.Element definingElementDecl, biz.c24.io.api.data.ComplexDataType type)
{
super(definingElementDecl, type);
}
public MyFirstLevelComplex(myns.MyFirstLevelComplex clone)
{
super(clone);
}
public void addElement(java.lang.String name, java.lang.Object value)
{
name = makeSubstitution(name, -1);
if (name.equals("MySecondLevelComplex"))
setMySecondLevelComplex((myns.MyFirstLevelComplex.MySecondLevelComplex) value);
else
super.addElement(name, value);
}
public java.lang.Object clone()
{
return new myns.MyFirstLevelComplex(this);
}
public myns.MyFirstLevelComplex.MySecondLevelComplex createMySecondLevelComplex()
{
myns.MyFirstLevelComplex.MySecondLevelComplex obj = (myns.MyFirstLevelComplex.MySecondLevelComplex) getElementDecl("MySecondLevelComplex").createObject();
setMySecondLevelComplex(obj);
return obj;
}
public boolean equals(java.lang.Object obj)
{
return super.equals(obj);
}
public java.lang.Object getElement(java.lang.String name, int index)
{
name = getSubstitute(name);
if (name.equals("MySecondLevelComplex"))
return this.mySecondLevelComplex;
else
return super.getElement(name, index);
}
public int getElementCount(java.lang.String name)
{
name = getSubstitute(name);
if (name.equals("MySecondLevelComplex"))
return this.mySecondLevelComplex == null ? 0 : 1;
else
return super.getElementCount(name);
}
public int getElementIndex(java.lang.String name, java.lang.Object element)
{
name = getSubstitute(name);
if (name.equals("MySecondLevelComplex"))
return this.mySecondLevelComplex != null && this.mySecondLevelComplex.equals(element) ? 0 : -1;
else
return super.getElementIndex(name, element);
}
public myns.MyFirstLevelComplex.MySecondLevelComplex getMySecondLevelComplex()
{
return this.mySecondLevelComplex;
}
public int hashCode()
{
return super.hashCode();
}
public void removeElement(java.lang.String name, int index)
{
name = unmakeSubstitution(name, index);
if (name.equals("MySecondLevelComplex"))
{
((biz.c24.io.api.data.ComplexDataObject) this.mySecondLevelComplex).setParent(null);
this.mySecondLevelComplex = null;
}
else
super.removeElement(name, index);
}
public void setElement(java.lang.String name, int index, java.lang.Object value)
{
name = makeSubstitution(name, index);
if (name.equals("MySecondLevelComplex"))
setMySecondLevelComplex((myns.MyFirstLevelComplex.MySecondLevelComplex) value);
else
super.setElement(name, index, value);
}
public void setMySecondLevelComplex(myns.MyFirstLevelComplex.MySecondLevelComplex value)
{
this.mySecondLevelComplex = value;
((biz.c24.io.api.data.ComplexDataObject) this.mySecondLevelComplex).setParent(this);
}
private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException
{
out.writeObject(this.mySecondLevelComplex);
}
private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException
{
this.mySecondLevelComplex = (myns.MyFirstLevelComplex.MySecondLevelComplex) in.readObject();
}
public static class MySecondLevelComplex extends biz.c24.io.api.data.ComplexDataObject
{
private java.lang.String myEnumerated;
public MySecondLevelComplex(biz.c24.io.api.data.Element definingElementDecl)
{
super(definingElementDecl);
}
public MySecondLevelComplex(biz.c24.io.api.data.Element definingElementDecl, biz.c24.io.api.data.ComplexDataType type)
{
super(definingElementDecl, type);
}
public MySecondLevelComplex(MySecondLevelComplex clone)
{
super(clone);
}
public void addElement(java.lang.String name, java.lang.Object value)
{
name = makeSubstitution(name, -1);
if (name.equals("MyEnumerated"))
setMyEnumerated((java.lang.String) value);
else
super.addElement(name, value);
}
public java.lang.Object clone()
{
return new myns.MyFirstLevelComplex.MySecondLevelComplex(this);
}
public boolean equals(java.lang.Object obj)
{
return super.equals(obj);
}
public java.lang.Object getElement(java.lang.String name, int index)
{
name = getSubstitute(name);
if (name.equals("MyEnumerated"))
return this.myEnumerated;
else
return super.getElement(name, index);
}
public int getElementCount(java.lang.String name)
{
name = getSubstitute(name);
if (name.equals("MyEnumerated"))
return this.myEnumerated == null ? 0 : 1;
else
return super.getElementCount(name);
}
public int getElementIndex(java.lang.String name, java.lang.Object element)
{
name = getSubstitute(name);
if (name.equals("MyEnumerated"))
return this.myEnumerated != null && this.myEnumerated.equals(element) ? 0 : -1;
else
return super.getElementIndex(name, element);
}
public java.lang.String getMyEnumerated()
{
return this.myEnumerated;
}
public int hashCode()
{
return super.hashCode();
}
public void removeElement(java.lang.String name, int index)
{
name = unmakeSubstitution(name, index);
if (name.equals("MyEnumerated"))
this.myEnumerated = null;
else
super.removeElement(name, index);
}
public void setElement(java.lang.String name, int index, java.lang.Object value)
{
name = makeSubstitution(name, index);
if (name.equals("MyEnumerated"))
setMyEnumerated((java.lang.String) value);
else
super.setElement(name, index, value);
}
public void setMyEnumerated(java.lang.String value)
{
this.myEnumerated = value;
}
private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException
{
out.writeObject(this.myEnumerated);
}
private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException
{
this.myEnumerated = (java.lang.String) in.readObject();
}
}
}
-
Object Factory of JAXB[ Go to top ]
- Posted by: random fletch
- Posted on: May 06 2004 18:43 EDT
- in response to suresh thalluri
'Due to the nature of the interfaces, one cannot new content objects: you have to use a factory. This can be very tedious, as your content hierarchy involves getting new objects all the time. For every object creation you have to go to the factory.'If you open the object factory and look at the code what it doesn't do anything more than creating a new instance. You can instantiate new object if you prefer that way..
new Blah()
vs.
factory.createBlah()
rsi here i come.
and to avoid the "mark as noisy": using factory methods instead of constructors offers significant opportunities to substitute implementations. if jaxb turns out not to be the implementation that is suitable for you, at least with a factory method, they've left opportunity to back out. -
Article: The State of JAXB[ Go to top ]
- Posted by: John Davies
- Posted on: May 06 2004 11:36 EDT
- in response to Dion Almaer
JAXB has it's limits, it's great for small schemas but try something like FpML and it just simple won't cut it. Nor for that matter will Castor.
The code generated is also of limitted use, Castor for example creates object bloat to the stage where it will actually slow things down over raw XML.
We (C24) have taken both of these products and taken them to their ultimate conclusion, we not only generate JavaDoc'd, Externalizable Java with corresponding customized ANT build files but we guarantee support for ANY XML Schema.
Although this is free to charities and non-profit JSR-like bodies however it is sadly not free. :-(
For anyone interested we have just released version 3 in beta so there is little on our web site on the new IntelliJ-like GUI or code but we can send you a fully working eval if you are interested. At the time of writing the web site refers to version 2.1.
Our customers include several of the world's largest banks in New York, London and Frankfurt.
Marketting? Yes sorry, but if you've got stuck with JAXB, we're got a solution.
-John Davies-
CTO, C24
(Currently at TSS Java Symposium in Vegas) -
David Bau wrote some insightful JAXB comments[ Go to top ]
- Posted by: Web Master
- Posted on: May 06 2004 15:14 EDT
- in response to Dion Almaer