Bug in JAX-WS 2.0 RI? Limit on string size when using Provider PAYLOAD
Hi,
When I send a simple string argument using a jax-ws (2.0 RI) web service and client, I get an error when the string size is bigger than a certain size. It only happens with the Provider (PAYLOAD) service interface,
it does not happen with a Provider (MESSAGE). The following client code
package test;
import org.test.TestPortType;
import org.test.TestService;
public class Client {
public static void main(String[] args) {
new Client().run();
}
public void run() {
TestPortType test = (new TestService()).getTestBinding();
String arg = "";
for(int i=0;i<12153;++i) {
arg += "a";
}
System.out.println(test.test(arg));
}
}
gives the following exception on the Tomcat 6.0 server:
javax.xml.ws.WebServiceException: com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: XML declaration parsing failed
at com.sun.xml.ws.handler.LogicalMessageImpl.getPayload(LogicalMessageImpl.java:146)
at com.sun.xml.ws.protocol.soap.server.ProviderSOAPMD.toMessageInfo(ProviderSOAPMD.java:66)
at com.sun.xml.ws.protocol.soap.server.SOAPMessageDispatcher$SoapInvoker.invoke(SOAPMessageDispatcher.java:571)
at com.sun.xml.ws.protocol.soap.server.SOAPMessageDispatcher.receive(SOAPMessageDispatcher.java:141)
at com.sun.xml.ws.server.Tie.handle(Tie.java:88)
at com.sun.xml.ws.transport.http.servlet.WSServletDelegate.handle(WSServletDelegate.java:333)
at com.sun.xml.ws.transport.http.servlet.WSServletDelegate.doPost(WSServletDelegate.java:288)
at com.sun.xml.ws.transport.http.servlet.WSServlet.doPost(WSServlet.java:77)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:263)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:584)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Unknown Source)
Caused by: com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: XML declaration parsing failed
at com.sun.xml.internal.messaging.saaj.soap.SOAPPartImpl.lookForXmlDecl(Unknown Source)
at com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPPart1_1Impl.createEnvelopeFromSource(Unknown Source)
at com.sun.xml.internal.messaging.saaj.soap.SOAPPartImpl.getEnvelope(Unknown Source)
at com.sun.xml.internal.messaging.saaj.soap.MessageImpl.getSOAPBody(Unknown Source)
at com.sun.xml.ws.handler.LogicalMessageImpl.getPayload(LogicalMessageImpl.java:82)
... 21 more
Caused by: java.io.IOException: Pushback buffer overflow
at java.io.PushbackReader.unread(Unknown Source)
at com.sun.xml.internal.messaging.saaj.util.XMLDeclarationParser.parse(Unknown Source)
... 26 more
when using the following Provider:
package test;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.ws.BindingType;
import javax.xml.ws.Provider;
import javax.xml.ws.ServiceMode;
import javax.xml.ws.WebServiceProvider;
import org.test.TestResponse;
@WebServiceProvider(
portName="TestPort",
serviceName="TestService",
targetNamespace="http://test.org",
wsdlLocation="WEB-INF/wsdl/test.wsdl"
)
@BindingType(value="http://schemas.xmlsoap.org/wsdl/soap/http")
@ServiceMode(value=javax.xml.ws.Service.Mode.PAYLOAD)
public class TestProvider implements Provider<Source> {
@Override
public Source invoke(Source arg0) {
try {
JAXBContext jaxbContext = JAXBContext.newInstance("org.test");
Marshaller marshaller = jaxbContext.createMarshaller();
TestResponse response = new TestResponse();
response.setOut("OK");
DOMResult domResult = new DOMResult();
marshaller.marshal(response, domResult);
return new DOMSource(domResult.getNode());
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
}
If I decrease the string size with just one, it all works fine. I am using the following wsdl, sun-jaxws.xml, and ant build script (I copy all jax-ws RI 2.0 libraries to the WEB-INF/lib directory.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://test.org" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="test" targetNamespace="http://test.org">
<wsdl:types>
<xsd:schema targetNamespace="http://test.org">
<xsd:element name="test">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="in" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="testResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="out" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</wsdl:types>
<wsdl:message name="testRequest">
<wsdl:part element="tns:test" name="parameters"/>
</wsdl:message>
<wsdl:message name="testResponse">
<wsdl:part element="tns:testResponse" name="parameters"/>
</wsdl:message>
<wsdl:portType name="testPortType">
<wsdl:operation name="test">
<wsdl:input message="tns:testRequest"/>
<wsdl:output message="tns:testResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="testBinding" type="tns:testPortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="test">
<soap:operation soapAction="http://test.org/test" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="testService">
<wsdl:port binding="tns:testBinding" name="testBinding">
<soap:address location="http://localhost:8080/test/test"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
<?xml version="1.0" encoding="UTF-8"?>
<endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime" version="2.0">
<endpoint name="testService"
implementation="test.TestProvider"
url-pattern="/test"/>
</endpoints>
<?xml version="1.0" encoding="UTF-8"?>
<project name="test" basedir="." default="build">
<property name="src.dir" value="${basedir}/src"/>
<property name="test.dir" value="${basedir}/test"/>
<property name="gsrc.dir" value="${basedir}/gsrc"/>
<property name="bin.dir" value="${basedir}/bin"/>
<property name="jar.dir" value="${bin.dir}/jar"/>
<property name="war.dir" value="${bin.dir}/war"/>
<property name="wsdl.dir" value="${basedir}/wsdl"/>
<property name="wsdl.file" value="test.wsdl"/>
<property name="webinf.dir" value="${basedir}/web/WEB-INF"/>
<property name="tomcat.drop.location" value="c:\Servers\Tomcat 6.0\webapps"/>
<path id="proj.lib">
<fileset dir="${basedir}/lib">
<include name="**/*.jar"/>
</fileset>
<pathelement location="${basedir}/bin"/>
</path>
<target name="clean">
<delete dir="${bin.dir}"/>
<delete dir="${gsrc.dir}"/>
<delete dir="${webinf.dir}/lib"/>
<delete dir="${webinf.dir}/wsdl"/>
<mkdir dir="${bin.dir}"/>
<mkdir dir="${jar.dir}"/>
<mkdir dir="${war.dir}"/>
<mkdir dir="${gsrc.dir}"/>
<mkdir dir="${webinf.dir}/lib"/>
<mkdir dir="${webinf.dir}/wsdl"/>
</target>
<target name="wsimport">
<exec executable="wsimport">
<arg value="-d"/>
<arg value="${bin.dir}"/>
<arg value="-s"/>
<arg value="${gsrc.dir}"/>
<arg value="-verbose"/>
<arg value="${wsdl.dir}/${wsdl.file}"/>
</exec>
</target>
<target name="compile" depends="wsimport">
<javac destdir="${bin.dir}" debug="true" debuglevel="lines,vars,source">
<src path="${src.dir}"/>
<classpath refid="proj.lib"/>
</javac>
</target>
<target name="jar" depends="compile">
<jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${bin.dir}"/>
</target>
<target name="war" depends="jar">
<copy file="${jar.dir}/${ant.project.name}.jar" todir="${webinf.dir}/lib"/>
<copy todir="${webinf.dir}/lib" flatten="true">
<fileset dir="${basedir}/lib">
<include name="**/*.jar"/>
<exclude name="**/servlet-api.jar"/>
<exclude name="**/junit-4.4.jar"/>
</fileset>
</copy>
<copy todir="${webinf.dir}/wsdl">
<fileset dir="${wsdl.dir}"/>
</copy>
<jar destfile="${war.dir}/${ant.project.name}.war" basedir="${basedir}/web"/>
</target>
<target name="deploy" depends="war">
<copy file="${war.dir}/${ant.project.name}.war" todir="${tomcat.drop.location}" overwrite="true"/>
<delete dir="${tomcat.drop.location}/${ant.project.name}"/>
</target>
<target name="build" depends="clean,deploy"/>
</project>