Options for JAXB 2.1 Bindings Customization - java

I am working on generating Java objects from an XSD file using JAXB 2.1. The XSD file has several elements in it representing business model entities, with common names like Account, etc. The system which is using the generated files to unmarshal the XML has several conflicting class names in its domain model. Though we can use different package names to get around class name conflicts, I think it will be more readable/maintainable to have objects of different names.
Because of this, I'd like to alter the XJC compilation so that is produces objects like: DataTransferAccount.java, etc. instead of Account.java. Super, I'll use one of the two options JAXB provides when binding a schema (http://java.sun.com/webservices/docs/2.0/tutorial/doc/JAXBUsing4.html):
Inline Customizations - Annotate the XSD itself using the jaxb namespace to specify class names
External Bindings File - Provide an extra file to the XJC which has rules on how to map schema elements to java classes
Is there a good argument for using option 1, aside from the ease of use? Naively, I'm tempted to use it because it is easy, but down the road I can see maintenance headaches if we decide to move away from JAXB XML unmarshalling.

Your instincts are good - the only situation in which I'd consider adding inline annotations to the schema is if you or your developers were the ones responsible for maintaining the schema itself.
If the schema is someone else's, and there's any danger of it changing in future, then resist the temptation - use an external binding customization. Yes, it's a bit awkward to use, but it's worth the effort.
As for your original issue of name clashes, an XML Schema is not allowed to re-use the same name either. The only way you should be getting name clashes in the generated Java is if you're compiling schemas from multiple namespaces into the same java package. If you have multiple namespaces, I strongly suggest you put each namespace into its own package, it does tend to make things clearer. It also avoids these name clashes.

Related

What's the correct or proper way to specify XSD schemaLocation across projects?

Say I have two projects, A and B. Java projects, in case that's important.
Project A contains a bunch of XSD files that represent core types and elements. They are all placed in a package called, say, "definition". This gets built into project-a.jar.
Project B represents an extension project, and it's allowed to defined its own types and elements. I created a new schema and placed it in "definition.extension" package. This gets built into project-b.jar.
Now, for the XSDs in Project B, what exactly should I put as the schemaLocation for an include?
schemaLocation="../core-types.xsd" didn't quite work (I know, it's needs a URI), but what exactly is the proper or standard approach to this? Google found me more people asking this question that clear-cut, standard approaches on what really is the correct way to handle this.
It can't be that I have programmatically adjust the schemaLocation during runtime... or that I'd need a build step/script that will dynamically replaced the schemaLocation during compilation... right?
I'm not looking for answers like "put them in a shared location". I'm looking for something more along the lines of a dev environment that uses relative references instead of hardcoded references.
FYI, I'm using IntelliJ IDEA, in case there's an IDE-specific approach.
If you just want IntelliJ to stop showing your includes in red, you can use some custom URI in your include. You then go to Project Settings -> Schema's and DTD's where you can map this URI onto a local file.
If you need to do schema validation at run time, that's a different story. You probably need to use an XML Catalog. If you're using JAXB, you should have a look at this question: jaxb - how to map xsd files to URL to find them
You should use XML Catalogs. This link gives a thorough introduction to XML catalogs - and how to use them in Java for instance - by XML expert Norman Walsh. Quote:
These catalog files can be used to map public and system identifiers and other URIs to local files (or just other URIs).
The aforementioned identifiers are typically the schemalocations or namespaces you use in schema imports.
When using such catalogs, in order to avoid confusions and some bug in XJC, I strongly recommend you remove all schemaLocations from the schema imports in XML schemas, and only keep the namespace (if you have a choice of course). For example:
<import namespace="http://www.w3.org/1999/xlink" />
Then specify the mappings for each namespace to the actual schema location in the catalog. For example, using the OASIS XML catalog format:
<?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<uri name="http://www.w3.org/1999/xlink" uri="w3c/1999/xlink.xsd" />
</catalog>
At compilation time, if you are generating JAXB-annotated classes from the schemas, I recommend you use Episodes to achive separate schema compilation aka modular schema compilation. This is supported by maven-jaxb2-plugin for instance, which also has advanced support for catalogs.
For runtime, depending on your XML use case, you should try to use a library with native support for XML catalogs, such as most Java web service frameworks (JAX-WS RI/Metro, Apache CXF...) if you are developing web services for example. If you can't or if you want finer control over the XML catalog (e.g. being able to load schemas from the classpath), I invite you to look at the XML Entity and URI Resolvers page mentioned earlier, especially the sections Using Catalogs with Popular Applications and Adding Catalog Support to Your Applications. Basically, you play with org.apache.xml.resolver.tools.CatalogResolver and optionally (for finer control) org.apache.xml.resolver.CatalogManager classes. For concrete examples of custom CatalogResolver/CatalogManager, you may look at code sources from Apache commons-configuration, AuthzForce, CXF, etc.

