Spring Framework
  1. Spring Framework
  2. SPR-8461

ServletContextResource getFile should not rely on getRealPath (for WebLogic 10 compatibility)

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Complete
    • Affects Version/s: 3.0.5, 3.1 M1, 3.1 M2
    • Fix Version/s: 3.1.2, 3.2 M1
    • Component/s: Web
    • Labels:
      None
    • Last commented by a User:
      false

      Description

      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/" />
      • 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
      • 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.

        Activity

        Hide
        Jonathan added a comment -

        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.

        Show
        Jonathan added a comment - 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.
        Hide
        Juergen Hoeller added a comment -

        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

        Show
        Juergen Hoeller added a comment - 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
        Hide
        Jonathan added a comment -

        Juergen, thanks for the updates

        Show
        Jonathan added a comment - Juergen, thanks for the updates
        Hide
        Piotr Findeisen added a comment -

        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);
        		}
        
        Show
        Piotr Findeisen added a comment - 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); }
        Hide
        Piotr Findeisen added a comment -

        It may be that the improvement of SPR-5040 no longer works – correct me if i'm wrong.

        Show
        Piotr Findeisen added a comment - It may be that the improvement of SPR-5040 no longer works – correct me if i'm wrong.
        Hide
        Michael Wyraz added a comment -

        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.

        Show
        Michael Wyraz added a comment - 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.
        Hide
        Juergen Hoeller added a comment -

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

        Juergen

        Show
        Juergen Hoeller added a comment - Fixed for 3.2 M1 and 3.1.2, falling back to getRealPath for non-existent files. Juergen

          People

          • Assignee:
            Juergen Hoeller
            Reporter:
            Jason Arndt
            Last updater:
            Trevor Marshall
          • Votes:
            4 Vote for this issue
            Watchers:
            6 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:
              Days since last comment:
              1 year, 47 weeks, 2 days ago