SAXParseException: XML document structures must start and end within the same entity - java

I'm calling a web service from an Apache Axis 1.4 Java client. The call reaches the server correctly but the client is throwing this exception after approximately a couple of minutes:
AxisFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
faultSubcode:
faultString: org.xml.sax.SAXParseException: XML document structures must start and end within the same entity.
faultActor:
faultNode:
faultDetail:
The exception is not always the same. Sometimes it specifies a specific element in the response:
AxisFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
faultSubcode:
faultString: org.xml.sax.SAXParseException: The element type "name" must be terminated by the matching end-tag "</name>".
faultActor:
faultNode:
faultDetail:
The web service call I am making returns a large amount of data. If I configure the server to return less data, the call is completed successfully.
Note: Although I'm not getting any client-side time out exceptions, I tried increasing the value for the timeout to five minutes, but this had no effect.

Apache Axis 1.4 supports HTTP 1.0 by default. The server being called is using HTTP 1.1, which apparently supports Chunked Transfer Encoding.
From w3.org:
The chunked encoding modifies the body of a message in order to transfer it as a series of chunks, each with its own size indicator, followed by an OPTIONAL trailer containing entity-header fields. This allows dynamically produced content to be transferred along with the information necessary for the recipient to verify that it has received the full message.
Which means that Axis 1.4 knows nothing about chunks in the HTTP response and probably closes the connection before receiving all the chunks. When it attempts to deserialize the SOAP message, it complains that the XML is not well formed and is missing some closing tag, which is expected because it doesn't have the complete SOAP response.
The solution is to configure Axis to use CommonsHTTPSender which supports HTTP 1.1 by default. You do this by adding a client-config.wsdd on your classpath under org/apache/axis/client/client-config.wsdd with the following content:
<?xml version="1.0" encoding="UTF-8"?>
<deployment name="ApacheCommonsHTTPConfig" xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<globalConfiguration>
<parameter name="disablePrettyXML" value="true"/>
<parameter name="enableNamespacePrefixOptimization" value="false"/>
</globalConfiguration>
<transport name="http" pivot="java:org.apache.axis.transport.http.CommonsHTTPSender" />
<transport name="local" pivot="java:org.apache.axis.transport.local.LocalSender" />
<transport name="java" pivot="java:org.apache.axis.transport.java.JavaSender" />
</deployment>
The relevant setting is the transport with name "http".
Most application servers already have this class loaded in their classpath, in case it isn't you need to add the Apache Commons HTTP jar to your classpath.

Related

Tomcat: custom error page instead of empty response

Some requests are rejected by Tomcat with an empty HTTP 400 response.
A couple of examples:
A request url containing unencoded characters (e.g. '[' or ']' since Tomcat 8.5.x) triggers:
INFO o.a.c.h.Http11Processor Error parsing HTTP request header
Note: further occurrences of HTTP header parsing errors will be logged at DEBUG level.
java.lang.IllegalArgumentException: Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986
A 400 error page is also returned for example when the header size is too large:
INFO: Error parsing HTTP request header
Note: further occurrences of HTTP header parsing errors will be logged at DEBUG level.
java.lang.IllegalArgumentException: Request header is too large
Is it possible to have a custom error page for those errors? More generally for when Tomcat triggers this HTTP 400 response. Delivering an empty response is the worst UX. I am aware that the creation of such requests should be avoided, but I am nonetheless looking for a fallback.
I have set up a custom error page in my (embedded) Tomcat context with ctx.addErrorPage(...) for the error code 400.
It works properly when triggered from my webapp.
E.g. when delegating the error handling to the servlet error handling mechanism with res.sendError(SC_BAD_REQUEST); - res being a HttpServletResponse.
Unfortunately for the kind of tomcat errors described at the top, the custom error page is not used.
Thanks!
This is a nuisance to me as well. Unfortunately, from having a look at the sources, it seems to be wired deep in Tomcat's internals, and can't be changed easily.
In particular, the exceptions you note are thrown in org.apache.coyote.http11.Http11InputBuffer, which is part of one of Tomcat's component called the Coyote HTTP/1.1 Connector (old docs, newer docs don't have this):
The Coyote HTTP/1.1 Connector element represents a Connector component
that supports the HTTP/1.1 protocol. It enables Catalina to function
as a stand-alone web server, in addition to its ability to execute
servlets and JSP pages.
Also, the exceptions end up in catalina.log and are very short - compare this to when you get an exception from the JSP processor, which are several times that size.
So I think it isn't trivial to patch this - at least not without knowledge about Tomcat internals, which I don't have :(

Tomcat: Attachment errors while using https

I've configured tomcat (8.5.16) to use https (using org.apache.coyote.http11.Http11NioProtocol), the application (based on spring framework) works fine (like before, with http) but frequently I have an error when the user upload an attachment. It happens randomly, sometime I have this error:
Caused by: org.apache.tomcat.util.http.fileupload.FileUploadBase$IOFileUploadException: Processing of multipart/form-data request failed. Channel is in closing state
and sometimes this:
Caused by: org.apache.tomcat.util.http.fileupload.FileUploadBase$IOFileUploadException: Processing of multipart/form-data request failed. Stream ended unexpectedly at org.apache.tomcat.util.http.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:297)
Before, using http there were no errors...
Any idea?
Cheers
Matteo
It was a problem with http/2, not https.
Removing this
<UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
from connector, it works as well as before.
Matteo

Time Out in SOA

I have an app deployed in weblogic server. In that app, I am calling an async webservice through a bpel in a composite. It is getting timed out after 5 minutes.
I tried adding the following code during the invoke activity:
bpelx:for="'PTM20'"
But still timeout is 5 minutes.
Is there anything I need to do other than adding this? Is there any global SOA properties to modify?
I am invoking an aync webservice through a bpel like this:
< invoke name="myprocess" inputVariable="varx" operation="method" bpelx:for="'PTM20'" ....>
The exception I am getting is following:
<bpelFault><faultType>0</faultType>
<remoteFault xmlns="http://schemas.oracle.com/bpel/extension">
<part name="summary">
<summary>oracle.fabric.common.FabricInvocationException: Unable to invoke endpoint URI "my_webservice_url" successfully due to: javax.xml.soap.SOAPException: javax.xml.soap.SOAPException: Message send failed: Read timed out</summary></part>
<part name="detail"><detail>Unable to invoke endpoint URI "my_webservice_url" successfully due to: javax.xml.soap.SOAPException: javax.xml.soap.SOAPException: Message send failed: Read timed out</detail></part>
<part name="code"><code>null</code></part>
</remoteFault></bpelFault>
While going through Audit Trail, I can see the time difference between invocation and time out happened is 5 minutes. It did not wait for 20 minutes as expected.
Please help.
Thanks.
There are couple places to consider when configuring SOA/BPEL engine timeouts:
Domain wide global JTA timeout settings
individual BPEL engine EJB timeouts
Ideally you never want to hit those timeouts because you won't be able to do proper error handling. To avoid that you should set individual timeouts on outgoing references links and make sure they have smaller values than two mentioned above.
There are many blog posts available on this subject, for starters take a look at this post

Java Web Service error: com.ctc.wstx.exc.WstxEOFException: Unexpected EOF in prolog

