users@jaxb.java.net

Re: POJOs and (EJB) annotations

From: Kohsuke Kawaguchi <Kohsuke.Kawaguchi_at_Sun.COM>
Date: Thu, 16 Mar 2006 17:25:06 -0800

Dmitri Colebatch wrote:
> Hi Kohsuke,
>
> Thanks for the response - I'll add my thoughts inline. Note that I'm
> 'thinking aloud' here and I haven't fully thought through the details,
> but am interested in having a conversation to flush out the good and
> bad points so that we might be able to end up in a better place.

Yep. I enjoy this, too.

> On 3/17/06, Kohsuke Kawaguchi <Kohsuke.Kawaguchi_at_sun.com> wrote:
>> The case you mentioned was adding one field, so as you say, that's
>> simple enough. But some of the changes can be more substantial --- for
>> example, one of the things people want to do is to rename the
>> compiler-generated classes (placing it to a proper package can be
>> thought of as a renaming.) And I'm not aware of any good algorithm that
>> lets the compiler do "aha, this complex type is normally generated into
>> foo.bar.Zot but the user moved it to aaa.bbb.Ccc, so OK, I gotta put
>> update there."
>
> Firstly, I agree that this approach wouldn't solve all the problems,
> but then again neither does the current approach.
>
> Secondly, I think the current instructions that one can provide to xjc
> via way of appInfo in the schema could still be used to do simple
> generation instructions such as package/class/field names.

I think those JAXB customizations are awfully complicated --- you first
have to know XML Schema enough to be able to say "this is what I want to
customize", then you have to learn the customization syntax, where
practically only guidance is in the spec (and the focus of the spec is
more about implementors of JAXB and preciseness --- it's not meant to be
  for users.)

If you don't want to change a schema, you then have to learn XPath
enough to be able to write down the exact location in XPath. If you are
doing this from JAX-WS, you have to learn some more.

IMO it's just too much work. In comparison, every Java developer with a
good IDE can instantly rename a method, a class in 5 seconds.

So I'm not saying that the JAXB customization is evil, but if we can use
our IDEs to achieve some of what the customization can do, I think that
would be a big win.

> Thirdly, if the user was to rename a field (or perhaps even a whole
> class) the generator could look for the @XmlElement declaration. Eg,
> continuing from my previous example, suppose the generator finds this:
>
> @Entity
> @Table(name="foo_tbl")
> @XmlRootElement
> class Foo
> {
> @Column(name="bar_column")
> @XmlElement(name="Bar")
> String username;
> }
>
> It wants to generate a field called "bar" for the xml element "Bar".
> But it can look at the existing class, and discover that there is a
> differently named field with that XmlElement annotation already and so
> that must be the field that should be used. Any additional changes
> could then be made to that.

Generally speaking, it has to be bit smarter than that. To do the update
correctly, XJC has to also know how the previous version of the schema
was bound.

For example, that "Bar" element might have been bound to xs:tring, but
in the current version of the schema it might be xs:int. If so, you need
to update that "String" to "int".

But if it's been bound to "xs:int" all along, you just have to assume
that the user really wanted to bind it to String and keep it intact.

Or the content model might get changed. You have to know what needs to
be newly added, removed, changed, and etc.


>> So far, the one approach that I think could work is to use CVS and diff.
>> You generate code from schema, import that to the vendor branch, then
>> make changes locally. When your schema changes, you regenerate it,
>> import that to the vendor branch again, and then do a three-way merge.
>
> Yeah I've had that thought too, but as we all know cvs is fairly
> limited once you start making more substantial changes. In my current
> work I laid a tag when on the first generated code so I could do this
> if I needed, but I've lost confidence in it working as I want to make
> more changes than I think it will allow (including simplifying code by
> removing the use of inner classes).

Right. It's fairly limited --- especially with CVS. For example, if you
rename a class the history is lost.

But I hope my point still stands --- this is really the exact same
problem that the version control system is trying to address. If you
think of XJC as another developer, all you are trying to do is to
control changes by two people.

So I think it might be easier to think of the problem in that way. There
are better VCS than CVS, that can track renaming and other things...


The other direction that I thought might be worth while is to instead of
trying to fix everything automatically, which sounded awfully
complicated to implement, it might be more practical to compare a set of
annotated source code against the schema, and point out any potential
inconsistency.

The idea is that you generate code from v1 schema, make changes, and
when v2 schema comes along, you run the comparison tool, and it points
you to things you need to update. If the changes in the schema is small
enough, this could still be an improvement than the status quo.


> Another approach to this would be to leave the JAXB generation the
> same, and then have some sort of stand alone java code merger that
> could merge/fold the newly generated JAXB code into some modified (but
> previously generated) code. I haven't fully thought this through as
> well, and I think the example above about renaming fields shows that
> whatever did this would have to know a bit about JAXB as well.

I think that's called "version control system" --- I think we are saying
the same thing here.


> haha - yes, and I think you have good reason to be! Although I'm more
> than happy to get my hands dirty on this if it looks feasible.

Cool! I'm looking forward to seeing it.

-- 
Kohsuke Kawaguchi
Sun Microsystems                   kohsuke.kawaguchi_at_sun.com