JAX-WS empty response in WebSphere but not in Tomcat - java

I'm developing a simple SOAP JAX-WS WebService.
I'm on JRE 7, so I had to pick quite old libraries because I'll have to deploy on WebSphere 8.5.
I used Spring and CXF.
Testing with soapUI I see the response object is empty on WebSphere and correctly represented in Tomcat 7 (run with a JDK 7), but everything is ok with execution (I can see log trace and DB updated), on both dev an prod environment.
On the other hand, faults (custom complex types too) are represented correctly on both systems.
I tried to change schema between complex type with a sequence of elements or a set of attributes; again, all is ok on Tomcat and response is a well formed XML with correct namespaces but empty on WebSphere.
Here are two response examples:
WebSpehere
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:authResponse xmlns:ns2="http://www.my-ws-domain.com/schema/geco-reply-ws/"/>
</soap:Body>
</soap:Envelope>
Tomcat
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:authResponse xmlns:ns2="http://www.my-ws-domain.com/schema/geco-reply-ws/">
<authToken>33WDg36lr+IKUdEMhrfW+L4pg5SzRjtuHtp3kDC5pBE=</authToken>
</ns2:authResponse>
</soap:Body>
</soap:Envelope>
I thought it can be JAXB implementation (XML marshallig on WebSphere).
Any suggestions?

It turns out that WebSphere 8.5 has some problems dealing with hash algoritms in javax.crypto package.
If I respond with a plain text or some Base64 encoding or custom hash function, everything works well.
If in some part of the call stack, I try to hash a string with crypto functions, no error is shown in WAS console, but hash function returns null.

Related

SOAP Request/Response Namespace issue with Websphere Liberty

As part of our application segregation, we are downgrading the application server from WebSphere Application Server(WAS) to WebSphere Liberty. we faced the issue of target namespaces in SOAP Request & Response with WebSphere Liberty. We are able to generate the WSDL with proper format. But, we end up with request & response issues while integrating services through our Enterprise Service Bus(ESB).
Technically we are trying to use the apache-CXF which is inbuilt in WebSphere liberty for SOAP but also we have axis & axis2 jars exist in our application as part of other modules requirement. Axis2 comes with the below family of jars.
axis2-metadata-1.6.2.jar
axis2-saaj-1.6.2.jar
axis2-transport-http-1.6.2.jar
axis2-kernel-1.6.2.jar
axis2-jaxws-1.6.2.jar
If you look at the below two lookups, the first request namespace is proper and that's what we are expecting, and the second is what we are receiving the wrong target namespace. Kindly look at the tag code differences.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://service.api.service.com/2.0">
<soapenv:Header/>
<soapenv:Body>
<ns:findByCode>
<code>?</code>
</ns:findByCode>
</soapenv:Body></soapenv:Envelope>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" "xmlns:ns"=http://service.api.service.com/2.0>
<soapenv:Header/>
<soapenv:Body>
<ns:findByCode>
<code>?</code>
</ns:findByCode>
</soapenv:Body></soapenv:Envelope>
Note: We are getting proper request information while using SOAP-UI. There is some problem with jars or liberty only. We have even raised a request to the Liberty team. I am placing the problem to get the ideas from this community if someone might have already faced a similar issue with Liberty server.
As part of the analysis, we figure out the jar axis2-transport-http-1.6.2.jar is causing the issue by using the internal formatter. Once we remove this jar along with the below jars, we are receiving the request and response in the expected format as mentioned in the question.
axis2-metadata-1.6.2.jar
axis2-saaj-1.6.2.jar
axis2-kernel-1.6.2.jar
Note: We could not find the usage of the above 3 jars so removed.

What library determines how SOAP messages are serialised?