I have a problem creating and connecting a Java client to a running Web Service.
I use the following code:
Service myService = null;
URL wsdlLocation = new URL("http://myservice?wsdl");
QName serviceName = new QName(wsdlLocation, "MyService");
Service myService = new Service(wsdlLocation, serviceName);
where the Service class was created with the following command:
wsimport -d gen -keep http://myservice?wsdl
I've also tried with a client generated by Apache cxf 2.4's wsdl2java, but got the same result.
(I've changed the WSDL location and Service class name only for this post, in the code I use the original ones.)
But I get an exception when I call the Web Service deployed on the appserver, when creating the service with the new Service() command.
But: I've tested the wsdl location with SOAP UI and it works perfectly.
Also, I've created a Mock Service using Soap UI and my Java client could connect to it, call it and get the results back.
The problem appears when I want' to call the web service running on the appserver.
Stacktrace:
javax.xml.ws.WebServiceException: org.apache.cxf.service.factory.ServiceConstructionException: Failed to create service.
at org.apache.cxf.jaxws.ServiceImpl.<init>(ServiceImpl.java:149)
at org.apache.cxf.jaxws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:98)
at javax.xml.ws.Service.<init>(Service.java:76)
at MyService.<init>(MyService.java:42)
at mypackage.createService(AClass.java:288)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
Caused by: org.apache.cxf.service.factory.ServiceConstructionException: Failed to create service.
at org.apache.cxf.wsdl11.WSDLServiceFactory.<init>(WSDLServiceFactory.java:100)
at org.apache.cxf.jaxws.ServiceImpl.initializePorts(ServiceImpl.java:199)
at org.apache.cxf.jaxws.ServiceImpl.<init>(ServiceImpl.java:147)
... 12 more
Caused by: javax.wsdl.WSDLException: WSDLException: faultCode=PARSER_ERROR: com.ctc.wstx.exc.WstxEOFException: Unexpected EOF in prolog
at [row,col,system-id]: [1,0,"http://myservice?wsdl"]
at org.apache.cxf.wsdl11.WSDLManagerImpl.loadDefinition(WSDLManagerImpl.java:256)
at org.apache.cxf.wsdl11.WSDLManagerImpl.getDefinition(WSDLManagerImpl.java:205)
at org.apache.cxf.wsdl11.WSDLServiceFactory.<init>(WSDLServiceFactory.java:98)
... 14 more
Caused by: com.ctc.wstx.exc.WstxEOFException: Unexpected EOF in prolog
at [row,col,system-id]: [1,0,"http://myservice?wsdl"]
at com.ctc.wstx.sr.StreamScanner.throwUnexpectedEOF(StreamScanner.java:677)
at com.ctc.wstx.sr.BasicStreamReader.handleEOF(BasicStreamReader.java:2139)
at com.ctc.wstx.sr.BasicStreamReader.nextFromProlog(BasicStreamReader.java:2045)
at com.ctc.wstx.sr.BasicStreamReader.next(BasicStreamReader.java:1134)
at org.apache.cxf.staxutils.StaxUtils.readDocElements(StaxUtils.java:1248)
at org.apache.cxf.staxutils.StaxUtils.readDocElements(StaxUtils.java:1142)
at org.apache.cxf.staxutils.StaxUtils.read(StaxUtils.java:1069)
at org.apache.cxf.wsdl11.WSDLManagerImpl.loadDefinition(WSDLManagerImpl.java:247)
... 16 more
Could someone please help me?
I encountered this error and found that it appeared to be due to using a URL that returned an HTTP 302 redirect instead of the WSDL directly.
The URL I was using was in the format /Service?wsdl, which redirected to a URL in the format /Service/wsdl/Service.wsdl. Once I used the redirect target URL directly, everything worked.
I remember reading that it could be related to the endpoint expecting a trailing '/'. I'm not sure if this valid, but please try it and post here it if works.
I had a similar error and when I checked the server logs - it was related to http server having encountered an unsupported http method in request. Due to this teh server returns an HTTP response that the SOAP client cannot handle ... hence Unexpected EOF in prolog
Below is a snippet my web-server log for tomcat "localhost.XXXX.log"
org.apache.tomcat.util.descriptor.web.SecurityConstraint.findUncoveredHttpMethods For security constraints with URL pattern [/services/*] only the HTTP methods [POST GET] are covered. All other methods are uncovered.
This gave following error on client side
com.ctc.wstx.exc.WstxEOFException: Unexpected EOF in prolog
In my case since I was downgrading a secured service to unsecured and my web.xml had following stray entry that was restricting GET and post with a security constraint and I wasnt sending needed security parameters in the request..
<security-constraint>
<web-resource-collection>
<web-resource-name>restricted web services</web-resource-name>
<url-pattern>/services/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
I removed this constraint to get rid of this error :-)
In your case it may not related to security constraint - but for sure its related to server sending raw http response - Please check your server/ client configuration and ensure it sends appropriate http request that are liked by http server
I had a similar error and when I checked the server logs - it was related to http server having encountered an unsupported http method in request returns an HTTP response that the SOAP client cannot handle ... check your web-server logs
Surely this isn't due to character or format issue.
It's possible that the server didn't return any data, of which the Woodstox (wstx) was trying to parse into XML and failed, which resulted to this error.
I had similiar issue and i have resolved with debugging.
When i try to download WSDL in runtime i found that i could not get the WSDL because of the proxy.
Please check that you can access the WSDL in runtime like this code:
try {
String wsdl = org.apache.commons.io.IOUtils.toString(new URL("http://YOUR_WSDL_URL"));
System.out.println("WSDL => "+wsdl);
} catch (IOException e) {
e.printStackTrace();
}
One of the imports are missing. Please check routes to your xsd's.
I had the same problem. I had to use the full path to the WSDL file to make it works.
My contribution to this error is this:
I don't get this error when I am in debugging mode.
It seems that when the executor of the Java program that queries the WSDL Service (Java in my case) has the time to perform many requests, like in debugging mode, because of when sometimes the programs stops because I put some breakpoints, in this case I don't get this error.
When I run the program in production mode, yes.
But the requests are the same, the WSDL doesn't change, as well ad the endpoints.
It's like a limitation of the web Server, I think.

Axis: faultString: org.xml.sax.SAXParseException: Premature end of file

I have deployed a webservice using servletexec configured with IIS and i can successfully access webservice using anonymous account. But when I enable Windows Integrated Authentication I am getting following error.
- ntlm authentication scheme selected
- Discarding unexpected response: HTTP/1.1 100 Continue
AxisFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
faultSubcode:
faultString: org.xml.sax.SAXParseException: Premature end of file.
faultActor:
faultNode:
faultDetail:
{http://xml.apache.org/axis/}hostname:akvm
org.xml.sax.SAXParseException: Premature end of file.
at org.apache.axis.message.SOAPFaultBuilder.createFault(SOAPFaultBuilder.java:222)
at org.apache.axis.message.SOAPFaultBuilder.endElement(SOAPFaultBuilder.java:129)
at org.apache.axis.encoding.DeserializationContext.endElement(DeserializationContext.java:1087)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(AbstractSAXParser.java:633)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanEndElement(XMLNSDocumentScannerImpl.java:719)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(XMLDocumentFragmentScannerImpl.java:1685)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:368)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:834)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:764)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:148)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1242)
at javax.xml.parsers.SAXParser.parse(SAXParser.java:375)
at org.apache.axis.encoding.DeserializationContext.parse(DeserializationContext.java:227)
at org.apache.axis.SOAPPart.getAsSOAPEnvelope(SOAPPart.java:696)
at org.apache.axis.Message.getSOAPEnvelope(Message.java:435)
at org.apache.axis.handlers.soap.MustUnderstandChecker.invoke(MustUnderstandChecker.java:62)
at org.apache.axis.client.AxisClient.invoke(AxisClient.java:206)
at org.apache.axis.client.Call.invokeEngine(Call.java:2784)
at org.apache.axis.client.Call.invoke(Call.java:2767)
at org.apache.axis.client.Call.invoke(Call.java:2443)
at org.apache.axis.client.Call.invoke(Call.java:2366)
It looks like that the Axis client does not like the NTLM authentication challenge. See error message at the top:
Discarding unexpected response: HTTP/1.1 100 Continue
After which there is no XML for Axis to parse, which is why you're getting premature end of file.
In order to use NTLM with Axis (1.4), you'll have to use the CommonsHTTPSender instead of the standard transport:
<transport name="http" pivot="java:org.apache.axis.transport.http.CommonsHTTPSender">
</transport>
in your client-config.wsdd and then set up the NTLM username and password through the Stub object.
The "premature end of file" type errors from the xerces SAX implementation usually indicates that the SAX parser expected data, but got none (not null, but an initialized empty InputSource). From the stack trace, it looks as if the axis SOAP handler expects a SOAP xml message to arrive, but the message is empty. My knowledge of ISS and its infrastructure is close to nil, can you get any log messages from the server?

Categories