I’ve deployed a contract-first web service using CXF.
The server into which it is deployed performs 302 redirections from http to ssl, so any request to http://server/app/* returns an HTTP 302 error code and redirects to https://server/app/*.
In the original WSDL there are references to XSD elements in another namespace, so the generated WSDL (the one http://server/app/services/MyService?wsdl provides) contains a <wsdl:import> element.
If I try to invoke the WS by manually building a SOAP request in a String and send it over an SSL socket, the WS responds correctly. I’ve got all necessary certificates in my keystore.
However, when I try to build a client using CXF’s wsdl2java pointing to https://server/app/services/MyService?wsdl, I get the following error (complete stack trace below):
[Fatal Error] MyService?wsdl=MyServicePortType.wsdl:1:50:
White spaces are required between publicId and systemId.
The trace is referring to the <wsdl:import> statement. Its location attribute is http://server:80/app/services/MyService?wsdl=MyServicePortType.wsdl. My guess is that the error is thrown because of the 302 redirection. It should be https://server/app/services/MyService?wsdl=MyServicePortType.wsdl instead.
The original WSDL is URL-agnostic, and the service’s URL is defined relative in a Spring <jaxws:endpoint> element. It is accessed through the CXF servlet. That is, there’s no <soap:address> element in the original WSDL’s <wsdl:port>.
<import resource="classpath:META-INF/cxf/cxf.xml"/>
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
<bean id="myServiceBean" class="mypackage.MyServiceImpl" />
<jaxws:endpoint
id="myServiceEndpoint"
implementor="#myServiceBean"
address="/MyService">
</jaxws:endpoint>
Should I specify somewhere in the service’s autogenerated classes, WSDL or Spring configuration that the service is to be deployed on SSL? And how could I do it?
EDIT:
Possibly related link:
- jax-ws doesn’t like http redirect? discussion on markmail.
Complete stacktrace:
D:\>wsdl2java -d src -client -impl -verbose -db xmlbeans -autoNameResolution -validate -compile -classdir classes https://server/app/services/MyService?wsdl
Loading FrontEnd jaxws ...
Loading DataBinding xmlbeans ...
wsdl2java -d src -client -impl -verbose -db xmlbeans -autoNameResolution -valida
te -compile -classdir classes https://server/app/services/MyService?wsdl
wsdl2java - Apache CXF 2.3.2
[Fatal Error] MyService?wsdl=MyServicePortType.wsdl:1:50: White spaces are required between publicId and systemId.
WSDLToJava Error: org.apache.cxf.wsdl11.WSDLRuntimeException: Fail to create wsdl definition from : https://server/app/services/MyService?wsdl
Caused by : WSDLException (at /wsdl:definitions/wsdl:import): faultCode=PARSER_ERROR: Problem parsing 'http://server:80/app/services/MyService?wsdl=MyServicePortType.wsdl'.: org.xml.sax.SAXParseException: White spaces are required between publicId and systemId.
org.apache.cxf.tools.common.ToolException: org.apache.cxf.wsdl11.WSDLRuntimeException: Fail to create wsdl definition from : https://server/app/services/MyService?wsdl
Caused by : WSDLException (at /wsdl:definitions/wsdl:import): faultCode=PARSER_ERROR: Problem parsing 'http://server:80/app/services/MyService?wsdl=MyServicePortType.wsdl'.: org.xml.sax.SAXParseException: White spaces are required between publicId and systemId.
at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.execute(WSDLToJavaContainer.java:288)
at org.apache.cxf.tools.common.toolspec.ToolRunner.runTool(ToolRunner.java:103)
at org.apache.cxf.tools.wsdlto.WSDLToJava.run(WSDLToJava.java:113)
at org.apache.cxf.tools.wsdlto.WSDLToJava.run(WSDLToJava.java:86)
at org.apache.cxf.tools.wsdlto.WSDLToJava.main(WSDLToJava.java:184)
Caused by: org.apache.cxf.wsdl11.WSDLRuntimeException: Fail to create wsdl definition from : https://server/app/services/MyService?wsdl
Caused by : WSDLException (at /wsdl:definitions/wsdl:import): faultCode=PARSER_ERROR: Problem parsing 'http://server:80/app/services/MyService?wsdl=MyServicePortType.wsdl'.: org.xml.sax.SAXParseException: White spaces are required between publicId and systemId.
at org.apache.cxf.wsdl11.WSDLDefinitionBuilder.parseWSDL(WSDLDefinitionBuilder.java:97)
at org.apache.cxf.wsdl11.WSDLDefinitionBuilder.build(WSDLDefinitionBuilder.java:69)
at org.apache.cxf.tools.wsdlto.frontend.jaxws.wsdl11.JAXWSDefinitionBuilder.build(JAXWSDefinitionBuilder.java:84)
at org.apache.cxf.tools.wsdlto.frontend.jaxws.wsdl11.JAXWSDefinitionBuilder.build(JAXWSDefinitionBuilder.java:61)
at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.processWsdl(WSDLToJavaContainer.java:170)
at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.execute(WSDLToJavaContainer.java:137)
at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.execute(WSDLToJavaContainer.java:280)
... 4 more
Caused by: javax.wsdl.WSDLException: WSDLException (at /wsdl:definitions/wsdl:import): faultCode=PARSER_ERROR: Problem parsing 'http://server:80/app/services/MyService?wsdl=MyServicePortType.wsdl'.: org.xml.sax.SAXParseException: White spaces are required between publicId and systemId.
at com.ibm.wsdl.xml.WSDLReaderImpl.getDocument(Unknown Source)
at com.ibm.wsdl.xml.WSDLReaderImpl.parseImport(Unknown Source)
at com.ibm.wsdl.xml.WSDLReaderImpl.parseDefinitions(Unknown Source)
at com.ibm.wsdl.xml.WSDLReaderImpl.readWSDL(Unknown Source)
at com.ibm.wsdl.xml.WSDLReaderImpl.readWSDL(Unknown Source)
at org.apache.cxf.wsdl11.WSDLManagerImpl.loadDefinition(WSDLManagerImpl.java:237)
at org.apache.cxf.wsdl11.WSDLManagerImpl.getDefinition(WSDLManagerImpl.java:186)
at org.apache.cxf.wsdl11.WSDLDefinitionBuilder.parseWSDL(WSDLDefinitionBuilder.java:78)
... 10 more
Caused by: org.xml.sax.SAXParseExceptionpublicId: http://server:80/app/services/MyService?wsdl=MyServicePortType.wsdl; systemId: http://server:80/app/services/MyService?wsdl=MyServicePortType.wsdl; lineNumber: 1; columnNumber: 50; White spaces are required between publicId and systemId.
at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source)
... 18 more
It turns out the service implementation
mypackage.MyServiceImplwas missing thejavax.jws.WebServiceannotation.Once included with the proper
serviceName,portName,targetNamespace, andendpointInterfaceattributes, the service deployed without<wsdl:import>. I suspect this has to do mainly with thetargetNamespaceattribute.However, external XSD’s still get referenced with http addresses, like
<xsd:import schemaLocation="http://server:80/app/schema/myschema.xsd">. I referenced them relative in the original WSDL. The only solution to this for me has been inlining all XSD definitions in the original WSDL.