diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactory.java index 8bb8581689..1fdc54cca8 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactory.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactory.java @@ -279,9 +279,9 @@ public class JettyServletWebServerFactory extends AbstractServletWebServerFactor } } - private Resource createResource(URL url) throws IOException { + private Resource createResource(URL url) throws Exception { if ("file".equals(url.getProtocol())) { - File file = new File(getDecodedFile(url)); + File file = new File(url.toURI()); if (file.isFile()) { return Resource.newResource("jar:" + url + "!/META-INF/resources"); } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactory.java index e2ed862799..6947f403c2 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactory.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactory.java @@ -674,8 +674,8 @@ public class TomcatServletWebServerFactory extends AbstractServletWebServerFacto private void addResourceJars(List resourceJarUrls) { for (URL url : resourceJarUrls) { - String file = getDecodedFile(url); - if (file.endsWith(".jar") || file.endsWith(".jar!/")) { + String path = url.getPath(); + if (path.endsWith(".jar") || path.endsWith(".jar!/")) { String jar = url.toString(); if (!jar.startsWith("jar:")) { // A jar file in the file system. Convert to Jar URL. diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowServletWebServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowServletWebServerFactory.java index 4424986e12..604090f81c 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowServletWebServerFactory.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowServletWebServerFactory.java @@ -361,18 +361,18 @@ public class UndertowServletWebServerFactory extends AbstractServletWebServerFac : new LoaderHidingResourceManager(rootResourceManager)); for (URL url : metaInfResourceUrls) { if ("file".equals(url.getProtocol())) { - File file = new File(getDecodedFile(url)); - if (file.isFile()) { - try { + try { + File file = new File(url.toURI()); + if (file.isFile()) { resourceJarUrls.add(new URL("jar:" + url + "!/")); } - catch (MalformedURLException ex) { - throw new RuntimeException(ex); + else { + resourceManagers.add(new FileResourceManager( + new File(file, "META-INF/resources"), 0)); } } - else { - resourceManagers.add(new FileResourceManager( - new File(file, "META-INF/resources"), 0)); + catch (Exception ex) { + throw new RuntimeException(ex); } } else { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/AbstractServletWebServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/AbstractServletWebServerFactory.java index ba97934054..381fbf4a6c 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/AbstractServletWebServerFactory.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/AbstractServletWebServerFactory.java @@ -282,6 +282,14 @@ public abstract class AbstractServletWebServerFactory return this.staticResourceJars.getUrls(); } + /** + * Converts the given {@code url} into a decoded file path. + * + * @param url the url to convert + * @return the file path + * @deprecated Since 2.0.2 in favor of {@link File#File(java.net.URI)} + */ + @Deprecated protected final String getDecodedFile(URL url) { try { return URLDecoder.decode(url.getFile(), "UTF-8"); diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/StaticResourceJars.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/StaticResourceJars.java index 72c6594d26..0b1f492996 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/StaticResourceJars.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/StaticResourceJars.java @@ -18,14 +18,13 @@ package org.springframework.boot.web.servlet.server; import java.io.File; import java.io.IOException; -import java.io.UnsupportedEncodingException; import java.lang.management.ManagementFactory; import java.net.JarURLConnection; import java.net.MalformedURLException; +import java.net.URISyntaxException; import java.net.URL; import java.net.URLClassLoader; import java.net.URLConnection; -import java.net.URLDecoder; import java.util.ArrayList; import java.util.List; import java.util.jar.JarFile; @@ -71,10 +70,20 @@ class StaticResourceJars { } } + private File toFile(URL url) { + try { + return new File(url.toURI()); + } + catch (URISyntaxException ex) { + throw new IllegalStateException( + "Failed to create File from URL '" + url + "'"); + } + } + private void addUrl(List urls, URL url) { try { if ("file".equals(url.getProtocol())) { - addUrlFile(urls, url, new File(getDecodedFile(url))); + addUrlFile(urls, url, toFile(url)); } else { addUrlConnection(urls, url, url.openConnection()); @@ -85,16 +94,6 @@ class StaticResourceJars { } } - private String getDecodedFile(URL url) { - try { - return URLDecoder.decode(url.getFile(), "UTF-8"); - } - catch (UnsupportedEncodingException ex) { - throw new IllegalStateException( - "Failed to decode '" + url.getFile() + "' using UTF-8"); - } - } - private void addUrlFile(List urls, URL url, File file) { if ((file.isDirectory() && new File(file, "META-INF/resources").isDirectory()) || isResourcesJar(file)) { diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/server/StaticResourceJarsTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/server/StaticResourceJarsTests.java index 8ae5788c14..fbbff0255f 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/server/StaticResourceJarsTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/server/StaticResourceJarsTests.java @@ -58,6 +58,14 @@ public class StaticResourceJarsTests { assertThat(staticResourceJarUrls).hasSize(1); } + @Test + public void includeJarWithStaticResourcesWithPlusInItsPath() throws Exception { + File jarFile = createResourcesJar("test + resources.jar"); + List staticResourceJarUrls = new StaticResourceJars() + .getUrlsFrom(jarFile.toURI().toURL()); + assertThat(staticResourceJarUrls).hasSize(1); + } + @Test public void excludeJarWithoutStaticResources() throws Exception { File jarFile = createJar("dependency.jar"); diff --git a/spring-boot-tests/spring-boot-integration-tests/spring-boot-server-tests/src/test/java/org/springframework/boot/context/embedded/IdeApplicationLauncher.java b/spring-boot-tests/spring-boot-integration-tests/spring-boot-server-tests/src/test/java/org/springframework/boot/context/embedded/IdeApplicationLauncher.java index bec7657a1b..cae0c23066 100644 --- a/spring-boot-tests/spring-boot-integration-tests/spring-boot-server-tests/src/test/java/org/springframework/boot/context/embedded/IdeApplicationLauncher.java +++ b/spring-boot-tests/spring-boot-integration-tests/spring-boot-server-tests/src/test/java/org/springframework/boot/context/embedded/IdeApplicationLauncher.java @@ -40,7 +40,7 @@ import org.springframework.util.StringUtils; */ class IdeApplicationLauncher extends AbstractApplicationLauncher { - private final File exploded = new File("target/ide application"); + private final File exploded = new File("target/the+ide application"); IdeApplicationLauncher(ApplicationBuilder applicationBuilder) { super(applicationBuilder);