commit
4f47b7b46a
|
@ -146,6 +146,7 @@ public class JarFile extends java.util.jar.JarFile implements Iterable<java.util
|
||||||
private JarFile(JarFile parent, RandomAccessDataFile rootFile, String pathFromRoot, RandomAccessData data,
|
private JarFile(JarFile parent, RandomAccessDataFile rootFile, String pathFromRoot, RandomAccessData data,
|
||||||
JarEntryFilter filter, JarFileType type, Supplier<Manifest> manifestSupplier) throws IOException {
|
JarEntryFilter filter, JarFileType type, Supplier<Manifest> manifestSupplier) throws IOException {
|
||||||
super(rootFile.getFile());
|
super(rootFile.getFile());
|
||||||
|
super.close();
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.rootFile = rootFile;
|
this.rootFile = rootFile;
|
||||||
this.pathFromRoot = pathFromRoot;
|
this.pathFromRoot = pathFromRoot;
|
||||||
|
@ -353,7 +354,6 @@ public class JarFile extends java.util.jar.JarFile implements Iterable<java.util
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.closed = true;
|
this.closed = true;
|
||||||
super.close();
|
|
||||||
if (this.type == JarFileType.DIRECT && this.parent == null) {
|
if (this.type == JarFileType.DIRECT && this.parent == null) {
|
||||||
this.rootFile.close();
|
this.rootFile.close();
|
||||||
}
|
}
|
||||||
|
@ -365,6 +365,10 @@ public class JarFile extends java.util.jar.JarFile implements Iterable<java.util
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean isClosed() {
|
||||||
|
return this.closed;
|
||||||
|
}
|
||||||
|
|
||||||
String getUrlString() throws MalformedURLException {
|
String getUrlString() throws MalformedURLException {
|
||||||
if (this.urlString == null) {
|
if (this.urlString == null) {
|
||||||
this.urlString = getUrl().toString();
|
this.urlString = getUrl().toString();
|
||||||
|
|
|
@ -19,7 +19,6 @@ package org.springframework.boot.loader.jar;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.FilePermission;
|
import java.io.FilePermission;
|
||||||
import java.io.FilterInputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
@ -81,18 +80,14 @@ final class JarURLConnection extends java.net.JarURLConnection {
|
||||||
|
|
||||||
private final JarEntryName jarEntryName;
|
private final JarEntryName jarEntryName;
|
||||||
|
|
||||||
private final CloseAction closeAction;
|
|
||||||
|
|
||||||
private JarEntry jarEntry;
|
private JarEntry jarEntry;
|
||||||
|
|
||||||
private JarURLConnection(URL url, JarFile jarFile, JarEntryName jarEntryName, CloseAction closeAction)
|
private JarURLConnection(URL url, JarFile jarFile, JarEntryName jarEntryName) throws IOException {
|
||||||
throws IOException {
|
|
||||||
// What we pass to super is ultimately ignored
|
// What we pass to super is ultimately ignored
|
||||||
super(EMPTY_JAR_URL);
|
super(EMPTY_JAR_URL);
|
||||||
this.url = url;
|
this.url = url;
|
||||||
this.jarFile = jarFile;
|
this.jarFile = jarFile;
|
||||||
this.jarEntryName = jarEntryName;
|
this.jarEntryName = jarEntryName;
|
||||||
this.closeAction = closeAction;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -173,17 +168,7 @@ final class JarURLConnection extends java.net.JarURLConnection {
|
||||||
if (inputStream == null) {
|
if (inputStream == null) {
|
||||||
throwFileNotFound(this.jarEntryName, this.jarFile);
|
throwFileNotFound(this.jarEntryName, this.jarFile);
|
||||||
}
|
}
|
||||||
return new FilterInputStream(inputStream) {
|
return inputStream;
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() throws IOException {
|
|
||||||
super.close();
|
|
||||||
if (JarURLConnection.this.closeAction != null) {
|
|
||||||
JarURLConnection.this.closeAction.perform();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void throwFileNotFound(Object entry, JarFile jarFile) throws FileNotFoundException {
|
private void throwFileNotFound(Object entry, JarFile jarFile) throws FileNotFoundException {
|
||||||
|
@ -264,30 +249,24 @@ final class JarURLConnection extends java.net.JarURLConnection {
|
||||||
int index = indexOfRootSpec(spec, jarFile.getPathFromRoot());
|
int index = indexOfRootSpec(spec, jarFile.getPathFromRoot());
|
||||||
if (index == -1) {
|
if (index == -1) {
|
||||||
return (Boolean.TRUE.equals(useFastExceptions.get()) ? NOT_FOUND_CONNECTION
|
return (Boolean.TRUE.equals(useFastExceptions.get()) ? NOT_FOUND_CONNECTION
|
||||||
: new JarURLConnection(url, null, EMPTY_JAR_ENTRY_NAME, null));
|
: new JarURLConnection(url, null, EMPTY_JAR_ENTRY_NAME));
|
||||||
}
|
}
|
||||||
int separator;
|
int separator;
|
||||||
JarFile connectionJarFile = jarFile;
|
|
||||||
while ((separator = spec.indexOf(SEPARATOR, index)) > 0) {
|
while ((separator = spec.indexOf(SEPARATOR, index)) > 0) {
|
||||||
JarEntryName entryName = JarEntryName.get(spec.subSequence(index, separator));
|
JarEntryName entryName = JarEntryName.get(spec.subSequence(index, separator));
|
||||||
JarEntry jarEntry = jarFile.getJarEntry(entryName.toCharSequence());
|
JarEntry jarEntry = jarFile.getJarEntry(entryName.toCharSequence());
|
||||||
if (jarEntry == null) {
|
if (jarEntry == null) {
|
||||||
return JarURLConnection.notFound(connectionJarFile, entryName,
|
return JarURLConnection.notFound(jarFile, entryName);
|
||||||
(connectionJarFile != jarFile) ? connectionJarFile::close : null);
|
|
||||||
}
|
}
|
||||||
connectionJarFile = connectionJarFile.getNestedJarFile(jarEntry);
|
jarFile = jarFile.getNestedJarFile(jarEntry);
|
||||||
index = separator + SEPARATOR.length();
|
index = separator + SEPARATOR.length();
|
||||||
}
|
}
|
||||||
JarEntryName jarEntryName = JarEntryName.get(spec, index);
|
JarEntryName jarEntryName = JarEntryName.get(spec, index);
|
||||||
if (Boolean.TRUE.equals(useFastExceptions.get()) && !jarEntryName.isEmpty()
|
if (Boolean.TRUE.equals(useFastExceptions.get()) && !jarEntryName.isEmpty()
|
||||||
&& !connectionJarFile.containsEntry(jarEntryName.toString())) {
|
&& !jarFile.containsEntry(jarEntryName.toString())) {
|
||||||
if (connectionJarFile != jarFile) {
|
|
||||||
connectionJarFile.close();
|
|
||||||
}
|
|
||||||
return NOT_FOUND_CONNECTION;
|
return NOT_FOUND_CONNECTION;
|
||||||
}
|
}
|
||||||
return new JarURLConnection(url, new JarFile(connectionJarFile), jarEntryName,
|
return new JarURLConnection(url, new JarFile(jarFile), jarEntryName);
|
||||||
(connectionJarFile != jarFile) ? connectionJarFile::close : null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int indexOfRootSpec(StringSequence file, String pathFromRoot) {
|
private static int indexOfRootSpec(StringSequence file, String pathFromRoot) {
|
||||||
|
@ -300,22 +279,18 @@ final class JarURLConnection extends java.net.JarURLConnection {
|
||||||
|
|
||||||
private static JarURLConnection notFound() {
|
private static JarURLConnection notFound() {
|
||||||
try {
|
try {
|
||||||
return notFound(null, null, null);
|
return notFound(null, null);
|
||||||
}
|
}
|
||||||
catch (IOException ex) {
|
catch (IOException ex) {
|
||||||
throw new IllegalStateException(ex);
|
throw new IllegalStateException(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static JarURLConnection notFound(JarFile jarFile, JarEntryName jarEntryName, CloseAction closeAction)
|
private static JarURLConnection notFound(JarFile jarFile, JarEntryName jarEntryName) throws IOException {
|
||||||
throws IOException {
|
|
||||||
if (Boolean.TRUE.equals(useFastExceptions.get())) {
|
if (Boolean.TRUE.equals(useFastExceptions.get())) {
|
||||||
if (closeAction != null) {
|
|
||||||
closeAction.perform();
|
|
||||||
}
|
|
||||||
return NOT_FOUND_CONNECTION;
|
return NOT_FOUND_CONNECTION;
|
||||||
}
|
}
|
||||||
return new JarURLConnection(null, jarFile, jarEntryName, closeAction);
|
return new JarURLConnection(null, jarFile, jarEntryName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -418,15 +393,4 @@ final class JarURLConnection extends java.net.JarURLConnection {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* An action to be taken when the connection is being "closed" and its underlying
|
|
||||||
* resources are no longer needed.
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
private interface CloseAction {
|
|
||||||
|
|
||||||
void perform() throws IOException;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,6 @@ import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.zip.ZipFile;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
@ -30,7 +29,6 @@ import org.junit.jupiter.api.io.TempDir;
|
||||||
|
|
||||||
import org.springframework.boot.loader.TestJarCreator;
|
import org.springframework.boot.loader.TestJarCreator;
|
||||||
import org.springframework.boot.loader.jar.JarURLConnection.JarEntryName;
|
import org.springframework.boot.loader.jar.JarURLConnection.JarEntryName;
|
||||||
import org.springframework.test.util.ReflectionTestUtils;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||||
|
@ -230,7 +228,7 @@ class JarURLConnectionTests {
|
||||||
JarURLConnection connection = JarURLConnection.get(url, this.jarFile);
|
JarURLConnection connection = JarURLConnection.get(url, this.jarFile);
|
||||||
JarFile connectionJarFile = connection.getJarFile();
|
JarFile connectionJarFile = connection.getJarFile();
|
||||||
connectionJarFile.close();
|
connectionJarFile.close();
|
||||||
assertThat((Boolean) ReflectionTestUtils.getField(this.jarFile, ZipFile.class, "closeRequested")).isFalse();
|
assertThat(this.jarFile.isClosed()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getRelativePath() {
|
private String getRelativePath() {
|
||||||
|
|
Loading…
Reference in New Issue