From f42b442ce2008f218192aafa2ba2840e1ce88bb1 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 3 Oct 2019 15:29:58 +0100 Subject: [PATCH] Fix handling of encoded URLs in Class-Path manifest attribute Fixes gh-18410 --- .../boot/devtools/restart/ChangeableUrls.java | 9 ++++++++- .../boot/devtools/restart/ChangeableUrlsTests.java | 7 +++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/ChangeableUrls.java b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/ChangeableUrls.java index dd42b5ce092..ea19344290a 100644 --- a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/ChangeableUrls.java +++ b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/ChangeableUrls.java @@ -22,6 +22,7 @@ import java.lang.management.ManagementFactory; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; +import java.net.URLDecoder; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -156,7 +157,13 @@ final class ChangeableUrls implements Iterable { urls.add(referenced); } else { - nonExistentEntries.add(referenced); + referenced = new URL(jarUrl, URLDecoder.decode(entry, "UTF-8")); + if (new File(referenced.getFile()).exists()) { + urls.add(referenced); + } + else { + nonExistentEntries.add(referenced); + } } } catch (MalformedURLException ex) { diff --git a/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/restart/ChangeableUrlsTests.java b/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/restart/ChangeableUrlsTests.java index 5328097fedc..6c6dc063ea3 100644 --- a/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/restart/ChangeableUrlsTests.java +++ b/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/restart/ChangeableUrlsTests.java @@ -82,14 +82,17 @@ public class ChangeableUrlsTests { File relative = this.temporaryFolder.newFolder(); URL absoluteUrl = this.temporaryFolder.newFolder().toURI().toURL(); File jarWithClassPath = makeJarFileWithUrlsInManifestClassPath("project-core/target/classes/", - "project-web/target/classes/", "does-not-exist/target/classes", relative.getName() + "/", absoluteUrl); + "project-web/target/classes/", "project%20space/target/classes/", "does-not-exist/target/classes/", + relative.getName() + "/", absoluteUrl); new File(jarWithClassPath.getParentFile(), "project-core/target/classes").mkdirs(); new File(jarWithClassPath.getParentFile(), "project-web/target/classes").mkdirs(); + new File(jarWithClassPath.getParentFile(), "project space/target/classes").mkdirs(); ChangeableUrls urls = ChangeableUrls.fromClassLoader( new URLClassLoader(new URL[] { jarWithClassPath.toURI().toURL(), makeJarFileWithNoManifest() })); assertThat(urls.toList()).containsExactly( new URL(jarWithClassPath.toURI().toURL(), "project-core/target/classes/"), - new URL(jarWithClassPath.toURI().toURL(), "project-web/target/classes/"), relative.toURI().toURL(), + new URL(jarWithClassPath.toURI().toURL(), "project-web/target/classes/"), + new URL(jarWithClassPath.toURI().toURL(), "project space/target/classes/"), relative.toURI().toURL(), absoluteUrl); }