For this post, I use a very simple example XML Schema Definition that describes XML grammar for storing basic movie information. Although I could generate Java classes from DTD with JAXB, I'm going to use the more typical approach here of using an XSD as the source.

It is easy to generate Java classes using the xjc binding compiler provided with the Oracle's JDK 7 implementation. This is shown in the next screen snapshot.

The command shown in the above screen snapshot (xjc -d src -p dustin.examples Movie.xsd ) places the generated classes in a destination directory specified by the -d option (src) and generates all classes in a package called dustin.examples (based on -p option).

The next screen snapshot shows that the appropriate classes have been generated (two Java classes representing the contents described by the XSD and an ObjectFactory). The Main.java class is not JAXB-generated and was there before running the xjc compiler.

The generated enum representing movie genre is shown next. It's not an issue that it lacks the common methods because, as an enum, these aren't really necessary to be explicitly coded.

Unfortunately, this generated MovieType and Movies classes lack implementations of common methods toString(), equals(Object), and hashCode(). There may be situations in which these methods are desirable. There are several approaches that could be used to deal with this, but the approach that is the focus of the remainder of this post is to use the JAXB2 Basic Plug-ins to instruct the xjc binding compiler to create these methods.

This simple code demonstrates the presence or lack of an overridden equals(Object) method and lack of an overridden toString() method. In this case, using the JAXB RI 2 xjc binding compiler, we see that the lack of these methods leads to surprising results as shown in the next screen snapshot.

The above output demonstrates that even when default xjc-generated JAXB objects are populated with the very same XML source file, they are not considered equal and don't override toString(). This is, of course, because they lack their own overridden versions of these most important methods.

There are numerous ways to handle this if it is necessary to print the contents of a JAXB object instantiated from a default generated class without the common methods. One approach would be to have a third-party class perform equality checks on the two provided objects and provide methods for building String representations of these objects. However, the approach that I focus on for the remainder of this post is that of using the JAXB2 Basic Plugins for equals, hashCode, and toString to have these common methods automatically generated and included in the JAXB/xjc-generated classes when they are constructed.

When the above Ant target is executed, the xjc binding compiler is again run (via the Ant xjc task), but this time uses the three specified plugins to generate the equals, hashCode, and toString methods. The output of this is shown in the next screen snapshot.

The files are all generated again, but they are larger this time because of the common methods and support methods added for those. These generated classes are shown in their directory in the next screen snapshot.

The enum MovieGenre is no different with the plugins, which is fine because enums have reasonable toString methods and their identity and equality comparisons are always the same given the same classloader. The two classes, however, are significantly different with toString(), equals(Object), and hashCode() methods and several supporting methods added to them. I list the generated source code for these two classes, Movies and MovieType, next.

When the simple test is executed against these new generated Java classes, the results are more satisfying.

Using the JAXB2 plugins did what we needed and the JAXB-generated objects with same content are now properly considered equal and there is a better-than-nothing (which is what we had before) String representation of the objects' contents. There is some "cost" to this, however. As the generated code above shows, the JAXB-generated classes must implement specific interfaces and implement significant support methods above and beyond the common methods themselves.

This post has only shown three of the JAXB2 Plugins that are available (some of the others require an extra step of specifying binding customization within the source XSD or within a binding file). Several more are available, but it is especially common to want implementations of toString and equals and hashCode and this post has shown how to get those with JAXB-generated classes using JAXB2 Plugins.