Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I extend Java code generated by JAXB, CXF or Hibernate tools?

With generated Java source code, like

  • code generated with Hibernate tools
  • code generated with JAXB schema binding (xjc)
  • code generated with WDSL2Java (cxf)

all generated classes are "value object" types, without business logic. And if I add methods to the generated source code, I will loose these methods if I repeat the source code generation.

Do these Java code generation tools offer ways to "extend" the generated code?

For example,

  • to override the ToString method (for logging)
  • to implement the visitor pattern (for data analysis / validation)
like image 410
mjn Avatar asked Apr 23 '09 06:04

mjn


4 Answers

For JAXB, see Adding Behaviours.

Basically, you configure JAXB to return a custom instance of the object you'd normally expect. In the below example you create a new object PersonEx which extends the JAXB object Person. This mechanism works well in that you're deriving from the generated classes, and not altering the JAXB classes or schemas at all.

package org.acme.foo.impl;

class PersonEx extends Person {
  @Override
  public void setName(String name) {
    if(name.length()<3) throw new IllegalArgumentException();
    super.setName(name);
  }
}

@XmlRegistry
class ObjectFactoryEx extends ObjectFactory {
  @Override
  Person createPerson() {
    return new PersonEx();
  }
}

Note that the @Override directive is important in case your JAXB object changes - it will prevent your customisation becoming orphaned.

like image 113
Brian Agnew Avatar answered Nov 13 '22 21:11

Brian Agnew


As for Hibernate you may tweak the template files used in code generation to change their behaviour. If you want to tweak the HIbernate Tools you can edit, for example: dao/daohome.ftl

You may even add fields to the "toString()" output editing the .hbm.xml files

...
<property name="note" type="string">
    <meta attribute="use-in-tostring">true</meta>
    <column name="note" />
</property>
...

Both for logging and validation you may consider using AOP with AspectJ (I don't recommend messing with the generated code, since you might want to build that from scratch many times over).

like image 28
Manrico Corazzi Avatar answered Nov 13 '22 21:11

Manrico Corazzi


First I would reiterate that modification of generated code has many problems associated with it and that, where possible it should be avoided. That said sometimes this is impractical to avoid or more effort than just dealing with the changes when the code is regenerated.

Sadly java doesn't support the concept of partial classes that c# has. These are precisely to solve this sort of problem.

You should see if your code generation tools support some form of meaningful comments which delimit regions added by yourself in the class (this is unlikely and won't help if you are modifying the code rather than adding to it)

You best option if you really wish to do this is to generate the files initially but check them into a version control repository immediately. Then make your changes, check that in.

Next time you rerun the tools and let them overwrite the existing files you can diff against your source controlled ones and merge the changes back in (most trivial changes like addition of new columns/tables will be little effort.

This will not help you as much if the code generator suddenly generates radically different code (say a new version) but in those cases any code you added which wasn't simply additional convenience methods relying on data/methods already exposed publicly) will have problems no matter how it is mixed into the class. The version control system does still help however since it also records the original changes so you can see what you had added previously and what, one would assume, you need to recreate in the new style.

like image 4
ShuggyCoUk Avatar answered Nov 13 '22 23:11

ShuggyCoUk


It is not a good idea to edit generated code files, either by editing the files them selves or by subclassing. Whatever you do, be sure to leave the signature created by the tool intact, so that it will be possible to understand in the future that the file was auto-generated.

I recommend that you research the command options of the tools to see if they allow you some flexibility. Some tools can generate abstract classes or interfaces instead of concrete classes. If this is not possible, create a domain object that includes the autogenerated object as a member variable.

like image 3
kgiannakakis Avatar answered Nov 13 '22 23:11

kgiannakakis