spring-projects / spring-projects/spring-ws
JAXB doesnt create the XsdSchemaCollection bean using DefaultWsdl11Definition correctly [SWS-1041]
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 346
- Forks
- 323
- Avg merge
- 3d 2h
- Merged PRs (30d)
- 7
Description
Nikolas Charalambidis opened SWS-1041 and commented
Hi,
I have two schemas in src/main/resources with the same namespace www.mycompany.com. schemaA.xsd and schemaB.xsd have the same header:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://www.mycompany.com"
targetNamespace="http://www.mycompany.com"
elementFormDefault="qualified">
My WebServiceConfiguration`` extending ``WsConfigurerAdapter`` defines aside the ``ServletRegistrationBean`` also the following ``XsdSchema(Collection)`` beans:
// Just a bean with one schema
@Bean
public XsdSchema schema() {
return new SimpleXsdSchema(new ClassPathResource("xsd/schemaA.xsd"));
}
// A bean with both schemas
@Bean
public XsdSchemaCollection schemaCollection() {
return new XsdSchemaCollection() {
@Override
public XsdSchema[] getXsdSchemas() {
return new XsdSchema[] {
new SimpleXsdSchema(new ClassPathResource("xsd/schemaA.xsd")),
new SimpleXsdSchema(new ClassPathResource("xsd/schemaB.xsd"))
};
}
@Override
public XmlValidator createValidator() {
throw new UnsupportedOperationException();
}
};
}
And the WSDL bean:
@Bean(name = "soapWsdl")
public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema schema, XsdSchemaCollection schemaCollection) {
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName("SoapPort");
wsdl11Definition.setLocationUri("/service/soap");
wsdl11Definition.setTargetNamespace("https://www.mycompany.com");
// At this point I use just one of the folliwing:
wsdl11Definition.setSchema(schema);
wsdl11Definition.setSchemaCollection(schemaCollection);
return wsdl11Definitionl;
}
Using one of these in the bean above:
wsdl11Definition.setSchema(schema);
If I use only XsdSchema defining one schema (regardless whether schemaA or schemaB), everything works, the SOAP Web service is running and WSDL is generated
wsdl11Definition.setSchemaCollection(schemaCollection);
Now the NPE is thrown although the InliningXsdSchemaTypesProvider sets the one schema as the collection with one schema. The error thrown is:
2018-10-05 21:29:28.636 WARN 164968 — [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'soapWsdl' defined in class path resource [cz/vse/soap/WebServiceConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition]: Factory method 'defaultWsdl11Definition' threw exception; nested exception is java.lang.NullPointerException
...
Caused by: java.lang.NullPointerException: null at org.springframework.xml.xsd.SimpleXsdSchema.getTargetNamespace(SimpleXsdSchema.java:94) ~[spring-xml-3.0.3.RELEASE.jar!/:na] at com.mycompany.WebServiceConfig.defaultWsdl11Definition(WebServiceConfig.java:66) ~[classes!/:0.0.1]
I make the things work with calling the SimpleXsdSchema::afterPropertiesSet which is not somehow called upon the bean instantiation. Hard to say what happens. However, editing the method like this makes the schemas work together:
@Override
public XsdSchema[] getXsdSchemas() {
SimpleXsdSchema[] schemaArray = new SimpleXsdSchema[] {
new SimpleXsdSchema(new ClassPathResource("xsd/schemaA.xsd")),
new SimpleXsdSchema(new ClassPathResource("xsd/schemaB.xsd"))
};
for (SimpleXsdSchema schema : schemaArray) {
try {
schema.afterPropertiesSet();
} catch (ParserConfigurationException | IOException | SAXException e) {
/* ...*/
}
}
return schemaArray;
}
Why passing the XsdSchema and XsdSchemaCollection doesn't behave equally even they are supposed to do according to DefaultWsdl11Definition? I expect it should work even without calling the schema.afterPropertiesSet().
Affects: 2.0.5
Reference URL: https://stackoverflow.com/questions/52672270/jaxb-difference-between-xsdschema-and-xsdschemacollection-while-creating-the-def
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the provided WebServiceConfig bean method and compare DefaultWsdl11Definition.setSchema with setSchemaCollection. Read InliningXsdSchemaTypesProvider and SimpleXsdSchema, especially SimpleXsdSchema.getTargetNamespace and afterPropertiesSet. Reproduce the two-schema configuration and verify that WSDL creation no longer throws a NullPointerException without manual initialization.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, spring
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100