Fail operations when JarFile is closed

Update `JarFile` to track when the instance has been closed and throw
an exception in the same way that `ZipFile` does.

Closes gh-21072
This commit is contained in:
Phillip Webb
2020-04-21 18:11:03 -07:00
parent cc33e23d31
commit ed7a5db174
3 changed files with 112 additions and 5 deletions

View File

@@ -30,17 +30,21 @@ import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.attribute.FileTime;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import java.util.stream.Stream;
import java.util.zip.CRC32;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -56,6 +60,7 @@ import org.springframework.util.StreamUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatIOException;
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
@@ -171,6 +176,12 @@ class JarFileTests {
assertThat(entry.getName()).isEqualTo("1.dat");
}
@Test
void getJarEntryWhenClosed() throws Exception {
this.jarFile.close();
assertThatZipFileClosedIsThrownBy(() -> this.jarFile.getJarEntry("1.dat"));
}
@Test
void getInputStream() throws Exception {
InputStream inputStream = this.jarFile.getInputStream(this.jarFile.getEntry("1.dat"));
@@ -180,23 +191,41 @@ class JarFileTests {
assertThat(inputStream.read()).isEqualTo(-1);
}
@Test
void getInputStreamWhenClosed() throws Exception {
this.jarFile.close();
assertThatZipFileClosedIsThrownBy(() -> this.jarFile.getInputStream(this.jarFile.getEntry("1.dat")));
}
@Test
void getComment() {
assertThat(this.jarFile.getComment()).isEqualTo("outer");
}
@Test
void getCommentWhenClosed() throws Exception {
this.jarFile.close();
assertThatZipFileClosedIsThrownBy(() -> this.jarFile.getComment());
}
@Test
void getName() {
assertThat(this.jarFile.getName()).isEqualTo(this.rootJarFile.getPath());
}
@Test
void getSize() throws Exception {
void size() throws Exception {
try (ZipFile zip = new ZipFile(this.rootJarFile)) {
assertThat(this.jarFile.size()).isEqualTo(zip.size());
}
}
@Test
void sizeWhenClosed() throws Exception {
this.jarFile.close();
assertThatZipFileClosedIsThrownBy(() -> this.jarFile.size());
}
@Test
void getEntryTime() throws Exception {
java.util.jar.JarFile jdkJarFile = new java.util.jar.JarFile(this.rootJarFile);
@@ -603,6 +632,41 @@ class JarFileTests {
}
}
@Test
void iterator() {
Iterator<JarEntry> iterator = this.jarFile.iterator();
List<String> names = new ArrayList<String>();
while (iterator.hasNext()) {
names.add(iterator.next().getName());
}
assertThat(names).hasSize(12).contains("1.dat");
}
@Test
void iteratorWhenClosed() throws IOException {
this.jarFile.close();
assertThatZipFileClosedIsThrownBy(() -> this.jarFile.iterator());
}
@Test
void iteratorWhenClosedLater() throws IOException {
Iterator<JarEntry> iterator = this.jarFile.iterator();
iterator.next();
this.jarFile.close();
assertThatZipFileClosedIsThrownBy(() -> iterator.hasNext());
}
@Test
void stream() {
Stream<String> stream = this.jarFile.stream().map(JarEntry::getName);
assertThat(stream).hasSize(12).contains("1.dat");
}
private void assertThatZipFileClosedIsThrownBy(ThrowingCallable throwingCallable) {
assertThatIllegalStateException().isThrownBy(throwingCallable).withMessage("zip file closed");
}
private int getJavaVersion() {
try {
Object runtimeVersion = Runtime.class.getMethod("version").invoke(null);