what is the benefit in dynamically generating java bean classes from xml?

I had written a lot of java bean classes using my IDE. Another person suggests a different approach. He suggests that I put an xml file with bean definitions in them. Then I either use jaxb or xslt to dynamically generate the classes during build time. Though its a novel and interesting approach, I do not see any major benefit in it.
I see only one benefit in this suggested approach : The java bean classes need not be maintained in configuration control. Any bean changes is going to require only an update in the xml file.
Are there any major benefits in dynamically generating java classes ? Is there any other reason why this approach is taken ?
I agree with #Akhilss. My experiences have been in large scale Java EE projects where code generation is common.
It all depends on your project. If you are coding only a few beans and only need basic functionality then I don't see the need to start with XML (Which is often over used anyway). Especially if you actually don't need the XML as well.
However if you are building a system which needs the XML, an example being a SOAP web service WSDL and schema, then generation is a good idea because it saves you from manually keep schemas and beans in sync. As well as providing factory classes and other support code.
As a counter argument, with EJB3 and similar standards, it's now often easier to write the beans and generate the messy XML stuff on the fly. Ie. let the server do the grunt work.
Another reason to consider code generation is if you require more complex functionality in your beans because they represent data structures. A few years ago I trialled the Apache Tuscany project for generating SDO beans from XML. The nice thing about that was that I could generate functionality like property change notifications so when I modified any of the bean's properties (including collections), other parts of your program could be notified automatically. Generated functionality like that can save you a lot of time and money if you need it.
Ultimately, I'd suggest adhering to the KISS principle. So don't add what you don't need. Generated code from XML is useful if it helps you in the long run. But like any technology, be sure you are adding it for the right reasons.
I have used Jibx and its generator in my project. My experience has been mixed.
The usual case for using JAXB's (XJC) generator is referred to in http://static.springsource.org/spring-ws/site/reference/html/why-contract-first.html
Conversion to and from XML maked it possible to store in the DB and retrieve for future use as well as use for test case input for functional tests.
Using any kind of generator (Jaxb,Jibx,XMLBeans,Custom) might make sense for large sized projects. It allows for standardization of data types (like BigDecimal for financial amounts, like ArrayList for all lists), forcing interfaces (like Serializable or Cloneable). This enforces good practices and reduce the need for reviews of generated files.
It allows for injection of code through XSLT or post processing of generated java file. Example is to inject Rounding code to a specific decimal size(2,6,9) with a specific policy (UP,DOWN,NEAR) within the setter method for each field of type financialAmount. Forcing such behavior does reduce the instance of bugs(for incorrect financial values which companies are liable for).
The disadvantage are
Usually each java class can be only a bean class. Any customization made will be overwritten. Since (in my case) the generator is tied in to the build process. The classes get generated with every build.
You cannot do implementation of your custom interfaces on a bean class or add annotations for your own or third party frameworks.
You cannot easily implement patterns like a factory method since default constructors are usually generated. Refactoring is usually difficult since generators do not usually support it.
You may(not sure now, was true a couple of years ago for Jibx) not be able to generated ENUMS when it would be most applicable.
You may not be able to override the default datatype with your own regardless of the need. CopyOnWrite list and not ArrayList for a variable shared across threads or a custom implementation of a List which also implements the Observer pattern.
The benefits of a generator outweigh the costs for large sized (in persons and not code, think 150 developers in three locations) distributed projects. You can work around the disadvantages by defining your custom classes which contain the bean and implements behaviour or post processing (adding additional code) with further metadata picked up from XSD annotations or another configuration file. Remember support and Maintenance of the generator become critical since the entire project depends on it. Use it with CAUTION.
For smaller sized projects I personally would write my own classes. For larger sized projects I personally would not use it in the middle tier mostly because of the lack of refactoring support. It can be used for simple beans meant to be bound to UI frameworks.

Dealing with shared namespaces with multiple WSDL's (xmlbeans)

I have five WSDL's that share namespaces, but not all of them. I generate client code out of them (databinding with XMLBeans). Seperately they compile fine. I create JAR files out of each generated client code.
Once I try to use all JAR files within a project, I get naming / compile conflicts.
I want to reuse as much as possible. Is there any smart way to deal with this (rather than giving each client an own node in the package structure)?
The XMLBeans (2.x) faq notes the limitations of xsdconfig namespace mapping:
Note: XMLBeans doesn’t support using two or more sets of java classes (in different packages) mapped to schema types/elements that have the same names and target namespaces, using all in the same class loader. Depending on the direction you are using for the java classes to schema types mapping, some features might not work correctly. This is because even though the package names for the java classes are different, the schema location for the schema metadata (.xsb files) is the same and contains the corresponding implementing java class, so the JVM will always pick up the first on the classpath. This can be avoided if multiple class loaders are used.

