Commit 1412eaa0 authored by Andy Wilkinson's avatar Andy Wilkinson

Handle relative URLs in jar's Class-Path when getting changeable URLs

5e0ba6ea added support for reading a jar manifest's Class-Path
attribute when resolving changeable URLs from a URLClassLoader,
however it did not handle relative URLs, i.e. URLs without a protocol,
correctly.

This commit updates ChangeableUrls so that it uses the URL of the
JAR that contains the manifest as the base for any new URLs that
are created. When the Class-Path entry is relative, this base will
be used. When the Class-Path entry is absolutee, URL's constructor
will ignore the supplied base.

Closes gh-5665
parent af248381
...@@ -94,7 +94,7 @@ final class ChangeableUrls implements Iterable<URL> { ...@@ -94,7 +94,7 @@ final class ChangeableUrls implements Iterable<URL> {
JarFile jarFile = getJarFileIfPossible(url); JarFile jarFile = getJarFileIfPossible(url);
if (jarFile != null) { if (jarFile != null) {
try { try {
return getUrlsFromClassPathAttribute(jarFile.getManifest()); return getUrlsFromClassPathAttribute(url, jarFile.getManifest());
} }
catch (IOException ex) { catch (IOException ex) {
throw new IllegalStateException( throw new IllegalStateException(
...@@ -118,7 +118,7 @@ final class ChangeableUrls implements Iterable<URL> { ...@@ -118,7 +118,7 @@ final class ChangeableUrls implements Iterable<URL> {
return null; return null;
} }
private static List<URL> getUrlsFromClassPathAttribute(Manifest manifest) { private static List<URL> getUrlsFromClassPathAttribute(URL base, Manifest manifest) {
List<URL> urls = new ArrayList<URL>(); List<URL> urls = new ArrayList<URL>();
String classPathAttribute = manifest.getMainAttributes() String classPathAttribute = manifest.getMainAttributes()
.getValue(Attributes.Name.CLASS_PATH); .getValue(Attributes.Name.CLASS_PATH);
...@@ -126,7 +126,7 @@ final class ChangeableUrls implements Iterable<URL> { ...@@ -126,7 +126,7 @@ final class ChangeableUrls implements Iterable<URL> {
for (String entry : StringUtils.delimitedListToStringArray(classPathAttribute, for (String entry : StringUtils.delimitedListToStringArray(classPathAttribute,
" ")) { " ")) {
try { try {
urls.add(new URL(entry)); urls.add(new URL(base, entry));
} }
catch (MalformedURLException ex) { catch (MalformedURLException ex) {
throw new IllegalStateException( throw new IllegalStateException(
......
...@@ -77,10 +77,12 @@ public class ChangeableUrlsTests { ...@@ -77,10 +77,12 @@ public class ChangeableUrlsTests {
public void urlsFromJarClassPathAreConsidered() throws Exception { public void urlsFromJarClassPathAreConsidered() throws Exception {
URL projectCore = makeUrl("project-core"); URL projectCore = makeUrl("project-core");
URL projectWeb = makeUrl("project-web"); URL projectWeb = makeUrl("project-web");
File relative = this.temporaryFolder.newFolder();
ChangeableUrls urls = ChangeableUrls.fromUrlClassLoader(new URLClassLoader( ChangeableUrls urls = ChangeableUrls.fromUrlClassLoader(new URLClassLoader(
new URL[] { makeJarFileWithUrlsInManifestClassPath(projectCore, new URL[] { makeJarFileWithUrlsInManifestClassPath(projectCore,
projectWeb) })); projectWeb, relative.getName() + "/") }));
assertThat(urls.toList(), contains(projectCore, projectWeb)); assertThat(urls.toList(),
contains(projectCore, projectWeb, relative.toURI().toURL()));
} }
private URL makeUrl(String name) throws IOException { private URL makeUrl(String name) throws IOException {
...@@ -92,7 +94,7 @@ public class ChangeableUrlsTests { ...@@ -92,7 +94,7 @@ public class ChangeableUrlsTests {
return file.toURI().toURL(); return file.toURI().toURL();
} }
private URL makeJarFileWithUrlsInManifestClassPath(URL... urls) throws Exception { private URL makeJarFileWithUrlsInManifestClassPath(Object... urls) throws Exception {
File classpathJar = this.temporaryFolder.newFile("classpath.jar"); File classpathJar = this.temporaryFolder.newFile("classpath.jar");
Manifest manifest = new Manifest(); Manifest manifest = new Manifest();
manifest.getMainAttributes().putValue(Attributes.Name.MANIFEST_VERSION.toString(), manifest.getMainAttributes().putValue(Attributes.Name.MANIFEST_VERSION.toString(),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment