From 3daf626842713178f4f396524865da18850467b0 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 26 Apr 2017 18:17:00 +0200 Subject: [PATCH] Defensive fallback for file system resolution in lastModified() Issue: SPR-15485 --- .../io/AbstractFileResolvingResource.java | 32 +++++++++++-------- .../core/io/AbstractResource.java | 7 ++-- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/io/AbstractFileResolvingResource.java b/spring-core/src/main/java/org/springframework/core/io/AbstractFileResolvingResource.java index 21797cd5ce..9b192fd4dd 100644 --- a/spring-core/src/main/java/org/springframework/core/io/AbstractFileResolvingResource.java +++ b/spring-core/src/main/java/org/springframework/core/io/AbstractFileResolvingResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package org.springframework.core.io; import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; @@ -139,11 +140,11 @@ public abstract class AbstractFileResolvingResource extends AbstractResource { try { URL url = getURL(); if (ResourceUtils.isFileURL(url)) { - // Proceed with file system resolution... + // Proceed with file system resolution return getFile().exists(); } else { - // Try a URL connection content-length header... + // Try a URL connection content-length header URLConnection con = url.openConnection(); customizeConnection(con); HttpURLConnection httpCon = @@ -183,7 +184,7 @@ public abstract class AbstractFileResolvingResource extends AbstractResource { try { URL url = getURL(); if (ResourceUtils.isFileURL(url)) { - // Proceed with file system resolution... + // Proceed with file system resolution File file = getFile(); return (file.canRead() && !file.isDirectory()); } @@ -200,11 +201,11 @@ public abstract class AbstractFileResolvingResource extends AbstractResource { public long contentLength() throws IOException { URL url = getURL(); if (ResourceUtils.isFileURL(url)) { - // Proceed with file system resolution... + // Proceed with file system resolution return getFile().length(); } else { - // Try a URL connection content-length header... + // Try a URL connection content-length header URLConnection con = url.openConnection(); customizeConnection(con); return con.getContentLength(); @@ -215,15 +216,18 @@ public abstract class AbstractFileResolvingResource extends AbstractResource { public long lastModified() throws IOException { URL url = getURL(); if (ResourceUtils.isFileURL(url) || ResourceUtils.isJarURL(url)) { - // Proceed with file system resolution... - return super.lastModified(); - } - else { - // Try a URL connection last-modified header... - URLConnection con = url.openConnection(); - customizeConnection(con); - return con.getLastModified(); + // Proceed with file system resolution + try { + return super.lastModified(); + } + catch (FileNotFoundException ex) { + // Defensively fall back to URL connection check instead + } } + // Try a URL connection last-modified header + URLConnection con = url.openConnection(); + customizeConnection(con); + return con.getLastModified(); } diff --git a/spring-core/src/main/java/org/springframework/core/io/AbstractResource.java b/spring-core/src/main/java/org/springframework/core/io/AbstractResource.java index 15b4b8f882..a1c29a837e 100644 --- a/spring-core/src/main/java/org/springframework/core/io/AbstractResource.java +++ b/spring-core/src/main/java/org/springframework/core/io/AbstractResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -181,8 +181,9 @@ public abstract class AbstractResource implements Resource { * Determine the File to use for timestamp checking. *

The default implementation delegates to {@link #getFile()}. * @return the File to use for timestamp checking (never {@code null}) - * @throws IOException if the resource cannot be resolved as absolute - * file path, i.e. if the resource is not available in a file system + * @throws FileNotFoundException if the resource cannot be resolved as + * an absolute file path, i.e. is not available in a file system + * @throws IOException in case of general resolution/reading failures */ protected File getFileForLastModifiedCheck() throws IOException { return getFile();