I am working on a JAVA (Spring3) MW project that makes calls to other backend web services. However, some SOAP messages are '''malformed''' (I think) and I cannot trace where the problem lies.
I am not quite sure what details I should include, but here is some that might be handy: It is a JAVA6 project, using Spring3, and is deployed on Tomcat 8 for testing purposes.
Here is a SOAP example that resembles the message my code is generating:
<S:Envelope
xmlns:S="http://schemas.xmlsoap.org/soap/">
<S:Body xmlns="http://backend.company.com/">
<GetCustomerInfo>
<MsgHeader>
<SomeTag>some value</SomeTag>
</MsgHeader>
<Body>
<CustomerId>123456</CustomerId>
</Body>
</GetCustomerInfo>
</S:Body>
</S:Envelope>
When I send this SOAP message to the backend web service, I receive the following error:
Exception: : Element must have a namespace specified if there is a default namespace in scope : Body
When I change my message as follows, everything magically starts working. The only difference is where I define the namespace for my Soap body element.
<S:Envelope
xmlns:S="http://schemas.xmlsoap.org/soap/>
<S:Body>
<GetCustomerInfo xmlns="http://backend.company.com/">
<MsgHeader>
<SomeTag>some value</SomeTag>
</MsgHeader>
<Body>
<CustomerId>123456</CustomerId>
</Body>
</GetCustomerInfo>
</S:Body>
</S:Envelope>
I have 11 questions:
(1) Is there anything wrong with my initial message related to XML-conformance? They both look very similar to me.
(10) What library in my code converts my JAVA object to the XML message? And what changes do I need in my configuration to produce SOAP messages that are like the latter example?
(11) In my fist XML file, what would be the "expanded name" for my first Body tag? would it be http://schemas.xmlsoap.org/soap/:Body or http://backend.company.com/:Body?
In case it is relevant, the service class my code calls is annotated with the following tags:
#WebService(
targetNamespace = "http://backend.company.com/",
name = "MyServiceName"
)
#XmlSeeAlso({ObjectFactory.class})
#SOAPBinding(
parameterStyle = ParameterStyle.BARE
)
OK. finally figured out the answer to my question. The web app passes down the JAVA object to the JDK runtime libraries for unmarshalling. And the JDK uses the JAX-WS RI of the JDK runtime to actually build the SOAP message.
Apparently the problem is caused by a mismatch of the JDK versions between the client and the server.
Initially I had started Tomcat using JDK1.8 and by default JDK 1.8 uses JAX-WS RI 2.2.9 for marshalling/unmarshalling.
The server on the other hand was using JDK1.7, which uses JAX-WS RI 2.2.4 for marshalling/unmarshalling of the SOAP messages.
When i switched to JDK1.7, all my problems were solved.
Note that, this has nothing to do with the JDK that was us used to comppile the source code, but is related to the runtime JDK version that is used to run the code.
BTW, both messages are valid and functionally equivalent XML messages. It is just that earlier versions do not agree.

Transforming CXF SOAP web-service into a custom HTTP / JSON web-service

