For those not in the know, schemagen is a program that comes as part of the Java Web Services Developer Pack and it's used to generated XML schemas from JAXB annotations on Java beans. It so happens that the creators of the JAXB reference implementation also made a Maven 2 plugin for this program. I had previously attempted to use it to generate schemas in my initial attempts with JAXB, but had been presented with a slough of unfriendly exceptions being thrown at me whenever I ran the plugin. Not having the time back then to really play around with it and being considerably less experienced with JAXB, I had to shelve it and find other, less satisfying solutions to my problems with generating documentation.
Recently, I've had to come back to using JAXB because I'm making a RESTful Web Services API that leverages the power of both JAXB and Hibernate to do all my heavy lifting for me. This time around, I wasn't willing to tolerate a lack of schema to give to our users of the API, because it would mean a lot more work for them, and a lot more work for me. This time, I decided to be persistent and dig around the jaxb-schemagen plugin to make sure I could get it working. I'm proud to say that my perseverance paid off, and I now have my RESTful API schema being automatically generated for my application. Here are the problems and the solutions I ran into when I was trying to get going on this:
- I came across persistent NullPointerExceptions while trying to run the plugin at first. The stack trace indicated that the problem was with apt, the Java annotation processing tool. I later discovered that in order to properly map your classes into XSD schema types, you must specify an @XmlType annotation on *all* of the classes you wish to map (at least with JAXB 2.0, which is the version I'm currently using)
- After I resolved the first problem, I came across another pesky exception that likewise did not provide any useful debugging information. The plugin output indicated that it was finding annotations that it didn't know how to deal with, specifically the Java Persistence API annotations that I was using for Hibernate. After much digging around on Google and some detective work, I discovered that any annotations encountered by the jaxb-schemagen plugin had to be on the Maven runtime classpath. I double checked my POM to find that I had specified the scope of the JPA / Hibernate annotations as 'provided', which instructs Maven not to load them into either the compile or runtime classpaths. The initial reason I had for specifying the dependency scope as 'provided' was so that they would not needlessly get included with my project WAR files. I changed their scope to 'compile' (which also includes 'runtime') and voila, apt could now properly detect the unknown annotations, and get past them to deal with the JAXB annotations it needs to create the XML schema.
If anybody else encounters similar errors with JAXB-schemagen, I hope they find this page and find it useful.