Skip to Main Content

Java EE (Java Enterprise Edition) General Discussion

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Making properties transient from an out of reach parent class with JAXB

843834Jan 4 2010
Hi all,

I'm working with Jaxb in combination with XMPP (using the SMACK) library. I am using / want to use JAXB for the marshalling and unmarshalling of java objects. I have written some bridging code which registers JAXB based marshalling / unmarshalling instead of regular xmlpullparser based parsing ...

My initial approach was to wrap the objects to be (un)marshalled (the contents of the messages to send/receive), however it seems more developer friendly when a message object EXTENDS the so called IQ class from the SMACK library instead. This allows setting fields such as from and to directly on the custom message class. Otherwise developers would need to keep track of both the wrapper as well as the wrapped object.

The problem however is that the extended class (org.jivesoftware.smack.packet.IQ) has some properties which JAXB doesn't appreciate (a non-static inner class and a class without a no-arg constructor). When this IQ class would be under my control I would have resorted to annotating these properties with the @XmlTransient annotation. Unfortunately however this class is part of a library and not controllable. Initially I thought overriding the getter methods for these properties and annotating them with @XmlTransient would resolve this, but apparently this provides no solution as JAXB marks the property of the subclass as transient but not the property of the super class. I have included some code below which illustrates this behavior.

Does anyone have a solution for marking properties as transient (for JAXB) or in general adding annotations to classes 'out of reach'?

Thanks in advance,
Frens Jan Rumph

--- Problem illustration ---

The code example below illustrates my problem. Executing the code results in:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><subClass><field>field-value</field></subClass>
(obj2.getField() == null) = false, test failed
while I hoped for:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><subClass/>
(obj2.getField() == null) = true, test passed
import java.io.*;
import javax.xml.bind.*;
import javax.xml.bind.annotation.*;

public class JaxbTransientTest {
	public static void main(String[] args) throws JAXBException {
		// create the jaxb context and (un)marshaller
		JAXBContext ctxt = JAXBContext.newInstance(SuperClass.class, SubClass.class);
		Marshaller marshaller = ctxt.createMarshaller();
		Unmarshaller unmarshaller = ctxt.createUnmarshaller();

		// instantiate the sub class and set its field
		SuperClass obj1 = new SubClass();
		obj1.setField("field-value");

		// marshall the subclass instance and write it to sysout
		StringWriter sw = new StringWriter();
		marshaller.marshal(obj1, sw);
		System.out.println(sw);

		// unmarshall the subclass instance and check whether the field is null
		SuperClass obj2 = (SuperClass) unmarshaller.unmarshal(new StringReader(sw.toString()));
		System.out.print("(obj2.getField() == null) = ");
		System.out.println((obj2.getField() == null ? "true, test passed" : "false, test failed"));
	}

	@XmlRootElement
	public static class SuperClass {
		private String field;

		public String getField() {
			return field;
		}

		public void setField(String field) {
			this.field = field;
		}
	}

	@XmlRootElement
	public static class SubClass extends SuperClass {
		@Override
		@XmlTransient
		public String getField() {
			return super.getField();
		}
	}
}
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Feb 1 2010
Added on Jan 4 2010
0 comments
693 views