[SWS-374] DefaultURIResolver with witespaces Created: 16/Jun/08  Updated: 19/Nov/09  Resolved: 16/Jun/08

Status: Closed
Project: Spring Web Services
Component/s: XML
Affects Version/s: 1.5.1, 1.5.2
Fix Version/s: 1.5.3

Type: Bug Priority: Major
Reporter: Jakub Milkiewicz Assignee: Arjen Poutsma
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Websphere 6.1.0.13



 Description   

Hi

The following bean definition:

<bean id="schemaCollection" class="org.springframework.xml.xsd.commons.CommonsXsdSchemaCollection" lazy-init="true">
<property name="xsds" value="dl-messages.xsd"/>
<property name="inline" value="true"/>

throws exception in my logs with a stack trace (part of stack trace)

at org.apache.ws.commons.schema.resolver.DefaultURIResolver.resolveEntity(DefaultURIResolver.java:64)
at org.apache.ws.commons.schema.SchemaBuilder.resolveXmlSchema(SchemaBuilder.java:1872)
at org.apache.ws.commons.schema.SchemaBuilder.handleImport(SchemaBuilder.java:1620)
at org.apache.ws.commons.schema.SchemaBuilder.handleXmlSchemaElement(SchemaBuilder.java:175)
at org.apache.ws.commons.schema.SchemaBuilder.build(SchemaBuilder.java:82)
at org.apache.ws.commons.schema.XmlSchemaCollection.read(XmlSchemaCollection.java:359)
at org.apache.ws.commons.schema.XmlSchemaCollection.read(XmlSchemaCollection.java:304)
at org.apache.ws.commons.schema.XmlSchemaCollection.read(XmlSchemaCollection.java:315)
at org.springframework.xml.xsd.commons.CommonsXsdSchemaCollection.afterPropertiesSet(CommonsXsdSchemaCollection.java:109)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1367)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1333)
... 55 more
Caused by: java.net.URISyntaxException: Illegal character in path at index 16: file:/D:/Program Files/IBM/SDP70/runtimes/base_v61/profiles/prof/installedApps/linNode01Cell/ear-dl.ear/web-ws.war/dl-messages.xsd
at java.net.URI$Parser.fail(URI.java:2821)
at java.net.URI$Parser.checkChars(URI.java:2994)
at java.net.URI$Parser.parseHierarchical(URI.java:3078)
at java.net.URI$Parser.parse(URI.java:3026)
at java.net.URI.<init>(URI.java:590)
at org.apache.ws.commons.schema.resolver.DefaultURIResolver.resolveEntity(DefaultURIResolver.java:58)
... 65 more

After a little investigation I found that the main problem is that URI constructor used in DefaultURIResolver.resolveEntity method can not parse expression:
"file:/D:/Program Files/IBM/SDP70/runtimes/base_v61/profiles/prof/installedApps/linNode01Cell/ear-dl.ear/web-ws.war/dl-messages.xsd"

and it is because of white space in 'Program Files' folder.
To make URI constructor happy i would have to provide %20 instead of ' ' So to have it look like: "file:/D:/Program%20Files/IBM/SDP70/..."

I' ve made some tests and for me it seems like a problem with org.springframework.core.io.Resource.getURL() call on websphere that does not conform to URI specification OR problem with org.springframework.SaxUtils class that use getURL() instead of getURI.

1) Problem in Resource.getURL()

Calling getURL() on ClassPathResource or ServletContextResource in Websphere returns value that is proper URL but its string value (toString() value) contains whitespaces

A little example:

String sss = appContext.getResource("/WEB-INF/web.xml").getURL().toString();
System.out.println(sss);

String sss2 = appContext.getResource("/WEB-INF/web.xml").getURI().toString();
System.out.println(sss2);

produces:

file:/D:/Program
Files/IBM/SDP70/runtimes/base_v61/profiles/Wb/installedApps/liseksnNode01Cell/TestClassLoader.ear/TestClassLoaderWeb.war/WEB-INF/web.xml

file:/D:/Program%20Files/IBM/SDP70/runtimes/base_v61/profiles/Wb/installedApps/liseksnNode01Cell/TestClassLoader.ear/TestClassLoaderWeb.war/WEB-INF/web.xml

The analogous output you can get with ClassPathResource.

In comment on http://jira.springframework.org/browse/SPR-3900 by Juergen Hoeller
you can read

"Resource URLs always allow conversion to URIs now"

It doesn't look as it is always true on Websphere...

