I recently used maven-jaxb2-plugin to generate java classes based on xml schemas (xsd). I can run "mvn compile" on command line to generate java classes with the following configuration:
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
However, my Eclipse shows the following error:
Plugin execution not covered by lifecycle configuration: org.jvnet.jaxb2.maven2:maven-jaxb2-plugin:0.8.1:generate (execution: default, phase: generate-sources)
This error prevents Eclipse generating java source codes and adding the generated sources to the class path. In order to fix this problem, I need to install m2e connector for maven-jaxb2-plugin. I can manually install it to Eclipse with the following update site:
http://bitstrings.github.com/m2e-connectors-p2/milestones/
However, Eclipse provides a better to install it. Eclipse shows the problem with the following:
Roll the mouse over <execution>, it displays the following:
Click the link "Discover new m2e connector", and eclipse will try to find the correct connector automatically:
Eclipse found the same m2e connector. Click finish to install it. After I installed it successfully, Eclipse is happy with maven-jaxb2-plugin.
This approach can be applied to other plugins too.
Search This Blog
Showing posts with label jaxb. Show all posts
Showing posts with label jaxb. Show all posts
Sunday, June 24, 2012
Sunday, September 11, 2011
Creating JaxContext is slow
Recently, I need to create xml or json from a POJO. I used JAXB and jettison to do the job. At the beginning, I create the following class:
However, the above implementation is really slow. The reason is that it is slow to create JAXBContext because it uses reflection to parse the object's annotation. Since JAXBContext is thread safe, it should be only created once and reuse it. Here is the new version of implementation:
Also, toJson is 5 times slower than toXml. Since the response time meets SLA, I didn't bother to use other JSON implementation (like jackson).
import java.io.Writer;
import javax.xml.bind.*;
import javax.xml.stream.XMLStreamWriter;
import org.codehaus.jettison.mapped.*;
public class BadJaxbPrinter {
/**
* To print an object to xml format
* @param writer
* @param jaxbAnnotedObj the object to be printed. The class must be annoted with @XmlRootElement
* @throws JAXBException
*/
public void toXml(Writer writer, Object jaxbAnnotedObj) throws JAXBException {
JAXBContext context = JAXBContext.newInstance(jaxbAnnotedObj.getClass());
Marshaller marshaller = context.createMarshaller();
marshaller.marshal(jaxbAnnotedObj, writer);
}
/**
* To print an object to json format
* @param writer
* @param jaxbAnnotedObj the object to be printed. The class must be annoted with @XmlRootElement
* @throws JAXBException
*/
public void toJson(Writer writer, Object jaxbAnnotedObj) throws JAXBException {
Configuration config = new Configuration();
MappedNamespaceConvention convention = new MappedNamespaceConvention(config);
XMLStreamWriter xmlStreamWriter = new MappedXMLStreamWriter(convention, writer);
JAXBContext context = JAXBContext.newInstance(jaxbAnnotedObj.getClass());
Marshaller marshaller = context.createMarshaller();
marshaller.marshal(jaxbAnnotedObj, xmlStreamWriter);
}
}
However, the above implementation is really slow. The reason is that it is slow to create JAXBContext because it uses reflection to parse the object's annotation. Since JAXBContext is thread safe, it should be only created once and reuse it. Here is the new version of implementation:
public class JaxbPrinter {It is 25 times faster than the previous version with 10000 executions of toXml. Note that Marshaller and Unmarshaller are not thread safe and it is cheap to recreate them.
private final MappedNamespaceConvention convention;
//creating JaxbContext seems expensive, do NOT recreate it
private final JAXBContext context;
public JaxbPrinter(Class<?> clazz) throws JAXBException {
Configuration config = new Configuration();
convention = new MappedNamespaceConvention(config);
context = JAXBContext.newInstance(clazz);
}
/**
* To print an object to xml format
* @param writer
* @param jaxbAnnotedObj the object to be printed. The class must be annoted with @XmlRootElement
* @throws JAXBException
*/
public void toXml(Writer writer, Object jaxbAnnotedObj) throws JAXBException {
Marshaller marshaller = context.createMarshaller();
marshaller.marshal(jaxbAnnotedObj, writer);
}
/**
* To print an object to json format
* @param writer
* @param jaxbAnnotedObj the object to be printed. The class must be annoted with @XmlRootElement
* @throws JAXBException
*/
public void toJson(Writer writer, Object jaxbAnnotedObj) throws JAXBException {
XMLStreamWriter xmlStreamWriter = new MappedXMLStreamWriter(convention, writer);
Marshaller marshaller = context.createMarshaller();
marshaller.marshal(jaxbAnnotedObj, xmlStreamWriter);
}
}
Also, toJson is 5 times slower than toXml. Since the response time meets SLA, I didn't bother to use other JSON implementation (like jackson).
Labels:
java,
jaxb,
json,
POJO,
POJO to json,
POJO to xml,
xml
Subscribe to:
Posts (Atom)