Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove finalize() #725

Draft
wants to merge 9 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions api/src/main/java/jakarta/mail/Folder.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2023 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -32,6 +32,7 @@
import java.util.List;
import java.util.Vector;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dead import?


/**
* Folder is an abstract class that represents a folder for mail
Expand Down Expand Up @@ -650,7 +651,15 @@ public abstract boolean delete(boolean recurse)
*/
@Override
public void close() throws MessagingException {
close(true);
try {
close(true);
} catch (IllegalStateException ise) {
if (isOpen()) {
throw ise;
}
} finally {
q.terminateQueue();
}
}

/**
Expand Down Expand Up @@ -1641,15 +1650,6 @@ private void queueEvent(MailEvent event,
q.enqueue(event, v);
}

@Override
protected void finalize() throws Throwable {
try {
q.terminateQueue();
} finally {
super.finalize();
}
}

/**
* override the default toString(), it will return the String
* from Folder.getFullName() or if that is null, it will use
Expand Down
14 changes: 1 addition & 13 deletions api/src/main/java/jakarta/mail/Service.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2023 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -632,18 +632,6 @@ protected void queueEvent(MailEvent event,
q.enqueue(event, v);
}

/**
* Stop the event dispatcher thread so the queue can be garbage collected.
*/
@Override
protected void finalize() throws Throwable {
try {
q.terminateQueue();
} finally {
super.finalize();
}
}

