spring-projects / spring-projects/spring-ws

JAXB doesnt create the XsdSchemaCollection bean using DefaultWsdl11Definition correctly [SWS-1041]

Open
#1,108 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

status: waiting-for-triage
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.comschemaA.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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.