From a0f76eab470aeedbc447a432ad9d746d35fc1307 Mon Sep 17 00:00:00 2001 From: Vladimir Tsanev Date: Mon, 29 Feb 2016 18:41:27 +0200 Subject: [PATCH 1/2] =?UTF-8?q?Update=20JarURLConnection=20to=20support=20?= =?UTF-8?q?jar:file://=E2=80=A6=20URLs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, JarURLConnection would fail when created with a URL that began with jar:file:// as the double-slash is not included in jarFile.getUrl().getFile(). This commit updates JarURLConnection to normalise the value return from url.getFile() to remove a double-slash when present. Fixes gh-5287 Closes gh-5289 --- .../boot/loader/jar/JarURLConnection.java | 6 +++++- .../boot/loader/jar/JarFileTests.java | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/JarURLConnection.java b/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/JarURLConnection.java index d2c9a62a6dd..ce4b558dbbb 100644 --- a/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/JarURLConnection.java +++ b/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/JarURLConnection.java @@ -73,7 +73,11 @@ class JarURLConnection extends java.net.JarURLConnection { // What we pass to super is ultimately ignored super(EMPTY_JAR_URL); this.url = url; - String spec = url.getFile().substring(jarFile.getUrl().getFile().length()); + String urlFile = url.getFile(); + if (urlFile.startsWith("file://")) { + urlFile = "file:" + urlFile.substring("file://".length()); + } + String spec = urlFile.substring(jarFile.getUrl().getFile().length()); int separator; while ((separator = spec.indexOf(SEPARATOR)) > 0) { jarFile = getNestedJarFile(jarFile, spec.substring(0, separator)); diff --git a/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/JarFileTests.java b/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/JarFileTests.java index e2b728589df..e58237a54dc 100644 --- a/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/JarFileTests.java +++ b/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/JarFileTests.java @@ -334,6 +334,22 @@ public class JarFileTests { assertThat(connection.getEntryName(), equalTo("2.dat")); } + @Test + public void createNonNestedUrlFromStringCreatedUsingPath() throws Exception { + // gh-5287 + JarFile.registerUrlProtocolHandler(); + String spec = "jar:" + this.rootJarFile.toPath().toUri() + "!/2.dat"; + URL url = new URL(spec); + assertThat(url.toString(), equalTo(spec)); + InputStream inputStream = url.openStream(); + assertThat(inputStream, notNullValue()); + assertThat(inputStream.read(), equalTo(2)); + JarURLConnection connection = (JarURLConnection) url.openConnection(); + assertThat(connection.getURL().toString(), equalTo(spec)); + assertThat(connection.getJarFileURL().toURI(), equalTo(this.rootJarFile.toURI())); + assertThat(connection.getEntryName(), equalTo("2.dat")); + } + @Test public void getDirectoryInputStream() throws Exception { InputStream inputStream = this.jarFile From 74e27db486a8e562d68b98ad7b2611dafe481865 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 6 Apr 2016 16:52:19 +0100 Subject: [PATCH 2/2] Polish contribution --- .../boot/loader/jar/JarURLConnection.java | 18 +++++++++----- .../boot/loader/jar/JarFileTests.java | 24 +++++++------------ 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/JarURLConnection.java b/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/JarURLConnection.java index ce4b558dbbb..dd7d88b9c13 100644 --- a/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/JarURLConnection.java +++ b/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/JarURLConnection.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * Copyright 2012-2016 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. @@ -59,6 +59,8 @@ class JarURLConnection extends java.net.JarURLConnection { private static final JarEntryName EMPTY_JAR_ENTRY_NAME = new JarEntryName(""); + private static final String FILE_COLON_DOUBLE_SLASH = "file://"; + private static ThreadLocal useFastExceptions = new ThreadLocal(); private final JarFile jarFile; @@ -73,11 +75,8 @@ class JarURLConnection extends java.net.JarURLConnection { // What we pass to super is ultimately ignored super(EMPTY_JAR_URL); this.url = url; - String urlFile = url.getFile(); - if (urlFile.startsWith("file://")) { - urlFile = "file:" + urlFile.substring("file://".length()); - } - String spec = urlFile.substring(jarFile.getUrl().getFile().length()); + String spec = getNormalizedFile(url) + .substring(jarFile.getUrl().getFile().length()); int separator; while ((separator = spec.indexOf(SEPARATOR)) > 0) { jarFile = getNestedJarFile(jarFile, spec.substring(0, separator)); @@ -87,6 +86,13 @@ class JarURLConnection extends java.net.JarURLConnection { this.jarEntryName = getJarEntryName(spec); } + private String getNormalizedFile(URL url) { + if (!url.getFile().startsWith(FILE_COLON_DOUBLE_SLASH)) { + return url.getFile(); + } + return "file:" + url.getFile().substring(FILE_COLON_DOUBLE_SLASH.length()); + } + private JarFile getNestedJarFile(JarFile jarFile, String name) throws IOException { JarEntry jarEntry = jarFile.getJarEntry(name); if (jarEntry == null) { diff --git a/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/JarFileTests.java b/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/JarFileTests.java index e58237a54dc..f08243bb200 100644 --- a/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/JarFileTests.java +++ b/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/JarFileTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * Copyright 2012-2016 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. @@ -321,24 +321,18 @@ public class JarFileTests { @Test public void createNonNestedUrlFromString() throws Exception { - JarFile.registerUrlProtocolHandler(); - String spec = "jar:" + this.rootJarFile.toURI() + "!/2.dat"; - URL url = new URL(spec); - assertThat(url.toString(), equalTo(spec)); - InputStream inputStream = url.openStream(); - assertThat(inputStream, notNullValue()); - assertThat(inputStream.read(), equalTo(2)); - JarURLConnection connection = (JarURLConnection) url.openConnection(); - assertThat(connection.getURL().toString(), equalTo(spec)); - assertThat(connection.getJarFileURL().toURI(), equalTo(this.rootJarFile.toURI())); - assertThat(connection.getEntryName(), equalTo("2.dat")); + nonNestedJarFileFromString( + "jar:file:" + this.rootJarFile.getAbsolutePath() + "!/2.dat"); } @Test - public void createNonNestedUrlFromStringCreatedUsingPath() throws Exception { - // gh-5287 + public void createNonNestedUrlFromStringWithDoubleSlash() throws Exception { + nonNestedJarFileFromString( + "jar:file://" + this.rootJarFile.getAbsolutePath() + "!/2.dat"); + } + + private void nonNestedJarFileFromString(String spec) throws Exception { JarFile.registerUrlProtocolHandler(); - String spec = "jar:" + this.rootJarFile.toPath().toUri() + "!/2.dat"; URL url = new URL(spec); assertThat(url.toString(), equalTo(spec)); InputStream inputStream = url.openStream();