JAXB creating context and marshallers cost
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB 2 (JSR-222) expert group.
JAXBContext
is thread safe and should only be created once and reused to avoid the cost of initializing the metadata multiple times. Marshaller
and Unmarshaller
are not thread safe, but are lightweight to create and could be created per operation.
JAXB one Marshaller instance and Unmarshaller instance per application
Caching Marschaller
and Unmarshaller
is not a good idea. Cache the JAXBContext
instead.
JAXBContext
may be reused to create marshallers and unmarshallers.
Marshaller
and Unmarshaller
instances are NOT (necessarily) thread-safe or reusable.
I'll look for the references and update the answer.
Here's the reference:
The JAXBContext class is thread safe, but the Marshaller,
Unmarshaller, and Validator classes are not thread safe.
Related answer:
JAXB creating context and marshallers cost
How do I improve performance of application that uses the JAXBContext.newInstance operation?
A JAXB implementation (Metro, EclipseLink MOXy, Apache JaxMe, etc) typically initializes its metadata during the JAXBContext.newInstance
call. All OXM tools need to initialize mapping metadata at some point and try to minimize the cost of this operation. Since it is impossible to do it with zero cost, it is best to only do it once. Instances of JAXBContext are thread safe, so yes you only need to create it once.
From the JAXB 2.2 Specification, Section 4.2 JAXB Context:
To avoid the overhead involved in
creating a JAXBContext instance, a
JAXB application is encouraged to
reuse a JAXBContext instance. An
implementation of abstract class
JAXBContext is required to be
thread-safe, thus, multiple threads in
an application can share the same
JAXBContext instance.
Instances of Marshaller and Unmarshaller are not thread safe and must not be shared among threads, they are lightweight to create.
JAXB Marshaller indentation
This annoying issue could be fixed by applying javax Transformer to the output.
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.StreamResult;
Object jaxbElement = // The object you want to marshall using jaxb.
JAXBContext context = JAXBContext.newInstance(jaxbElement.getClass());
Marshaller marshaller = context.createMarshaller();
OutputStream out = // Here your destination, FileOutStream, ByteOutStream etc
DOMResult domResult = new DOMResult();
marshaller.marshal(jaxbElement, domResult);
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
transformer.transform(new DOMSource(domResult.getNode()), new StreamResult(out));
JAXB marshalling superclass
I'm not sure how you're configuring the JAXB context or marshaller but the following:-
public static void main(String[] args) throws Exception
{
Employee employee = new Employee();
employee.setId(1);
employee.setName("Ralph");
JAXBContext context = JAXBContext.newInstance(Employee.class);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(employee, System.out);
}
gives:-
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<employee>
<name>Ralph</name>
<id>1</id>
</employee>
JAXB and marshalling
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.
The behaviour you are seeing will differ upon which implemenation of JAXB you are using. The MOXy implementation will give you the result you are looking for. I will demonstrate below.
JAVA MODEL
Below is the Java model that will be used for this example. The package level @XmlSchema
annotation will be used to specify the namespace qualfication in each of the packages (see: http://blog.bdoughan.com/2010/08/jaxb-namespaces.html).
forum13408684.a.A
package forum13408684.a;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class A {
}
forum13408684.a.package-info
@XmlSchema(namespace="A", elementFormDefault=XmlNsForm.QUALIFIED)
package forum13408684.a;
import javax.xml.bind.annotation.*;
forum13408684.b.B
package forum13408684.a;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class B {
}
forum13408684.b.package-info
@XmlSchema(namespace="B", elementFormDefault=XmlNsForm.QUALIFIED)
package forum13408684.b;
import javax.xml.bind.annotation.*;
DEMO CODE
package forum13408684;
import javax.xml.bind.*;
import forum13408684.a.A;
import forum13408684.b.B;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(A.class, B.class);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(new A(), System.out);
marshaller.marshal(new B(), System.out);
}
}
OUTPUT
JAXB Reference Implementation
The output below matches what you described in your question:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<a xmlns="A" xmlns:ns2="B"/>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:b xmlns="A" xmlns:ns2="B"/>
EclipseLink JAXB (MOXy)
If you specify MOXy as your JAXB provider (see: http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html) you will get the output you are looking for.
<?xml version="1.0" encoding="UTF-8"?>
<a xmlns="A"/>
<?xml version="1.0" encoding="UTF-8"?>
<ns0:b xmlns:ns0="B"/>
Related Topics
Find an Array Inside Another Larger Array
How to Redirect to Another Action Class Without Using on Struts.Xml
Why I'm Not Able to Unwrap and Serialize a Java Map Using the Jackson Java Library
How to Upper Case Every First Letter of Word in a String
Java.Lang.Nosuchmethoderror in Flink
Performance Difference Between Java 8 Lambdas and Anonymous Inner Classes
Does Adding a Jlabel to a JPAnel "Hide" the JPAnel
How to Achieve Transfer File Between Client and Server Using Java Socket
How to Write Swap Method in Java
Eclipse - Debugger Doesn't Stop at Breakpoint
Jtable + Sorting Specific Field
Calling Static Method from Another Java Class
Service Layer and Controller: Who Takes Care of What
Java Web Service Client Basic Authentication
Pdfbox - Signature Validity Checkmark Not Visible in Acrobat Reader