views:

53

answers:

1

I'm using JAXB in a web service with some slightly complex objects. One of the objects, Sensor, has a list of other objects it can communicate with, which necessarily can include itself (behavior that cannot be changed), leading to a cyclic reference during marshalling to XML.

@XmlAccessorType(XmlAccessType.FIELD)
public class Sensor extends BaseObject {

    private ArrayList<SensorCommLink> sensorCommLinks;

}

@XmlAccessorType(XmlAccessType.FIELD)
public class SensorCommLink {

    @XmlIDREF
    private BaseObject receiver;
    @XmlIDREF
    private Sensor cueingSensor;

}

@XmlAccessorType(XmlAccessType.FIELD)
public abstract class BaseObject {

    @XmlElement 
    @XmlID
    private String id;

}

As shown above I solved this using @XmlIDREF and @XmlID and it works very nicely.

The client-side code generated via wsimport marshals the objects to XML and the server is able to unmarshal them perfectly.

The problem I'm experiencing is that for some reason on the server side I am getting a cyclic reference exception when I try to marshal a Sensor object. The maddening part is that the server-side code contains the JAXB annotations that are used by wsimport to create the client-side code, which works great, yet I can't marshal server-side Sensors due to the cycle.

I tried copying all of the extra annotations JAXB adds to the client-side code onto the server-side classes thinking perhaps there was a runtime bug in JAXB that was preventing it from properly applying the @XmlIDREF annotation. No luck there.

Perhaps there's something very basic I'm missing here but this issue is driving me a little batty and I'm at a dead stop while I try to figure it out.

One thing I did notice that I'm investigating is that some of the namespaces on the generated client-side objects aren't what I expected, though the code works. I'm curious to see if somehow a namespace issue on the server is causing the IDREF marshalling to bomb.

Any suggestions for fixes or additional troubleshooting would be much appreciated!

Cheers,

Chris

+1  A: 

Any chance on the server side it is processing properties (get/set) instead of fields (instance variables). You can enforce field access in the following way:

@XmlAccessorType(XmlAccessType.FIELD) public class SensorCommLink {

@XmlIDREF 
private BaseObject receiver; 
@XmlIDREF 
private Sensor cueingSensor; 

}

Or you could annotate the get methods.

Blaise Doughan
Blaise,I don't think so. The @XmlAccessorType(..FIELD) is on the SensorCommLink class -- I just left those extra annotations out of my original post. Perhaps I'll edit it for clarity. Thanks, though.
Chris M