2) Problem lies in SaxUtils class

Method getSystemId() on org.springframework.xml.sax.SaxUtils returns resource.getURI() instead of getURL().

I took a look at documentation (javadoc) of setSystemId(String systemId) method in org.xml.sax.InputSource class where you can read:

"If the system ID is a URL, it must be fully resolved"

Summary:
i hope that i explained you the source and potential solution for a problem.
I am just not 100 % if the problem lies in Spring webservices or core spring framework.



 Comments   
Comment by Arjen Poutsma [ 16/Jun/08 ]

I could not reproduce this, but I think I fixed it anyway, by changing the toURL() call to toURI() in SaxUtils.

Comment by Jakub Milkiewicz [ 16/Jun/08 ]

Tomorrows i will take a look at the patches, but i do not expect it not to work .
Thanks very much and waiting for version 1.5.3 to come out.

Comment by Arjen Poutsma [ 21/Jul/08 ]

Closing issues in 1.5.3

Comment by Ed Scriven [ 05/Sep/08 ]

This change mean that problems occur when creating a CastorMarshaller to inject onto a WebServiceTemplate, e.g.

<bean id="abc" class="org.springframework.oxm.castor.CastorMarshaller">
<property name="mappingLocation" value="classpath:a/b/c/mapping.xml" />
</bean>

The mappingLocation property value is instantiated as a ClassPathResource. As ClassPathResource does not implement getURI() then a NoSuchMethodException is thrown (from AbstractResource superclass) when SAXUtils.getSystemId() is invoked from the CastorMarshaller.afterPropertiesSet() method.

spring-xml-1.5.2 works as it uses has getURL(), yet spring 1.5.3 does not.

Comment by Ed Scriven [ 05/Sep/08 ]

Sorry, correction for above comment:

The mappingLocation property value is instantiated as a ClassPathResource. As ClassPathResource does not implement getURI() then a NoSuchMethodException is thrown (from AbstractResource superclass) when *SAXUtils.createInputSource()* is invoked from the *CastorMarshaller.createXMLContext()* method.

Comment by Jakub Milkiewicz [ 05/Sep/08 ]

Hi Ed

I hope you are not angry with me

ClassPathResource implements org.springframework.core.io.Resouce interface.
Method getURI() in Resouce was introduced in Spring 2.1 which was then promoted do Spring 2.5.

I am quite sure that the main reason of a problem lies in classLoader.getResource("path") implementation on websphere.
Some time ago I have found a post on IBM forum (will have to search for it again) with explanation about classLoader.getResource("path") returning URL that could contain not escaped whitespaces .
I will have to look at again.

Comment by Arjen Poutsma [ 05/Sep/08 ]

Yes, Resource.getUri() was introduced in Spring 2.5, so upgrading to that might solve your problem.

Comment by Ed Scriven [ 07/Sep/08 ]

Hello Arien,

Thanks for the response - turns out the versioning is the source of my problem. I thought I was already running on Spring 2.5, but one of my Maven dependencies was pulling in Spring 2 and putting it further up the classpath than 2.5

Your fix is fantastic!

Comment by Sebastien Dubois [ 17/Sep/09 ]

Hello,

I'm currently trying to deploy an application based on Spring WS to a Websphere application server and I just found out that my main problem is the one described in this JIRA issue.

I took a look at FishEye and I see that you switched back from getURI to getURL (https://fisheye.springsource.org/browse/spring-ws/trunk/xml/src/main/java/org/springframework/xml/sax/SaxUtils.java?r1=1240&r2=1366#l1). Unfortunately, the problem is thus still relevant event with spring-xml 1.5.8.

Is there a particular reason for the change back from getURI to getURL?

Comment by Sebastien Dubois [ 17/Sep/09 ]

Sorry, after carefully reading the previous comments I realized why it has been changed back to the way it was before.

I guess I'll have to try and see if another workaround can be found on WebSphere's side.

Comment by Jakub Milkiewicz [ 13/Oct/09 ]

Hi

In my project we are still using Spring WS 1.5.5 and currently we do not plan to migrate to newer version (hopefully!).
Sebastien:
Have you found any workaround on Webspherere side ?
Which version of WAS do you use ?

Comment by Arjen Poutsma [ 19/Nov/09 ]

I'm unsure about the status of this issue. Should it be reopened for people running WAS?

Generated at Sun Dec 17 15:47:21 UTC 2017 using JIRA 6.4.14#64029-sha1:ae256fe0fbb912241490ff1cecfb323ea0905ca5.