/**
* Package private method to allow Folder to get the Session for a Store.
*/
Expand Down
77 changes: 35 additions & 42 deletions api/src/main/java/jakarta/mail/util/SharedFileInputStream.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2023 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -75,9 +75,9 @@ public class SharedFileInputStream extends BufferedInputStream
* to a particular file so it can be closed when the
* last reference is gone.
*/
static class SharedFile {
static class SharedFile implements AutoCloseable {
private int cnt;
private RandomAccessFile in;
RandomAccessFile in;

SharedFile(String file) throws IOException {
this.in = new RandomAccessFile(file, "r");
Expand All @@ -92,19 +92,11 @@ public synchronized RandomAccessFile open() {
return in;
}

@Override
public synchronized void close() throws IOException {
if (cnt > 0 && --cnt <= 0)
in.close();
}

@Override
protected synchronized void finalize() throws Throwable {
try {
in.close();
} finally {
super.finalize();
}
}
}

private SharedFile sf;
Expand Down Expand Up @@ -265,10 +257,10 @@ private int read1(byte[] b, int off, int len) throws IOException {
int avail = count - pos;
if (avail <= 0) {
if (false) {
/* If the requested length is at least as large as the buffer, and
if there is no mark/reset activity, do not bother to copy the
bytes into the local buffer. In this way buffered streams will
cascade harmlessly. */
/* If the requested length is at least as large as the buffer, and
if there is no mark/reset activity, do not bother to copy the
bytes into the local buffer. In this way buffered streams will
cascade harmlessly. */
if (len >= buf.length && markpos < 0) {
// XXX - seek, update bufpos - how?
return in.read(b, off, len);
Expand Down Expand Up @@ -337,10 +329,10 @@ public synchronized long skip(long n) throws IOException {

if (avail <= 0) {
// If no mark position set then don't keep in buffer
/*
/*
if (markpos <0)
return in.skip(n);
*/
*/

// Fill in buffer to save bytes for reset
fill();
Expand Down Expand Up @@ -441,7 +433,17 @@ public void close() throws IOException {
sf = null;
in = null;
buf = null;
Objects.requireNonNull(this); //TODO: replace with Reference.reachabilityFence
/*
* 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);
}
}

Expand All @@ -454,7 +456,7 @@ public void close() throws IOException {
@Override
public long getPosition() {
//System.out.println("getPosition: start " + start + " pos " + pos
// + " bufpos " + bufpos + " = " + (bufpos + pos - start));
// + " bufpos " + bufpos + " = " + (bufpos + pos - start));
if (in == null)
throw new RuntimeException("Stream closed");
return bufpos + pos - start;
Expand All @@ -481,7 +483,7 @@ public synchronized InputStream newStream(long start, long end) {
throw new IllegalArgumentException("start < 0");
if (end == -1)
end = datalen;

return new SharedFileInputStream(sf,
this.start + start, end - start, bufsize);
} finally {
Expand All @@ -492,27 +494,18 @@ public synchronized InputStream newStream(long start, long end) {
// for testing...
/*
public static void main(String[] argv) throws Exception {
SharedFileInputStream is = new SharedFileInputStream(argv[0]);
java.util.Random r = new java.util.Random();
int b;
while ((b = is.read()) >= 0) {
System.out.write(b);
if (r.nextDouble() < 0.3) {
InputStream is2 = is.newStream(is.getPosition(), -1);
int b2;
while ((b2 = is2.read()) >= 0)
;
}
}
SharedFileInputStream is = new SharedFileInputStream(argv[0]);
java.util.Random r = new java.util.Random();
int b;
while ((b = is.read()) >= 0) {
System.out.write(b);
if (r.nextDouble() < 0.3) {
InputStream is2 = is.newStream(is.getPosition(), -1);
int b2;
while ((b2 = is2.read()) >= 0)
;
}
}
}
*/

/**
* Force this stream to close.
*/
@Override
protected synchronized void finalize() throws Throwable {
super.finalize();
close();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand All @@ -18,10 +18,16 @@

import org.junit.Test;

import jakarta.mail.util.SharedFileInputStream.SharedFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.lang.reflect.Field;


import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

/**
Expand Down Expand Up @@ -62,4 +68,51 @@ public void testGrandChild() throws Exception {
file.delete();
}
}

@Test
public void testCloseMultipleTimes() throws Exception {
File file = new File(SharedFileInputStreamTest.class.getResource("/jakarta/mail/util/sharedinputstream.txt").toURI());
SharedFileInputStream in = new SharedFileInputStream(file);
in.close();
in.close();
}

@Test
public void testOpenIfOneOpened() throws Exception {
File file = new File(SharedFileInputStreamTest.class.getResource("/jakarta/mail/util/sharedinputstream.txt").toURI());
SharedFileInputStream in0 = null;
SharedFileInputStream in1 = null;
try (SharedFileInputStream in = new SharedFileInputStream(file)) {
in0 = (SharedFileInputStream) in.newStream(0, 6);
in1 = (SharedFileInputStream) in.newStream(6, 12);
}
RandomAccessFile ra0 = getRandomAccessFile(in0);
RandomAccessFile ra1 = getRandomAccessFile(in1);
// It is the same instance
assertEquals(ra0, ra1);
// RandomAccessFile still be open
in1.close();
assertEquals(false, isClosed(ra1));
in0.close();
// All SharedFileInputStream are closed, so RandomAccessFile gets closed too
assertEquals(true, isClosed(ra1));
}

private RandomAccessFile getRandomAccessFile(SharedFileInputStream in) throws Exception {
Field f1 = SharedFileInputStream.class.getDeclaredField("sf");
f1.setAccessible(true);
SharedFile rin = (SharedFile) f1.get(in);
RandomAccessFile rf = rin.in;
return rf;
}

private boolean isClosed(RandomAccessFile rf) throws Exception {
try {
rf.readByte();
return false;
} catch (IOException e) {
return true;
}
}

}
10 changes: 10 additions & 0 deletions api/src/test/resources/jakarta/mail/util/sharedinputstream.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
test0
test1
test2
test3
test4
test5
test6
test7
test8
test9
1 change: 1 addition & 0 deletions copyright-exclude
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ mail/src/test/resources/jakarta/mail/internet/paramdata
mail/src/test/resources/jakarta/mail/internet/paramdatanostrict
api/src/test/resources/jakarta/mail/internet/tokenlist
api/src/test/resources/jakarta/mail/internet/addrlist
api/src/test/resources/jakarta/mail/util/sharedinputstream.txt
mail/src/test/resources/jakarta/mail/internet/MailDateFormat_old.ser
mail/src/test/resources/jakarta/mail/internet/MailDateFormat_new.ser
mail/src/test/resources/com/sun/mail/test/keystore.jks
Expand Down