diff --git a/api/src/main/java/jakarta/mail/util/SharedFileInputStream.java b/api/src/main/java/jakarta/mail/util/SharedFileInputStream.java
index b0f7c6c8..8d62026b 100644
--- a/api/src/main/java/jakarta/mail/util/SharedFileInputStream.java
+++ b/api/src/main/java/jakarta/mail/util/SharedFileInputStream.java
@@ -23,6 +23,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
+import java.util.Objects;
/**
* A SharedFileInputStream
is a
@@ -426,10 +427,24 @@ public boolean markSupported() {
public void close() throws IOException {
if (in == null)
return;
- sf.close();
- sf = null;
- in = null;
- buf = null;
+ try {
+ sf.close();
+ } finally {
+ sf = null;
+ in = null;
+ buf = null;
+ /*
+ * This avoids that 'new SharedFileInputStream(file)'
+ * is GCed meanwhile #newStream is invoked, for example:
+ * new SharedFileInputStream(file).newStream(0, -1)
+ *
+ * That could be an issue if a subclass of this one invokes #close
+ * from #finalize (not a good practice anyway).
+ */
+ Objects.requireNonNull(this);
+ // TODO Replace it by the next
+// Reference.reachabilityFence(this);
+ }
}
/**
diff --git a/api/src/test/java/jakarta/mail/util/SharedFileInputStreamTest.java b/api/src/test/java/jakarta/mail/util/SharedFileInputStreamTest.java
index 01409b33..d3aae154 100644
--- a/api/src/test/java/jakarta/mail/util/SharedFileInputStreamTest.java
+++ b/api/src/test/java/jakarta/mail/util/SharedFileInputStreamTest.java
@@ -16,8 +16,7 @@
package jakarta.mail.util;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
+import org.junit.Test;
import jakarta.mail.util.SharedFileInputStream.SharedFile;
@@ -25,13 +24,11 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
-import java.lang.ref.PhantomReference;
-import java.lang.ref.Reference;
-import java.lang.ref.ReferenceQueue;
import java.lang.reflect.Field;
-import java.util.concurrent.TimeoutException;
-import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
/**
* Please note:
@@ -101,25 +98,6 @@ public void testOpenIfOneOpened() throws Exception {
assertEquals(true, isClosed(ra1));
}
- @Test
- public void testGC() throws Exception {
- File file = new File(SharedFileInputStreamTest.class.getResource("/jakarta/mail/util/sharedinputstream.txt").toURI());
- SharedFileInputStream in = new SharedFileInputStream(file);
- GCUtil gcUtil = new GCUtil(in);
- SharedFileInputStream in0 = (SharedFileInputStream) in.newStream(0, 6);
- in.close();
- in = null;
- gcUtil.waitTillGCed(1000);
- gcUtil = new GCUtil(in0);
- SharedFileInputStream in1 = (SharedFileInputStream) in0.newStream(6, 12);
- assertEquals("test0\n", new String(in0.readAllBytes()));
- in0.close();
- in0 = null;
- gcUtil.waitTillGCed(1000);
- assertEquals("test1\n", new String(in1.readAllBytes()));
- in1.close();
- }
-
private RandomAccessFile getRandomAccessFile(SharedFileInputStream in) throws Exception {
Field f1 = SharedFileInputStream.class.getDeclaredField("sf");
f1.setAccessible(true);
@@ -137,27 +115,4 @@ private boolean isClosed(RandomAccessFile rf) throws Exception {
}
}
- private static class GCUtil {
-
- private final ReferenceQueue