users@jaxb.java.net

Re: Using existing classes

From: Gary Gregory <ggregory_at_seagullsw.com>
Date: Tue, 24 Dec 2002 11:39:00 -0500

We have been dealing with the same situation here. I will just share our
current solution and thoughts (=ramblings). There are two main issues I
think: (1) Integrating JAXB generated code and (2) Deciding on a per app
basis what JAXB means to you.

(1) Clearly, being able to generate the JAXB model classes as a subclasses
of custom classes would be quite practical at first. You would end up with,
for example, a Customer class and an XMLCustomer subclass, where the latter
was generated by JAXB. But, is this a proper use of inheritance? Do you
really want "an XML kind of customer"? It seems (to me) that this looks too
heavyweight of an architecture and also very brittle. You could end up with
one XML subclass for every single class in your app model, possibly spread
over many packages. In a general sense, adopting such an architecture would
mean that for every encoding (XML, JDBC, or whatever) of such a model class
would require a new subclass. Certainly, after a couple of encoding
implementation, you would end up refactoring common behavior into... what? A
CustomerMarshaller subclass which in turn has an XMLCustomer subclass?
Nah... I claim that this is situation calls for composition, not
inheritance. The Customer class can have an instance variable that holds on
to it's "binding", the JAXB generated object. You can also add an "adaptor"
layer to shield the model class from any changes to the underlying binding.
This does not 'feel' like to best solution.

(2) The more general issue I have with JAXB can be subdivided into two
areas: (a) Where do you start and (b) How much do you put into the XML
Schema. I threw away a lot of my implementation when I ported our
still-in-development app from object-based unit test fixtures to XML data
file based unit test fixtures. Why? When you start with JAXB, you start with
XML Schema. When you unmarshall, an XML data file with JAXB, you get a
custom object tree based on the classes defined by the XML Schema. What did
I have before? I already had a custom object tree in my unit tests. I
already had a app model set of classes. Now I had both. What feels like a
step back with JAXB is that the generated code defines state only. The app
model I had contained both state and behavior of course, like in any decent
OO design. But, to make things more complicated, the JAXB generated code
does not have to be stateless, strictly speaking. XML Schema is pretty
powerful stuff, and since you can specify all manners of restrictions and
data validation on the data contained in attributes and elements, these
specification do get translated into code. There can be (optionally), some
amount of clever behavior in the JAXB model code. You can get behavior like
data validation in your JAXB model classes. Now, I have two big conceptual
piles: JAXB model class with some state and some behavior plus my app model
with all of the state and all of the behavior. (I would say that most apps
would have additional transient state in their model that do not get
externalized.) Assuming that avoiding duplication is not acceptable, what to
do?

For good or bad, here is what we did:
Start with XML-Schema. This forced us to decide what should really be
persisted in the first place.
Use JAXB to generate code into a com.company.component.bind package. Since
the general category of code generated belongs in the "XML data binding"
category, we felt "bind" was a good name. The "bind" packages contains only
JAXB generated code. Create a class called com.company.component.Bindings
that hides JAXB details and provide type safe methods like
unmarshalCustomer. A root model class is in com.company.component like
com.company.component.Customer. Customer has an ivar called customerBinding
(we postfix JAXB generated class names with "Binding"). Customer delegate to
the binding getters and setters. Anything that requires binding data
structure traversal is done in the Bindindgs class.

I am not 100% satisfied with this arrangement but I like delegating to a
binding class instead of using inheritance as a hack to get my behavior for
"free". Inheritance does not feel right to me: what if I want to save a
Customer to a database? Do I have to create a JDBCCustomer subclass of...
Customer? Not of XMLCustomer. But I have instances of XMLCustomer flying
around my app... What if I had a "clean" Customer with all state and
behavior, then I would just instantiate my XML or JDBS subclass just-in-time
for that encoding/decoding task. But then I would need marshalling code
to/from the XML/JDBC subclass, which seems to be redundant with what happens
in JAXB already. Using an encoding subclass in a just-in-time manner also
means that your app would not catch validation error until the last second,
unless you where to duplicate code, which is not acceptable to me (in a
perfect world). If the case of an app with a UI, if the model is backed by a
binding object, you would be able the give feedback right away when an error
is detected in data validation.

JAXB poses some interesting design issues and I wish Sun would at least talk
about them in the JAXB docs/specs. BTW, I did not even mention subclassing
the JAXB generated code which I consider would create the most brittle code
and would be nasty. I think of all JAXB generated code as private to the
"Bindings" helper class. Clearly, there has to be a better way, ot at least
a cleaner way.

Gary

-----Original Message-----
From: Leon Smith [mailto:leon2000_at_pacbell.net]
Sent: Monday, December 23, 2002 2:44 PM
To: JAXB-INTEREST_at_JAVA.SUN.COM
Subject: Using existing classes


Sorry for the last HTML post, my email client is screwy:

Hello, I have been creating an application server for the past two years in
which each of many classes gets loaded from an XML file. I am switching from
my own proprietary binding scheme for performance reasons. My benchmark
programs show JAXB to be very acceptable in terms of speed (roughly twice as
fast as Castor for example), but I am a little mystified about the
requirement to generate new classes from the schema.

Isn't this like requiring new classes for serialization ? Unmarshalling from
XML is just one tiny part of the functionality of these classes. Wouldn't it
make more sense to generate "helper" classes and pass a "target" class as an
argument for unmarshalling ?

How do most people actually make this work in practice ? I have complex
hierarchies established so I really can't subclass from the implementation
classes, plus I don't see how to unmarshall into a subclass anyway.

If I add my behavior to the generated classes, I don't see that it will be
preserved if I have to change the schema and generate again.

I really want to use JAXB, but right now I am at a loss for how I could. Any
suggestiions would be very much appreciated.

Thanks

Leona