Igor Kromin |   Consultant. Coder. Blogger. Tinkerer. Gamer.

This issue had me stuck and I still don't know what is causing it. I've noticed that the JAXB behaviour for attributes that are annotated with @XmlIDREF changes based on whether the containing web service defines a SOAPHandler or not. This is all inside WebLogic 12.1.2.

To explain further, I have JAXB generated classes that make up the request for my web service. Inside some of these classes are xs:IDREF type attributes, the XML schema defines the object similar to this (only showing the relevant attributes)...
 XML Schema
<xs:complexType name="StrucDoc.RenderMultiMedia">
<xs:attribute name="referencedObject" type="xs:IDREFS" use="required"/>
...
</xs:complexType>


...which ends up looking like this in Java...
 JAXB Object
@XmlAttribute(name = "IDREF", required = true)
@XmlIDREF
@XmlSchemaType(name = "IDREF")
protected List<Object> referencedObject;


That's nothing too out of the ordinary and very valid to have. So now I added a SOAPHandler to the web service like this...
 Web Service
@HandlerChain(file = "handler-chain.xml")


The defined handler chain has 1 handler that implements SOAPHandler. Again nothing out of the ordinary here on its own.



Now when I processed this unmarshalled object, I got a JAXBElement, then fetched its value object, which gave me the StrucDocRenderMultiMedia object in my case, then I printed out the array of referenced objects. This produced output similar to this...
 Output
JAXB Object --> [email protected]
Value Object --> [email protected]77d92e59


That's all normal because my XML request did indeed have a valid object reference (not shown here).

Now when I removed the @HandlerChain annotation from the web service, the exact same request gave me this kind of output...
 Output
JAXB Object --> [email protected]
Value Object --> [email protected]
Reference Array --> []


The object references were gone!

I tried to track this down to no avail, however what I did discover was this wasn't entirely dependent on having or not having the SOAPHandler. You could have the SOAPHandler and as long as you didn't call context.getMessage() method, the behaviour didn't change. In other words, this was the culprit...
 SOAPHandler
public boolean handleMessage(SOAPMessageContext context) {
Boolean isOutbound = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (!isOutbound) {
...
SOAPMessage soapMsg = context.getMessage(); // <-- this line causes the behaviour change
...


I am guessing that when the SOAP Message is fetched from the context it does some kind of JAXB processing or initialisation that forces object references to resolve correctly, otherwise MOXy just returns an empty reference array.

In my case I actually didn't want these references to be resolved so I changed the generated JAXB classes to use @XmlTransient instead. That does not explain the strange behaviour that I saw, which I'd like to fully understand.

-i

A quick disclaimer...

Although I put in a great effort into researching all the topics I cover, mistakes can happen. Use of any information from my blog posts should be at own risk and I do not hold any liability towards any information misuse or damages caused by following any of my posts.

All content and opinions expressed on this Blog are my own and do not represent the opinions of my employer (Oracle). Use of any information contained in this blog post/article is subject to this disclaimer.
Hi! You can search my blog here ⤵
NOTE: (2022) This Blog is no longer maintained and I will not be answering any emails or comments.

I am now focusing on Atari Gamer.