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

HTTP 404 for static resources with last modified = 0L (breaks Docker images build with Jib) [SPR-17320] #21853

Closed
spring-projects-issues opened this issue Oct 1, 2018 · 2 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) in: web Issues in web modules (web, webmvc, webflux, websocket) status: backported An issue that has been backported to maintenance branches type: bug A general bug
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Oct 1, 2018

Martin Bonato opened SPR-17320 and commented

The ResourceHTTPRequestHandler returns HTTP 404 Not Found for static resources that have a file modification date of 0L (i.e. the unix epoch 00:00:00 GMT, January 1, 1970). This breaks resolving static resources in web applications build as Docker images with Jib.

One of the goals of Docker images build with Jib are "reproducible builds". That is, Docker images build from the same sources should result in the same docker image with the same SHAs for the Docker image and it's layers. To achieve this, Jib sets the modification date of every file it includes to 0 (see ReproducibleLayerBuilder). When the ResourceHTTPRequestHandler resolves a static resource from the classpath or the filesystem it checks the resource's lastModified date (ResourceHttpRequestHandler line 467|[https://github.com/spring-projects/spring-framework/blob/7aa933437c874122fef10a3cb8282359312e8d6e/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java#L467]. The AbstractResource however, throws a FileNotFoundException when the file last-modified date is 0:

 

    public long lastModified() throws IOException {
        long lastModified = getFileForLastModifiedCheck().lastModified();
        if (lastModified == 0L) {
            throw new FileNotFoundException(getDescription() +
                    " cannot be resolved in the file system for resolving its last-modified timestamp");
        }
        return lastModified;
    }

In consequence, static resources in the classpath or filesystem in Docker images build with Jib are not resolvable by Spring WebMVCs standard ResourceHttpRequestHandler.

This renders Spring WebApplications build with Jib unusable in most cases.

Resources having a last modified date of 0L should not be treated special by Spring, however ...

Up to Java 6 the contract of java.io.File.getLastModifed() defined a return value of 0L as being returned if the file does not exist or if an I/O error occurs. From Java 7 it also considers 0L as vaild return value in the Javadoc of getLastModified() 
Where it is required to distinguish an I/O exception from the case where 0L is returned, or where several attributes of the same file are required at the same time, or where the time of last access or the creation time are required, then the Files.readAttributes method may be used.

IMHO, Spring should not throw a FileNotFoundException in case getLastModified() returns 0L but should either just return 0L itself or try to read file attributes in such cases.


Issue Links:

Referenced from: commits b7e4a56, ff0afcf, b53995b, cf3635b

Backported to: 5.0.10, 4.3.20

1 votes, 2 watchers

@spring-projects-issues
Copy link
Collaborator Author

Martin Bonato commented

I just wanted to add, that I've also created an issue at the Jib procject (https://github.com/GoogleContainerTools/jib/issues/1079) for creating a workaround in Jib to avoid that issue. However I still think, that the handling of lastModified in AbstractResource is not 100% correct (at least for Java > 6).

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

This is addressed through a full revision of last-modified handling in 5.1.1 now. I'll backport a minimal version of this to 5.0.10 and 4.3.20, making your scenario work as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) in: web Issues in web modules (web, webmvc, webflux, websocket) status: backported An issue that has been backported to maintenance branches type: bug A general bug
Projects
None yet
Development

No branches or pull requests

2 participants