[SWS-870] WS-Addressing headers missing from synchronous SOAP responses Created: 31/Mar/14  Updated: 17/Sep/14  Resolved: 14/Apr/14

Status: Resolved
Project: Spring Web Services
Component/s: Core
Affects Version/s: 2.1.4
Fix Version/s: 2.2.RC1

Type: Bug Priority: Major
Reporter: Ivan Brencsics Assignee: Arjen Poutsma
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
is duplicated by SWS-871 Security Headers missing with XwsSecu... Resolved


WS-Addressing headers are missing from synchonous SOAP responses:

By debugging Spring-WS, we found that the AddressingEndpointInterceptor inserts the header values correctly in the SOAPMessage, and even the SOAPMessage parameter of the Saaj13Implementation.writeTo() contains the right WS headers. But when message.writeTo(outputStream) is called, the headers are not serialized.

If in the beginning of the method Saaj13Implementation.writeTo() we call message.saveChanges() without checking message.saveRequired(), the WS-A headers are serialized correctly. We assume that the flag that controls if save is needed might not be correctly set by a previous method.

Comment by Arjen Poutsma [ 10/Apr/14 ]

Could you please indicate your runtime environment? (JDK, app server, etc. with version numbers).

Comment by Ivan Brencsics [ 10/Apr/14 ]

Please find the parameters here:

$ /usr/java/default/bin/java -version
java version "1.7.0_51"
Java(TM) SE Runtime Environment (build 1.7.0_51-b13)
Java HotSpot(TM) Client VM (build 24.51-b03, mixed mode, sharing)

$ cat /etc/release
CentOS release 5.10 (Final)

Apache Tomcat Version 7.0.37

Comment by Arjen Poutsma [ 10/Apr/14 ]

The reason I asked is that we got two similar issues around the same time (this one and SWS-871), while I don't recollect making any changes in the header code recently. I suspected it might have had something to do with JDK 8 coming out and changing SAAJ behavior, but that doesn't seem to be the case.

I will investigate further next week.

Comment by Ivan Brencsics [ 10/Apr/14 ]

Thanks a lot for investigating. I also noticed that the other ticket (871) has the same problem, and the same conclusion. Probably it is not an accident. Although I cant imagine what could happen to SAAJ, but the fact is that if I call the saveChanges() unconditionally, the WSA headers are serialized correclty.

Comment by Arjen Poutsma [ 10/Apr/14 ]

Indeed, it appears that changing it to an unconditional saveChanges() would do the trick.

But first I would like to understand what caused these two bugs to appear all of a sudden, when the underlying SAAJ code in Spring-WS has been pretty much the same since version 1.0 was released over five years ago. We've never had SOAP headers disappear in all that time, and now we get two reports on a single day. That much coincidence makes me suspicious and I want to investigate it more.

Comment by Matthew Leese [ 10/Apr/14 ]

I also found it quite the coincidence that both bug reports were written on the same day.

I was able to track down our issue to Spring Integration. The DefaultSoapHeaderMapper sets the SOAP action on the SOAPMessage (this functionality was added in Spring Integration 2.1). This causes the SOAPMessage to call saveChanges() which sets needsSave to false. After this, the security headers are added. When SOAPMessage.writeTo() is called, it doesn't call saveChanges() again because needsSave is false.

So I think the true culprit is the changes made in Spring Integration. They just excercise an underlying bug in Spring WS.

Incidentally, SOAPMessage.writeTo() sets needsSave to true so if you set on the trace level logging on the WebServiceTemplate, the message transmission will work with the security headers attached.

Comment by Arjen Poutsma [ 10/Apr/14 ]

Ivan Brencsics are you also using Spring Integration, by any chance?

Comment by Ivan Brencsics [ 10/Apr/14 ]

No, we dont use Spring Integration.

Comment by Ivan Brencsics [ 10/Apr/14 ]

I did some investigation, but still confused. The SAAJ MessageImpl.needsSave() method has this comment: "All write methods (i.e setters) should call this method in order to make sure that a save is necessary since the state has been modified".

The only thing I can imagine is that in some setter in SAAJ the needsMethod() is not called, and finally in the Saaj13Implementation the saveChanges() is not triggered. Maybe it would make sense calling the needsSave() manually as the last step of the interceptors that inject the WSS, WSA headers.

Comment by Ivan Brencsics [ 11/Apr/14 ]

I can confirm what Matthew wrote. If I set the logging level to TRACE for the org.springframework.ws package, the problem is fixed. In case of TRACE level:
1) in the log entry the WSA headers are missing (the first call to writeTo() is not correct), but the save flag is configured
2) but when the Saaj13Implementation calls the writeTo() the second time, the WSA headers are correct on the wire.

Comment by Arjen Poutsma [ 14/Apr/14 ]

Fixed by calling saveChanges unconditionally now. Thanks for the help, everybody.

Comment by Ivan Brencsics [ 17/Sep/14 ]

Let me just share here that there might be a side effect of this fix:

Generated at Sun Oct 21 21:57:11 UTC 2018 using JIRA 7.9.2#79002-sha1:3bb15b68ecd99a30eb364c4c1a393359bcad6278.