Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ServletContextResource getFile should not rely on getRealPath (for WebLogic 10 compatibility) [SPR-8461] #13107

Closed
spring-projects-issues opened this issue Jun 16, 2011 · 7 comments
Assignees
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

@spring-projects-issues spring-projects-issues commented Jun 16, 2011

Jason Arndt opened SPR-8461 and commented

When using the ResourceHttpRequestHandler to serve static resources the ServletContextResource's getFile() method that is used doesn't work when not deploying exploded.

Here is the scenario:

  • wire up in spring config
    <mvc:resources mapping="/resources/**" location="/resources/" />

  • access http://localhost:7001/myapp/resources/images/img.gif

  • DispatcherServlet gets the request and delegates to the ResourceHttpRequestHandler.getResource()

  • ResourceHttpRequestHandler uses the ServletContextResource from it's list of locations to check "exists" and "readable"

  • ServletContextResource says yes it exists

  • isReadable() hops to AbstractFileResolvingResource, which determines that is is a "file system resolution" and calls getFile() on ServletContextResource. NOTE: the url that is returned by Weblogic is file:c:/weblogic/tmp/blah/blah/blah/resources/images/img.gif

  • The ServletContextResource.getFile() uses WebUtils.getRealPath(), which is returning /resources/images/img.gif and it tries to then create a File object.

I was able to work around this issue by creating and plugging in a custom ServletContextResource class that overrides the getFile() method and does this:

@Override
public File getFile() throws IOException {
////////////////////////////////////////////////////
//TODO: this fixes a Bug in spring...they are using file path resolution, so use it here too...
// @see AbstractFileResolvingResource.isReadable()
//String realPath = WebUtils.getRealPath(this.servletContext, this.path);
//return new File(realPath);
////////////////////////////////////////////////////////
URL url = getServletContext().getResource(getPath());
String realPath = url.getPath();
return new File(realPath);
}

I have tested this using Weblogic 10.3 deployed exploded, not exploded, and using the eclipse plugin which is basically exploded.


Affects: 3.0.5, 3.1 M1, 3.1 M2

4 votes, 6 watchers

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Nov 21, 2011

Jonathan commented

Jason,

I have a subclass of ServletContextResource that overrides the getFile method as described, but I'm not sure how to register it to be used. Can you provide advice on how to wire it up.

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Nov 28, 2011

Juergen Hoeller commented

We fixed this for tomorrow's 3.1 RC2 and also for the upcoming 3.0.7 release which will go out in late December. The fix is a bit different but will have the same effect: We check for "file:" URLs and simply call super.getFile() in that case since AbstractFileResolvingResource has proper code for that purpose already.

For overriding the default ServletContextResource implementation, you'd have to override your ApplicationContext's getResourceByPath implementation accordingly, returning a custom Resource class instead. Hopefully 3.1 RC2 (or 3.0.7) will be out early enough for your purposes.

Juergen

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Nov 29, 2011

Jonathan commented

Juergen, thanks for the updates

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Jan 19, 2012

Piotr Findeisen commented

We recently upgraded from Spring 3.0.5 to Spring 3.1 and... is there any way to get the legacy behavior in ServletContextResource?

I'm running on JBoss 4.2.3 and have ServletContextResource with path = "/../some.jar". In Spring 3.0.5 i could call ServletContextResource.getFile() to get a file handle to the jar and later open it. In Spring 3.1 calling ServletContextResource.getFile() throws

java.io.FileNotFoundException: ServletContext resource [/../some.jar] cannot be resolved to URL because it does not exist
	at org.springframework.web.context.support.ServletContextResource.getURL(ServletContextResource.java:132)
	at org.springframework.web.context.support.ServletContextResource.getFile(ServletContextResource.java:147)

The getFile() methods never makes to the legacy part:

...
else {
     String realPath = WebUtils.getRealPath(this.servletContext, this.path);
     return new File(realPath);
}

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Jan 19, 2012

Piotr Findeisen commented

It may be that the improvement of #9715 no longer works -- correct me if i'm wrong.

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented May 11, 2012

Michael Wyraz commented

The fix is invalid since it breaks functionality. If the File does not exist, it fails with an exception (in getURL()) instead of returning the path of the non-existent File.

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented May 25, 2012

Juergen Hoeller commented

Fixed for 3.2 M1 and 3.1.2, falling back to getRealPath for non-existent files.

Juergen

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants