Reduce JarURLConnection allocations
Update JarURLConnection & Handler so that a shared static final connection is returned for entries that cannot be found. See gh-6215
This commit is contained in:
parent
44b7f29ee3
commit
a5cddf79a8
|
@ -65,7 +65,7 @@ final class CentralDirectoryFileHeader implements FileHeader {
|
|||
}
|
||||
|
||||
void load(byte[] data, int dataOffset, RandomAccessData variableData,
|
||||
int variableOffset) throws IOException {
|
||||
int variableOffset, JarEntryFilter filter) throws IOException {
|
||||
// Load fixed part
|
||||
this.header = data;
|
||||
this.headerOffset = dataOffset;
|
||||
|
@ -81,6 +81,9 @@ final class CentralDirectoryFileHeader implements FileHeader {
|
|||
dataOffset = 0;
|
||||
}
|
||||
this.name = new AsciiBytes(data, dataOffset, (int) nameLength);
|
||||
if (filter != null) {
|
||||
this.name = filter.apply(this.name);
|
||||
}
|
||||
this.extra = NO_EXTRA;
|
||||
this.comment = NO_COMMENT;
|
||||
if (extraLength > 0) {
|
||||
|
@ -172,10 +175,10 @@ final class CentralDirectoryFileHeader implements FileHeader {
|
|||
}
|
||||
|
||||
public static CentralDirectoryFileHeader fromRandomAccessData(RandomAccessData data,
|
||||
int offset) throws IOException {
|
||||
int offset, JarEntryFilter filter) throws IOException {
|
||||
CentralDirectoryFileHeader fileHeader = new CentralDirectoryFileHeader();
|
||||
byte[] bytes = Bytes.get(data.getSubsection(offset, 46));
|
||||
fileHeader.load(bytes, 0, data, offset);
|
||||
fileHeader.load(bytes, 0, data, offset, filter);
|
||||
return fileHeader;
|
||||
}
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ class CentralDirectoryParser {
|
|||
CentralDirectoryFileHeader fileHeader = new CentralDirectoryFileHeader();
|
||||
int dataOffset = 0;
|
||||
for (int i = 0; i < endRecord.getNumberOfRecords(); i++) {
|
||||
fileHeader.load(bytes, dataOffset, null, 0);
|
||||
fileHeader.load(bytes, dataOffset, null, 0, null);
|
||||
visitFileHeader(dataOffset, fileHeader);
|
||||
dataOffset += this.CENTRAL_DIRECTORY_HEADER_BASE_SIZE
|
||||
+ fileHeader.getName().length() + fileHeader.getComment().length()
|
||||
|
|
|
@ -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.
|
||||
|
@ -85,10 +85,10 @@ public class Handler extends URLStreamHandler {
|
|||
@Override
|
||||
protected URLConnection openConnection(URL url) throws IOException {
|
||||
if (this.jarFile != null) {
|
||||
return new JarURLConnection(url, this.jarFile);
|
||||
return JarURLConnection.get(url, this.jarFile);
|
||||
}
|
||||
try {
|
||||
return new JarURLConnection(url, getRootJarFileFromUrl(url));
|
||||
return JarURLConnection.get(url, getRootJarFileFromUrl(url));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
return openFallbackConnection(url, ex);
|
||||
|
|
|
@ -39,8 +39,8 @@ class JarEntry extends java.util.jar.JarEntry implements FileHeader {
|
|||
|
||||
private long localHeaderOffset;
|
||||
|
||||
JarEntry(JarFile jarFile, String name, CentralDirectoryFileHeader header) {
|
||||
super(name);
|
||||
JarEntry(JarFile jarFile, CentralDirectoryFileHeader header) {
|
||||
super(header.getName().toString());
|
||||
this.jarFile = jarFile;
|
||||
this.localHeaderOffset = header.getLocalHeaderOffset();
|
||||
setCompressedSize(header.getCompressedSize());
|
||||
|
|
|
@ -200,6 +200,10 @@ public class JarFile extends java.util.jar.JarFile {
|
|||
return (JarEntry) getEntry(name);
|
||||
}
|
||||
|
||||
public boolean containsEntry(String name) {
|
||||
return this.entries.containsEntry(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ZipEntry getEntry(String name) {
|
||||
return this.entries.getEntry(name);
|
||||
|
@ -320,8 +324,7 @@ public class JarFile extends java.util.jar.JarFile {
|
|||
|
||||
@Override
|
||||
public String getName() {
|
||||
String path = this.pathFromRoot;
|
||||
return this.rootFile.getFile() + path;
|
||||
return this.rootFile.getFile() + this.pathFromRoot;
|
||||
}
|
||||
|
||||
boolean isSigned() {
|
||||
|
|
|
@ -66,11 +66,12 @@ class JarFileEntries implements CentralDirectoryVisitor, Iterable<JarEntry> {
|
|||
|
||||
private int[] positions;
|
||||
|
||||
private final Map<Integer, JarEntry> entriesCache = Collections
|
||||
.synchronizedMap(new LinkedHashMap<Integer, JarEntry>(16, 0.75f, true) {
|
||||
private final Map<Integer, FileHeader> entriesCache = Collections
|
||||
.synchronizedMap(new LinkedHashMap<Integer, FileHeader>(16, 0.75f, true) {
|
||||
|
||||
@Override
|
||||
protected boolean removeEldestEntry(Map.Entry<Integer, JarEntry> eldest) {
|
||||
protected boolean removeEldestEntry(
|
||||
Map.Entry<Integer, FileHeader> eldest) {
|
||||
if (JarFileEntries.this.jarFile.isSigned()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -165,6 +166,10 @@ class JarFileEntries implements CentralDirectoryVisitor, Iterable<JarEntry> {
|
|||
return new EntryIterator();
|
||||
}
|
||||
|
||||
public boolean containsEntry(String name) {
|
||||
return getEntry(name, FileHeader.class, true) != null;
|
||||
}
|
||||
|
||||
public JarEntry getEntry(String name) {
|
||||
return getEntry(name, JarEntry.class, true);
|
||||
}
|
||||
|
@ -235,21 +240,17 @@ class JarFileEntries implements CentralDirectoryVisitor, Iterable<JarEntry> {
|
|||
@SuppressWarnings("unchecked")
|
||||
private <T extends FileHeader> T getEntry(int index, Class<T> type,
|
||||
boolean cacheEntry) {
|
||||
JarEntry entry = this.entriesCache.get(index);
|
||||
if (entry != null) {
|
||||
return (T) entry;
|
||||
}
|
||||
try {
|
||||
CentralDirectoryFileHeader header = CentralDirectoryFileHeader
|
||||
.fromRandomAccessData(this.centralDirectoryData,
|
||||
this.centralDirectoryOffsets[index]);
|
||||
if (FileHeader.class.equals(type)) {
|
||||
// No need to convert
|
||||
return (T) header;
|
||||
FileHeader cached = this.entriesCache.get(index);
|
||||
FileHeader entry = (cached != null ? cached
|
||||
: CentralDirectoryFileHeader.fromRandomAccessData(
|
||||
this.centralDirectoryData,
|
||||
this.centralDirectoryOffsets[index], this.filter));
|
||||
if (CentralDirectoryFileHeader.class.equals(entry.getClass())
|
||||
&& type.equals(JarEntry.class)) {
|
||||
entry = new JarEntry(this.jarFile, (CentralDirectoryFileHeader) entry);
|
||||
}
|
||||
entry = new JarEntry(this.jarFile, applyFilter(header.getName()).toString(),
|
||||
header);
|
||||
if (cacheEntry) {
|
||||
if (cacheEntry && cached != entry) {
|
||||
this.entriesCache.put(index, entry);
|
||||
}
|
||||
return (T) entry;
|
||||
|
|
|
@ -35,9 +35,15 @@ import java.security.Permission;
|
|||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
class JarURLConnection extends java.net.JarURLConnection {
|
||||
final class JarURLConnection extends java.net.JarURLConnection {
|
||||
|
||||
private static final FileNotFoundException FILE_NOT_FOUND_EXCEPTION = new FileNotFoundException();
|
||||
private static ThreadLocal<Boolean> useFastExceptions = new ThreadLocal<Boolean>();
|
||||
|
||||
private static final FileNotFoundException FILE_NOT_FOUND_EXCEPTION = new FileNotFoundException(
|
||||
"Jar file or entry not found");
|
||||
|
||||
private static final IllegalStateException NOT_FOUND_CONNECTION_EXCEPTION = new IllegalStateException(
|
||||
FILE_NOT_FOUND_EXCEPTION);
|
||||
|
||||
private static final String SEPARATOR = "!/";
|
||||
|
||||
|
@ -63,7 +69,8 @@ class JarURLConnection extends java.net.JarURLConnection {
|
|||
|
||||
private static final String READ_ACTION = "read";
|
||||
|
||||
private static ThreadLocal<Boolean> useFastExceptions = new ThreadLocal<Boolean>();
|
||||
private static final JarURLConnection NOT_FOUND_CONNECTION = JarURLConnection
|
||||
.notFound();
|
||||
|
||||
private final JarFile jarFile;
|
||||
|
||||
|
@ -75,48 +82,20 @@ class JarURLConnection extends java.net.JarURLConnection {
|
|||
|
||||
private JarEntry jarEntry;
|
||||
|
||||
protected JarURLConnection(URL url, JarFile jarFile) throws IOException {
|
||||
private JarURLConnection(URL url, JarFile jarFile, JarEntryName jarEntryName)
|
||||
throws IOException {
|
||||
// What we pass to super is ultimately ignored
|
||||
super(EMPTY_JAR_URL);
|
||||
this.url = url;
|
||||
String spec = extractFullSpec(url, jarFile.getPathFromRoot());
|
||||
int separator;
|
||||
int index = 0;
|
||||
while ((separator = spec.indexOf(SEPARATOR, index)) > 0) {
|
||||
jarFile = getNestedJarFile(jarFile, spec.substring(index, separator));
|
||||
index += separator + SEPARATOR.length();
|
||||
}
|
||||
this.jarFile = jarFile;
|
||||
this.jarEntryName = getJarEntryName(spec.substring(index));
|
||||
}
|
||||
|
||||
private String extractFullSpec(URL url, String pathFromRoot) {
|
||||
String file = url.getFile();
|
||||
int separatorIndex = file.indexOf(SEPARATOR);
|
||||
if (separatorIndex < 0) {
|
||||
return "";
|
||||
}
|
||||
int specIndex = separatorIndex + SEPARATOR.length() + pathFromRoot.length();
|
||||
return file.substring(specIndex);
|
||||
}
|
||||
|
||||
private JarFile getNestedJarFile(JarFile jarFile, String name) throws IOException {
|
||||
JarEntry jarEntry = jarFile.getJarEntry(name);
|
||||
if (jarEntry == null) {
|
||||
throwFileNotFound(jarEntry, jarFile);
|
||||
}
|
||||
return jarFile.getNestedJarFile(jarEntry);
|
||||
}
|
||||
|
||||
private JarEntryName getJarEntryName(String spec) {
|
||||
if (spec.length() == 0) {
|
||||
return EMPTY_JAR_ENTRY_NAME;
|
||||
}
|
||||
return new JarEntryName(spec);
|
||||
this.jarEntryName = jarEntryName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connect() throws IOException {
|
||||
if (this.jarFile == null) {
|
||||
throw FILE_NOT_FOUND_EXCEPTION;
|
||||
}
|
||||
if (!this.jarEntryName.isEmpty() && this.jarEntry == null) {
|
||||
this.jarEntry = this.jarFile.getJarEntry(getEntryName());
|
||||
if (this.jarEntry == null) {
|
||||
|
@ -126,15 +105,6 @@ class JarURLConnection extends java.net.JarURLConnection {
|
|||
this.connected = true;
|
||||
}
|
||||
|
||||
private void throwFileNotFound(Object entry, JarFile jarFile)
|
||||
throws FileNotFoundException {
|
||||
if (Boolean.TRUE.equals(useFastExceptions.get())) {
|
||||
throw FILE_NOT_FOUND_EXCEPTION;
|
||||
}
|
||||
throw new FileNotFoundException(
|
||||
"JAR entry " + entry + " not found in " + jarFile.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public JarFile getJarFile() throws IOException {
|
||||
connect();
|
||||
|
@ -143,6 +113,9 @@ class JarURLConnection extends java.net.JarURLConnection {
|
|||
|
||||
@Override
|
||||
public URL getJarFileURL() {
|
||||
if (this.jarFile == null) {
|
||||
throw NOT_FOUND_CONNECTION_EXCEPTION;
|
||||
}
|
||||
if (this.jarFileUrl == null) {
|
||||
this.jarFileUrl = buildJarFileUrl();
|
||||
}
|
||||
|
@ -167,7 +140,7 @@ class JarURLConnection extends java.net.JarURLConnection {
|
|||
|
||||
@Override
|
||||
public JarEntry getJarEntry() throws IOException {
|
||||
if (this.jarEntryName.isEmpty()) {
|
||||
if (this.jarEntryName == null || this.jarEntryName.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
connect();
|
||||
|
@ -176,11 +149,17 @@ class JarURLConnection extends java.net.JarURLConnection {
|
|||
|
||||
@Override
|
||||
public String getEntryName() {
|
||||
if (this.jarFile == null) {
|
||||
throw NOT_FOUND_CONNECTION_EXCEPTION;
|
||||
}
|
||||
return this.jarEntryName.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream() throws IOException {
|
||||
if (this.jarFile == null) {
|
||||
throw FILE_NOT_FOUND_EXCEPTION;
|
||||
}
|
||||
if (this.jarEntryName.isEmpty()) {
|
||||
throw new IOException("no entry name specified");
|
||||
}
|
||||
|
@ -192,8 +171,20 @@ class JarURLConnection extends java.net.JarURLConnection {
|
|||
return inputStream;
|
||||
}
|
||||
|
||||
private void throwFileNotFound(Object entry, JarFile jarFile)
|
||||
throws FileNotFoundException {
|
||||
if (Boolean.TRUE.equals(useFastExceptions.get())) {
|
||||
throw FILE_NOT_FOUND_EXCEPTION;
|
||||
}
|
||||
throw new FileNotFoundException(
|
||||
"JAR entry " + entry + " not found in " + jarFile.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getContentLength() {
|
||||
if (this.jarFile == null) {
|
||||
return -1;
|
||||
}
|
||||
try {
|
||||
if (this.jarEntryName.isEmpty()) {
|
||||
return this.jarFile.size();
|
||||
|
@ -214,11 +205,14 @@ class JarURLConnection extends java.net.JarURLConnection {
|
|||
|
||||
@Override
|
||||
public String getContentType() {
|
||||
return this.jarEntryName.getContentType();
|
||||
return (this.jarEntryName == null ? null : this.jarEntryName.getContentType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Permission getPermission() throws IOException {
|
||||
if (this.jarFile == null) {
|
||||
throw FILE_NOT_FOUND_EXCEPTION;
|
||||
}
|
||||
if (this.permission == null) {
|
||||
this.permission = new FilePermission(
|
||||
this.jarFile.getRootJarFile().getFile().getPath(), READ_ACTION);
|
||||
|
@ -230,6 +224,56 @@ class JarURLConnection extends java.net.JarURLConnection {
|
|||
JarURLConnection.useFastExceptions.set(useFastExceptions);
|
||||
}
|
||||
|
||||
static JarURLConnection get(URL url, JarFile jarFile) throws IOException {
|
||||
String spec = extractFullSpec(url, jarFile.getPathFromRoot());
|
||||
int separator;
|
||||
int index = 0;
|
||||
while ((separator = spec.indexOf(SEPARATOR, index)) > 0) {
|
||||
String entryName = spec.substring(index, separator);
|
||||
JarEntry jarEntry = jarFile.getJarEntry(entryName);
|
||||
if (jarEntry == null) {
|
||||
return JarURLConnection.notFound(jarFile, JarEntryName.get(entryName));
|
||||
}
|
||||
jarFile = jarFile.getNestedJarFile(jarEntry);
|
||||
index += separator + SEPARATOR.length();
|
||||
}
|
||||
JarEntryName jarEntryName = JarEntryName.get(spec, index);
|
||||
if (Boolean.TRUE.equals(useFastExceptions.get())) {
|
||||
if (!jarEntryName.isEmpty()
|
||||
&& !jarFile.containsEntry(jarEntryName.toString())) {
|
||||
return NOT_FOUND_CONNECTION;
|
||||
}
|
||||
}
|
||||
return new JarURLConnection(url, jarFile, jarEntryName);
|
||||
}
|
||||
|
||||
private static String extractFullSpec(URL url, String pathFromRoot) {
|
||||
String file = url.getFile();
|
||||
int separatorIndex = file.indexOf(SEPARATOR);
|
||||
if (separatorIndex < 0) {
|
||||
return "";
|
||||
}
|
||||
int specIndex = separatorIndex + SEPARATOR.length() + pathFromRoot.length();
|
||||
return file.substring(specIndex);
|
||||
}
|
||||
|
||||
private static JarURLConnection notFound() {
|
||||
try {
|
||||
return notFound(null, null);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static JarURLConnection notFound(JarFile jarFile, JarEntryName jarEntryName)
|
||||
throws IOException {
|
||||
if (Boolean.TRUE.equals(useFastExceptions.get())) {
|
||||
return NOT_FOUND_CONNECTION;
|
||||
}
|
||||
return new JarURLConnection(null, jarFile, jarEntryName);
|
||||
}
|
||||
|
||||
/**
|
||||
* A JarEntryName parsed from a URL String.
|
||||
*/
|
||||
|
@ -316,6 +360,17 @@ class JarURLConnection extends java.net.JarURLConnection {
|
|||
return type;
|
||||
}
|
||||
|
||||
public static JarEntryName get(String spec) {
|
||||
return get(spec, 0);
|
||||
}
|
||||
|
||||
public static JarEntryName get(String spec, int beginIndex) {
|
||||
if (spec.length() <= beginIndex) {
|
||||
return EMPTY_JAR_ENTRY_NAME;
|
||||
}
|
||||
return new JarEntryName(spec.substring(beginIndex));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,11 +18,13 @@ package org.springframework.boot.loader.jar;
|
|||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.net.URL;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
import org.springframework.boot.loader.TestJarCreator;
|
||||
|
@ -33,12 +35,16 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||
* Tests for {@link JarURLConnection}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class JarURLConnectionTests {
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder temporaryFolder = new TemporaryFolder(new File("target"));
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
private File rootJarFile;
|
||||
|
||||
private JarFile jarFile;
|
||||
|
@ -52,76 +58,84 @@ public class JarURLConnectionTests {
|
|||
|
||||
@Test
|
||||
public void connectionToRootUsingAbsoluteUrl() throws Exception {
|
||||
URL absoluteUrl = new URL("jar:file:" + getAbsolutePath() + "!/");
|
||||
assertThat(new JarURLConnection(absoluteUrl, this.jarFile).getContent())
|
||||
URL url = new URL("jar:file:" + getAbsolutePath() + "!/");
|
||||
assertThat(JarURLConnection.get(url, this.jarFile).getContent())
|
||||
.isSameAs(this.jarFile);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void connectionToRootUsingRelativeUrl() throws Exception {
|
||||
URL relativeUrl = new URL("jar:file:" + getRelativePath() + "!/");
|
||||
assertThat(new JarURLConnection(relativeUrl, this.jarFile).getContent())
|
||||
URL url = new URL("jar:file:" + getRelativePath() + "!/");
|
||||
assertThat(JarURLConnection.get(url, this.jarFile).getContent())
|
||||
.isSameAs(this.jarFile);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void connectionToEntryUsingAbsoluteUrl() throws Exception {
|
||||
URL absoluteUrl = new URL("jar:file:" + getAbsolutePath() + "!/1.dat");
|
||||
assertThat(new JarURLConnection(absoluteUrl, this.jarFile).getInputStream())
|
||||
URL url = new URL("jar:file:" + getAbsolutePath() + "!/1.dat");
|
||||
assertThat(JarURLConnection.get(url, this.jarFile).getInputStream())
|
||||
.hasSameContentAs(new ByteArrayInputStream(new byte[] { 1 }));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void connectionToEntryUsingRelativeUrl() throws Exception {
|
||||
URL relativeUrl = new URL("jar:file:" + getRelativePath() + "!/1.dat");
|
||||
assertThat(new JarURLConnection(relativeUrl, this.jarFile).getInputStream())
|
||||
URL url = new URL("jar:file:" + getRelativePath() + "!/1.dat");
|
||||
assertThat(JarURLConnection.get(url, this.jarFile).getInputStream())
|
||||
.hasSameContentAs(new ByteArrayInputStream(new byte[] { 1 }));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void connectionToEntryUsingAbsoluteUrlWithFileColonSlashSlashPrefix()
|
||||
throws Exception {
|
||||
URL absoluteUrl = new URL("jar:file:/" + getAbsolutePath() + "!/1.dat");
|
||||
assertThat(new JarURLConnection(absoluteUrl, this.jarFile).getInputStream())
|
||||
URL url = new URL("jar:file:/" + getAbsolutePath() + "!/1.dat");
|
||||
assertThat(JarURLConnection.get(url, this.jarFile).getInputStream())
|
||||
.hasSameContentAs(new ByteArrayInputStream(new byte[] { 1 }));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void connectionToEntryUsingAbsoluteUrlForNestedEntry() throws Exception {
|
||||
URL absoluteUrl = new URL(
|
||||
"jar:file:" + getAbsolutePath() + "!/nested.jar!/3.dat");
|
||||
assertThat(new JarURLConnection(absoluteUrl, this.jarFile).getInputStream())
|
||||
URL url = new URL("jar:file:" + getAbsolutePath() + "!/nested.jar!/3.dat");
|
||||
assertThat(JarURLConnection.get(url, this.jarFile).getInputStream())
|
||||
.hasSameContentAs(new ByteArrayInputStream(new byte[] { 3 }));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void connectionToEntryUsingRelativeUrlForNestedEntry() throws Exception {
|
||||
URL relativeUrl = new URL(
|
||||
"jar:file:" + getRelativePath() + "!/nested.jar!/3.dat");
|
||||
assertThat(new JarURLConnection(relativeUrl, this.jarFile).getInputStream())
|
||||
URL url = new URL("jar:file:" + getRelativePath() + "!/nested.jar!/3.dat");
|
||||
assertThat(JarURLConnection.get(url, this.jarFile).getInputStream())
|
||||
.hasSameContentAs(new ByteArrayInputStream(new byte[] { 3 }));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void connectionToEntryUsingAbsoluteUrlForEntryFromNestedJarFile()
|
||||
throws Exception {
|
||||
URL absoluteUrl = new URL(
|
||||
"jar:file:" + getAbsolutePath() + "!/nested.jar!/3.dat");
|
||||
assertThat(new JarURLConnection(absoluteUrl,
|
||||
this.jarFile.getNestedJarFile(this.jarFile.getEntry("nested.jar")))
|
||||
.getInputStream()).hasSameContentAs(
|
||||
new ByteArrayInputStream(new byte[] { 3 }));
|
||||
URL url = new URL("jar:file:" + getAbsolutePath() + "!/nested.jar!/3.dat");
|
||||
JarFile nested = this.jarFile
|
||||
.getNestedJarFile(this.jarFile.getEntry("nested.jar"));
|
||||
assertThat(JarURLConnection.get(url, nested).getInputStream())
|
||||
.hasSameContentAs(new ByteArrayInputStream(new byte[] { 3 }));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void connectionToEntryUsingRelativeUrlForEntryFromNestedJarFile()
|
||||
throws Exception {
|
||||
URL absoluteUrl = new URL(
|
||||
"jar:file:" + getRelativePath() + "!/nested.jar!/3.dat");
|
||||
assertThat(new JarURLConnection(absoluteUrl,
|
||||
this.jarFile.getNestedJarFile(this.jarFile.getEntry("nested.jar")))
|
||||
.getInputStream()).hasSameContentAs(
|
||||
new ByteArrayInputStream(new byte[] { 3 }));
|
||||
URL url = new URL("jar:file:" + getRelativePath() + "!/nested.jar!/3.dat");
|
||||
JarFile nested = this.jarFile
|
||||
.getNestedJarFile(this.jarFile.getEntry("nested.jar"));
|
||||
assertThat(JarURLConnection.get(url, nested).getInputStream())
|
||||
.hasSameContentAs(new ByteArrayInputStream(new byte[] { 3 }));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nestedJarNotFound() throws Exception {
|
||||
URL url = new URL(
|
||||
"jar:file:" + getAbsolutePath() + "!/nested.jar!/missing.jar!/1.dat");
|
||||
JarFile nested = this.jarFile
|
||||
.getNestedJarFile(this.jarFile.getEntry("nested.jar"));
|
||||
JarURLConnection connection = JarURLConnection.get(url, nested);
|
||||
this.thrown.expect(FileNotFoundException.class);
|
||||
this.thrown.expectMessage("JAR entry missing.jar not found in");
|
||||
connection.connect();
|
||||
}
|
||||
|
||||
private String getAbsolutePath() {
|
||||
|
|
Loading…
Reference in New Issue