I have created a SOAP web-service, running in a tomcat container, using CXF and a WSDL contract approach. The Java code was generated from the WSDL using the maven plugin "cxf-codegen-plugin".
Now, I would like to also expose the web-service as a custom HTTP / JSON web-service by mapping the XML data into JSON data. But I haven't been successful yet and I would appreciate any help to achieve that.
I found that old documentation https://cxf.apache.org/docs/json-support.html on CXF's website (which has also been recently duplicated and not corrected here https://cwiki.apache.org/confluence/display/CXF20DOC/JSON+Support). I got it running with a small fix : sf.setBindingId(HTTPBinding.HTTP_BINDING); instead of sf.setBindingId(HttpBindingFactory.HTTP_BINDING_ID); since HttpBindingFactory does not exist anymore in CXF 3.x versions.
The first issue with that solution is that it depends on jettison-json whose last release was published in July 2016. The project looks dead. I could not find any suitable replacement. I only found StAXON which is worst : last release in February 2014.
Is there any other library that is well maintained and that implements StAX ?
The second issue is that the example uses a server bean while I already have a container. For the SOAP service, I simply use the public static Endpoint publish(String address, Object implementor) function.
How can I use both the Tomcat container and the JSON/XML conversion ?
The third issue is that I could not send a valid JSON request so far. The absence of documentation does not help. Still, I managed to get as far as sending a valid JSON equivalent of the SOAP header content. But I could not manage to guess how to make CXF also reads the equivalent of the SOAP body. The Java interface of the web-service is public Response get(Header header, Body body); and I keep getting errors : org.apache.cxf.interceptor.Fault: wrong number of arguments while invoking public abstract Response ServicePort.get(Header,Body) with params [Header#88f6973[user=bbcc2545-27ea-43cd-a1fe-c4a194258e0f]]. Obviously the body is missing.
Is there anyone who knows the right JSON syntax to send a request to a CXF HTTP / JSON web-service that relies on jettison-json ? (Or where could one find a comprehensive documentation ?)

Soap service works locally but on another server is raising ClassCast Exception

Can someone please help me with a strange problem?
I have a service:
#WebMethod
#WebResult(name = "sendCustomerCommunicationResponse", targetNamespace = "......something/Underwriting/Correspondance/V1", partName = "Body")
public SendCustomerCommunicationResponse sendCustomerCommunication(
#WebParam(name = "sendCustomerCommunicationRequest", targetNamespace = "........something/Underwriting/Correspondance/V1", partName = "Body")
SendCustomerCommunicationRequest body)
throws ServiceException_Exception, SystemException_Exception
;
And locally I'm calling it with :
SendCustomerCommunicationResponse response = correspondanceServicePort.sendCustomerCommunication(sendCustomerCommunicationRequest);
And this works well. But when I'm deploying the application on another server, I'm receiving:
"java.lang.ClassCastException:
it.usi.xframe.ub1.batch.services.esb.SendCustomerCommunicationRequest incompatible with
it.usi.xframe.ub1.batch.services.esb.SendCustomerCommunicationResponse"
P.S. The application is running on WebSphere server
The request is :
<soapenv:Envelope ...someSchema...>
<soapenv:Header>
<v1:TechnicalHeader>
<v1:correlationId>12742</v1:correlationId>
<v1:sender>userName</v1:sender>
<v1:countryCode/>
<v1:channelId/>
<v1:userID>userName</v1:userID>
<v1:operationId>CHANGE_STATUS</v1:operationId>
</v1:TechnicalHeader>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken>
<wsse:Username>someUser</wsse:Username>
<wsse:Password>somePassoword</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<v11:sendCustomerCommunicationRequest>
<v11:eventCode>{"header":{"publishingDate":1474016634749,"eventId":"DEL-NEG","applicationCode":"UB3","correlationId":"9999","language":"IT","channelId":"MOB"},"body":{"ndg":"5106215","additionalInfo":{}}}</v11:eventCode>
</v11:sendCustomerCommunicationRequest>
</soapenv:Body>
</soapenv:Envelope>
Maybe it could be a WebSphere JAXB issue, related to the version you're using or your server may miss some fixings. Take a look at what the docs say:
The JAXB Unmarshaller generates stub classes at runtime to assist in
unmarshalling the document. These generated classes are cached and may
be reused by other JAXBContexts in the application.
When a JAXBContext contains a class which has an element wildcard
(i.e. #XmlAnyElement) it was possible that the Unmarshaller would use
incompatible generated stub classes from another JAXBContext which
could result in a ClassCastException being thrown during
unmarshalling. The problem was resolved by improving the collision
checking done on previously generated stub classes so that a new stub
class is generated from the current JAXBContext if the previously
generated stub class found in the cache is not compatible.
That's hard to guess because of IBM's nature regardless the version you're using. Also, refer some other fixings:
During JAX-WS application start up
When servlet caching is enabled
The WSDL location property as part of the
Message Context is stored as a String
A one-way JAX-WS Web Service is defined with a Provider-based
endpoint
Additional code has been added in the local communication path
to detect and reject attempts to send data over a stale
connection
Q:
how is SendCustomerCommunicationResponsedefined? does it include #Xml.. annotations? (eg #XmlRoot ..
just for testing, could you set a name for the #WebResult return variable to something different than the name of the return class (SendCustomerCommunicationResponse)
what are ServiceException_Exception and SystemException_Exception? your own exceptions? It seems those are JAX-RS/JAXB generated exceptions..
It looks like a class version mismatch issue.
One of the scenarios where the developers create Web-Service stubs and build them in their project using a newer version whereas the server classpath has an older version of some dependent jar file. I would recommend the following steps to rule out this option of mismatched dependency versions.
Get the dependency tree and for the files which are failing. You should get a list of dependent jar files. (Check specifically the jar file that is responsible for the creation of the Request and Response objects in your local machine)
Compare the classpath of the WebSphere server and add any missing jars.
replace any dependent jar files in the WebSphere classpath if they belong to an older version.
The second approach can be to do a remote debug, if possible, after enabling the de-compiler in your IDE. Check the class files where the exception occurs and ensure that the editor is linked to the navigator view, to ensure that your navigator shows the file in the jar that being debugged. You should be able to find the exact jar file that is invoked at the time of the exception.
It seems like problem is on server (or with request).
When Server processes a request, it just makes an echo of it back.
Message payload was not changed (for any reason) and no exceptions was thrown.
So when it comes back and unmarshalled it is not instance of SendCustomerCommunicationResponse,but SendCustomerCommunicationRequest
I can suggest first to use SOAPUI (with sample of request) or tcpMon between client and server to see what is exact request and response from server.

AXIS2 Webservice client SOAP envelope error

I have problem with our webservice client. I used to send data to webservice with no problem, but we migrated from Geronimo to Weblogic, and ws client stopped to work. I have investigated data, which are being sent:
<?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Header><ns1:loginData xmlns:ns1="http://xxxxxx.xx/xxx/xx/xxxx/webservice/xxxxxx/auction/types" soapenv:mustUnderstand="0"><ns1:anonymous>false</ns1:anonymous></ns1:loginData></soapenv:Header><soapenv:Body><ns1:offersSend xmlns:ns1="http://xxxxxx.xx/xxx/xx/xxxx/webservice/xxxxxx/auction/types"><ns1:http://xxxxxx.xx/xxx/xx/xxxx/webservice/etrace/auction/types>......
http://xxxxxx.xx/xxx/xx/xxxx/webservice/xxxxxx/auction/types>
Returned error message is:
soapenv:Server.userException</faultcode><faultstring>org.xml.sax.SAXParseException: <Line 1, Column 426>: XML-20201: (Fatal Error) Expected name instead of :.</faultstring><detail><ns1:hostname xmlns:ns1="http://xml.apache.org/axis/">xxxx.xxxxxx.xxx</ns1:hostname></detail>
I'm curious what is wrong, is it some AXIS configuration? What are possibilities to get it working?
EDIT:
I have found that the problem lies in this part:
<ns1:http://xxxxxx.xx/xxx/xx/xxxx/webservice/etrace/auction/types>
Old working XML looked like this:
<ns1:entityData>
But how is it possible, that AXIS is doing call completely different?
This is likely caused by AXIOM-421. The issue occurs with certain Axiom versions in combination with certain StAX implementations. Probably after migrating from Geronimo to Weblogic, the StAX implementation that is used by the application is different.
The solution is either to upgrade to a newer Axiom version or to add Woodstox to your application so that it is used instead of Weblogic's StAX implementation.

Categories