What's the point of package annotations?

I understand the purpose of class annotations, thanks to How and where are Annotations used in Java?. What is the purpose of package annotations, as described in this blog post and §7.4.1 of the Java Language Specification?
Why would you want to associate metadata with a package? What kinds of things could you do?
bnd tool (and maven-bundle-plugin) makes use of package annotations. Putting #Version and #Export annotation in package-info.java allows it to generate OSGi metadata.
javadoc uses package annotations.
JAXB uses package-level annotations, for example, to specify mapping of a Java type to XML Schema type package-wide. Package annotations are also used in JBoss's xml binding.
Struts 2 Convention plugin uses an annotation to specify a default interceptor for all actions in a package.
There are some package-level Hibernate Annotations. An example of those annotations' usage can be found here.
I suppose #Deprecated would make sense. And maybe something like #Generated if the whole package was generated by some tool from non-Java source. Or #Internal if this package is not part of a public API.
Maybe OSGi tools (where you need to declare the versions of your packages, and the packages you depend on) could make use of this, too.
Has anyone seen those in the wild?
Two reasons that I can think of:
Annotating special packages to let some aspects (for example using AspectJ) to weave the classes in them for specific functionality.
Annotating some packages that are to be read by some tools, for example for source, meta-data or other kinds of resource generation.
JAXB for example allows most annotations that are normally used on a type to be equally well applied to a package. The meaning in that case would be to specify the default for all classes in that package.
For example, if you want all properties of all classes in a package that are exposed via getter/setters to be mapped in XML you could specify #XmlAccessorType(XMLAccessType.PROPERTY) on each class or simply specify it on the package.
This is not the real purpose, but I'm using them as a workaround to avoid recompilation of the package-info.java files.
The problem is that javac (and the Ant task <javac>) creates no class file for the package-info.java if there is only documentation (the reason for their existence) and the package bla; statement, and that the ant task recompiles every file for which there is no (or an older) corresponding .class file.
Adding a dummy annotation there (like SuppressWarnings) had the effect that a package-info.class is produced and thus the file is not recompiled until changed again.
(Ant 1.8.0 solved this by creating an empty package-info.class, even if there was no annotation, but I'm using an older ant here.)
Test metadata -- that is metadata around test packages (unit tests or otherwise). You can ascribe various pieces of test metadata that are appropriate at the package level, such as: features, owners, versions, bugs/issues, etc. These could be refined at the class or method level, but having package-level definitions or defaults could be handy for brevity. I've utilized a variant of this approach (before the benefit of annotations).
A similar argument could be made for generalized code metadata around the same sorts of things: features, ownership, defects, historical information, etc.

In Java for XML marshalling/unmarshalling which utility should we use from JAXB, JIBX, CASTOR, ADB etx?

In Java for XML marshalling/unmarshalling one can use JAXB, JIBX, CASTOR, ADB etc.
But out of these which is most generic & commonly used? Or is there any other utility available?
The standard is the JAXB (JSR 222), and the famous project with this name is the reference implementation. Unlike JAXB 1.0, JAXB 2.0 RI is quite good, and I've used it a lot. Other libraries implements the JAXB standard (I think tha Castor and JiBX, but I have no experience with them).
I've also use XStream, which was very easy and simple - it has a proprietary API though.
I don't know of any benchmark other than https://bindmark.dev.java.net/old-index.html - notice it is a 4 year old one. perhaps you can take it's ideas or any usable code it may have and run some tests yourself.
I personally use XMLBeans. I like it more than JAXB (and I am biased in favour of things from Sun since they should be more "standard"). I cannot speak to the commonly used part of it though.
JAXB is preferred because of following reasons:
No extra jaxb libraries are required if you are using JDK1.6 or above, because JAXB is bundled in JDK 1.6.
The jaxbMarshaller.unmarshal() contains a lot of overloaded methods, find one that suit yours.
JAXB is pretty easy to understand and operate. what it requires is couple of annotations like #XmlRootElement and #XmlAccessorType along with four lines of code
Modifying XML files in Java is much easier using JAXB as compared to other XML parsers like DOM and SAX because you only deal with POJOs
JAXB is more memory efficient than DOM or SAX parser.
JAXB doesn't require XML schema to work. Though you can use XML Schema for generating corresponding Java classes and its pretty useful if you have large and complex XML Schema which will result in huge number of classes but for simple usage you can just annotate your object with relevant XML annotations provided by JAXB package i.e. java.xml.binding and you are good to go.
I use CASTOR mapping and IMHO it is very easy to use provided you are familiar with XML. All you need to do is to create Java objects and map them to the XMl using a mapping file. The mapping file is required if your XML is a complex one. If it is a simple and straight forward XML, CASTOR will itself look for respective Java class which matches the XML element name [Castor uses Java's Reflection APIs to do this].

Categories

Resources