You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@cxf.apache.org by "Mike M. (JIRA)" <ji...@apache.org> on 2019/05/22 09:18:01 UTC

[jira] [Comment Edited] (CXF-8041) Error resolving relative XSD Schema on Tomcat

    [ https://issues.apache.org/jira/browse/CXF-8041?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16845695#comment-16845695 ] 

Mike M. edited comment on CXF-8041 at 5/22/19 9:17 AM:
-------------------------------------------------------

[~ffang] thanks for looking into this! :)

I ran my attached test project against the current CXF 3.3.3 SNAPSHOT and found that the exception creeps through another execution path now, but the effect is the same:

The {{org.apache.cxf.resource.DefaultResourceManager}} asks any registered ResourceResolver for the resource. Besides the {{ServletContextResourceResolver}} (that has been patched now), the call also goes through Spring and ends up (again) in the Tomcat Implementation that throws the very same {{IllegalArgumentException}} back up the stack (see attached stack trace below).

As a solution proposal, maybe the initial proposal should be rolled back and instead, the {{DefaultResourceManager#findResource}} method should catch either precisely that {{IllegalArgumentException}} or any potential {{RuntimeException}} thrown by any ResourceResolver while iterating through them around lines 113-122.

This problem can also be reproduced using my attached example project.

{{java.lang.IllegalArgumentException: The resource path [/../../../../com/example/ws/1/XML-Schema_Example.xsd] has been normalized to [null] which is not valid}}
{{ at org.apache.catalina.webresources.StandardRoot.validate(StandardRoot.java:266) ~[tomcat-embed-core-9.0.16.jar!/:9.0.16]}}
{{ at org.apache.catalina.webresources.StandardRoot.getResource(StandardRoot.java:212) ~[tomcat-embed-core-9.0.16.jar!/:9.0.16]}}
{{ at org.apache.catalina.webresources.StandardRoot.getResource(StandardRoot.java:206) ~[tomcat-embed-core-9.0.16.jar!/:9.0.16]}}
{{ at org.apache.catalina.core.ApplicationContext.getResource(ApplicationContext.java:539) ~[tomcat-embed-core-9.0.16.jar!/:9.0.16]}}
{{ at org.apache.catalina.core.ApplicationContextFacade.getResource(ApplicationContextFacade.java:200) ~[tomcat-embed-core-9.0.16.jar!/:9.0.16]}}
{{ at org.springframework.web.context.support.ServletContextResource.exists(ServletContextResource.java:103) ~[spring-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]}}
{{ at org.apache.cxf.bus.spring.BusApplicationContextResourceResolver.resolve(BusApplicationContextResourceResolver.java:87) ~[cxf-core-3.3.3-SNAPSHOT.jar!/:3.3.3.SNAPSHOT]}}
{{ at org.apache.cxf.resource.DefaultResourceManager.findResource(DefaultResourceManager.java:117) ~[cxf-core-3.3.3-SNAPSHOT.jar!/:3.3.3.SNAPSHOT]}}
{{ at org.apache.cxf.resource.DefaultResourceManager.resolveResource(DefaultResourceManager.java:58) ~[cxf-core-3.3.3-SNAPSHOT.jar!/:3.3.3.SNAPSHOT]}}
{{ at org.apache.cxf.ws.addressing.EndpointReferenceUtils$SchemaLSResourceResolver.resolveResource(EndpointReferenceUtils.java:149) ~[cxf-core-3.3.3-SNAPSHOT.jar!/:3.3.3.SNAPSHOT]}}


was (Author: netmikey):
[~ffang] thanks for looking into this! :-)

I ran my attached test project against the current CXF 3.3.3 SNAPSHOT and found that the exception creeps through another execution path now, but the effect is the same:

The {{org.apache.cxf.resource.DefaultResourceManager}} asks any registered ResourceResolver for the resource. Besides the {{ServletContextResourceResolver}} (that has been patched now), the call also goes through Spring and ends up (again) in the Tomcat Implementation that throws the very same {{IllegalArgumentException}} back up the stack (see attached stack trace below).

As a solution proposal, maybe the initial proposal should be rolled back and instead, the {{DefaultResourceManager#findResource}} method should catch either precisely that {{IllegalArgumentException}} or any potential {{RuntimeException}} thrown by any ResourceResolver while iterating through them around lines 113-122.

This problem can also be reproduced using my attached example project.

{{code}}
java.lang.IllegalArgumentException: The resource path [/../../../../com/example/ws/1/XML-Schema_Example.xsd] has been normalized to [null] which is not valid
        at org.apache.catalina.webresources.StandardRoot.validate(StandardRoot.java:266) ~[tomcat-embed-core-9.0.16.jar!/:9.0.16]
        at org.apache.catalina.webresources.StandardRoot.getResource(StandardRoot.java:212) ~[tomcat-embed-core-9.0.16.jar!/:9.0.16]
        at org.apache.catalina.webresources.StandardRoot.getResource(StandardRoot.java:206) ~[tomcat-embed-core-9.0.16.jar!/:9.0.16]
        at org.apache.catalina.core.ApplicationContext.getResource(ApplicationContext.java:539) ~[tomcat-embed-core-9.0.16.jar!/:9.0.16]
        at org.apache.catalina.core.ApplicationContextFacade.getResource(ApplicationContextFacade.java:200) ~[tomcat-embed-core-9.0.16.jar!/:9.0.16]
        at org.springframework.web.context.support.ServletContextResource.exists(ServletContextResource.java:103) ~[spring-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]
        at org.apache.cxf.bus.spring.BusApplicationContextResourceResolver.resolve(BusApplicationContextResourceResolver.java:87) ~[cxf-core-3.3.3-SNAPSHOT.jar!/:3.3.3.SNAPSHOT]
        at org.apache.cxf.resource.DefaultResourceManager.findResource(DefaultResourceManager.java:117) ~[cxf-core-3.3.3-SNAPSHOT.jar!/:3.3.3.SNAPSHOT]
        at org.apache.cxf.resource.DefaultResourceManager.resolveResource(DefaultResourceManager.java:58) ~[cxf-core-3.3.3-SNAPSHOT.jar!/:3.3.3.SNAPSHOT]
        at org.apache.cxf.ws.addressing.EndpointReferenceUtils$SchemaLSResourceResolver.resolveResource(EndpointReferenceUtils.java:149) ~[cxf-core-3.3.3-SNAPSHOT.jar!/:3.3.3.SNAPSHOT]
{{code}}

> Error resolving relative XSD Schema on Tomcat
> ---------------------------------------------
>
>                 Key: CXF-8041
>                 URL: https://issues.apache.org/jira/browse/CXF-8041
>             Project: CXF
>          Issue Type: Bug
>          Components: Core, Transports
>    Affects Versions: 3.3.1
>            Reporter: Mike M.
>            Assignee: Freeman Fang
>            Priority: Major
>             Fix For: 3.3.3, 3.2.10
>
>         Attachments: cxf-tomcat-resource-resolver.zip
>
>
> We found an issue in a CXF JAX-WS project when running in WSDL-first mode with schema-validation enabled on Tomcat. The WSDL references an external XSD schema using a relative path. The WSDL and XSD are bundled with the application and are present on the classpath.
> *Expectation:*
> The XSD should be resolved successfully and schema validation should work.
> *Actual behavior:*
> * The resource lookup runs through CXF {{EndpointReferenceUtils}}' {{SchemaLSResourceResolver}}. This one runs through multiple strategies for resolving the imported XSD URL to a resource. One of them (currently around line 150) is an attempt to ask a {{ResourceManager}} for the URL.
> * In a Servlet context, this will be handled by CXF's {{ServletContextResourceResolver}}. This one (currently starting around line 82) will ask the actual {{ServletContext}} for the URL. While doing so, it will catch and ignore {{MalformedURLException}} s as documented in the {{ServletContext}} interface as well as {{URISyntaxException}} s (probably precautionary).
> * Entering Tomcat's implementation: the call will go through Tomcat's {{ApplicationContext}} and end up in the {{StandardRoot}}'s {{#validate(String)}} method. Unfortunately, while validating the provided URL, this one throws {{IllegalArgumentException}} s instead of just returning {{null}}. In our case, since we resolve the XSD schema relative to the WSDL and need to go up some levels (../../) from it, Tomcat thinks we're trying to escape the application context and will trigger the {{IllegalArgumentException}}.
> * Unfortunately though, this exception never gets caught and propagates up the stack back to CXF's {{SchemaLSResourceResolver#resolveResource}}. This method had several strategies for resolving resources, remember? The annoying part is: we didn't even need that particular ServletContext strategy for our XSD, and one of the other methods (classpath lookup) would have resolved the XSD just fine, *had the ServletContext lookup not thrown the {{IllegalArgumentException}}*. That uncaught exception however, breaks the lookup entirely.
> *Solution proposal:*
> I think the least invasive solution would be for {{ServletContextResourceResolver}} to additionally catch {{IllegalArgumentException}} when calling {{ServletContext#getResource}}. It already catches {{URISyntaxException}} even though that one isn't documented by the {{ServletContext}} API. Catching an exception that basically says "Hey, this argument isn't valid" would be semantically similar imho.
> A more drastic approach would be catching all {{RuntimeException}} s from the Servlet Container in order to fulfill {{ResourceResolver#resolve}}'s contract, namely: "@return an instance of the resource or null if the resource cannot be resolved".
> *Reproducing the error:*
> I attached a sample project to this ticket that reproduces the issue. Make sure to follow the instructions in its README.md.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)