users@jaxb.java.net

Re: Using existing classes

From: Greg Scott <gptscott_at_googlemail.com>
Date: Mon, 27 Aug 2007 16:11:55 +0100

Hello,



I have been searching the JAXB documentation for a discussion of a
design-related problem I have with JAXB and incorporating it into an design
(set of classes and interfaces). Reassuringly, I found this posting from
this mailing list which almost completely captured my exact same problem (I
have pasted it below):
https://jaxb.dev.java.net/servlets/ReadMsg?listName=users&msgNo=150



I noticed this was from 2002! Given the old age of this posting, could I
raise this issue again, in the hope that, with the newer versions of JAXB or
different thinking, someone could offer a better way around this problem
than that suggested in (1).



Many thanks for any advice.



Greg Scott









Date: Tue, 24 Dec 2002 11:39:00 -0500

From: Gary Gregory <ggregory_at_seagullsw.com>

Subject: Using existing classes

Content-type: multipart/alternative;

 boundary="Boundary_(ID_58uuYtbp6qs51bz0CUtMnw)"



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