8212129: Remove finalize methods from java.util.zip.ZipFIle/Inflator/Deflator

Reviewed-by: rriggs, sherman, alanb, clanger
This commit is contained in:
Lance Andersen 2018-10-26 14:02:31 -04:00
parent 0108d754d7
commit a655e6b52b
5 changed files with 4 additions and 396 deletions

View file

@ -89,13 +89,6 @@ import sun.nio.ch.DirectBuffer;
* to perform cleanup should be modified to use alternative cleanup mechanisms such
* as {@link java.lang.ref.Cleaner} and remove the overriding {@code finalize} method.
*
* @implSpec
* If this {@code Deflater} has been subclassed and the {@code end} method has been
* overridden, the {@code end} method will be called by the finalization when the
* deflater is unreachable. But the subclasses should not depend on this specific
* implementation; the finalization is not reliable and the {@code finalize} method
* is deprecated to be removed.
*
* @see Inflater
* @author David Connelly
* @since 1.1
@ -204,8 +197,8 @@ public class Deflater {
public Deflater(int level, boolean nowrap) {
this.level = level;
this.strategy = DEFAULT_STRATEGY;
this.zsRef = DeflaterZStreamRef.get(this,
init(level, DEFAULT_STRATEGY, nowrap));
this.zsRef = new DeflaterZStreamRef(this,
init(level, DEFAULT_STRATEGY, nowrap));
}
/**
@ -901,21 +894,6 @@ public class Deflater {
}
}
/**
* Closes the compressor when garbage is collected.
*
* @deprecated The {@code finalize} method has been deprecated and will be
* removed. It is implemented as a no-op. Subclasses that override
* {@code finalize} in order to perform cleanup should be modified to use
* alternative cleanup mechanisms and to remove the overriding {@code finalize}
* method. The recommended cleanup for compressor is to explicitly call
* {@code end} method when it is no longer in use. If the {@code end} is
* not invoked explicitly the resource of the compressor will be released
* when the instance becomes unreachable.
*/
@Deprecated(since="9", forRemoval=true)
protected void finalize() {}
private void ensureOpen() {
assert Thread.holdsLock(zsRef);
if (zsRef.address() == 0)
@ -977,43 +955,5 @@ public class Deflater {
}
}
/*
* If {@code Deflater} has been subclassed and the {@code end} method is
* overridden, uses {@code finalizer} mechanism for resource cleanup. So
* {@code end} method can be called when the {@code Deflater} is unreachable.
* This mechanism will be removed when the {@code finalize} method is
* removed from {@code Deflater}.
*/
static DeflaterZStreamRef get(Deflater owner, long addr) {
Class<?> clz = owner.getClass();
while (clz != Deflater.class) {
try {
clz.getDeclaredMethod("end");
return new FinalizableZStreamRef(owner, addr);
} catch (NoSuchMethodException nsme) {}
clz = clz.getSuperclass();
}
return new DeflaterZStreamRef(owner, addr);
}
private static class FinalizableZStreamRef extends DeflaterZStreamRef {
final Deflater owner;
FinalizableZStreamRef (Deflater owner, long addr) {
super(null, addr);
this.owner = owner;
}
@Override
void clean() {
run();
}
@Override
@SuppressWarnings("deprecation")
protected void finalize() {
owner.end();
}
}
}
}

View file

@ -87,13 +87,6 @@ import sun.nio.ch.DirectBuffer;
* to perform cleanup should be modified to use alternative cleanup mechanisms such
* as {@link java.lang.ref.Cleaner} and remove the overriding {@code finalize} method.
*
* @implSpec
* If this {@code Inflater} has been subclassed and the {@code end} method has been
* overridden, the {@code end} method will be called by the finalization when the
* inflater is unreachable. But the subclasses should not depend on this specific
* implementation; the finalization is not reliable and the {@code finalize} method
* is deprecated to be removed.
*
* @see Deflater
* @author David Connelly
* @since 1.1
@ -135,7 +128,7 @@ public class Inflater {
* @param nowrap if true then support GZIP compatible compression
*/
public Inflater(boolean nowrap) {
this.zsRef = InflaterZStreamRef.get(this, init(nowrap));
this.zsRef = new InflaterZStreamRef(this, init(nowrap));
}
/**
@ -714,25 +707,6 @@ public class Inflater {
}
}
/**
* Closes the decompressor when garbage is collected.
*
* @implSpec
* If this {@code Inflater} has been subclassed and the {@code end} method
* has been overridden, the {@code end} method will be called when the
* inflater is unreachable.
*
* @deprecated The {@code finalize} method has been deprecated and will be
* removed. It is implemented as a no-op. Subclasses that override
* {@code finalize} in order to perform cleanup should be modified to use
* alternative cleanup mechanisms and remove the overriding {@code finalize}
* method. The recommended cleanup for compressor is to explicitly call
* {@code end} method when it is no longer in use. If the {@code end} is
* not invoked explicitly the resource of the compressor will be released
* when the instance becomes unreachable,
*/
@Deprecated(since="9", forRemoval=true)
protected void finalize() {}
private void ensureOpen () {
assert Thread.holdsLock(zsRef);
@ -792,43 +766,5 @@ public class Inflater {
}
}
/*
* If {@code Inflater} has been subclassed and the {@code end} method is
* overridden, uses {@code finalizer} mechanism for resource cleanup. So
* {@code end} method can be called when the {@code Inflater} is unreachable.
* This mechanism will be removed when the {@code finalize} method is
* removed from {@code Inflater}.
*/
static InflaterZStreamRef get(Inflater owner, long addr) {
Class<?> clz = owner.getClass();
while (clz != Inflater.class) {
try {
clz.getDeclaredMethod("end");
return new FinalizableZStreamRef(owner, addr);
} catch (NoSuchMethodException nsme) {}
clz = clz.getSuperclass();
}
return new InflaterZStreamRef(owner, addr);
}
private static class FinalizableZStreamRef extends InflaterZStreamRef {
final Inflater owner;
FinalizableZStreamRef(Inflater owner, long addr) {
super(null, addr);
this.owner = owner;
}
@Override
void clean() {
run();
}
@Override
@SuppressWarnings("deprecation")
protected void finalize() {
owner.end();
}
}
}
}

View file

@ -56,7 +56,6 @@ import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.IntFunction;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import jdk.internal.misc.JavaLangAccess;
@ -85,13 +84,6 @@ import static java.util.zip.ZipUtils.*;
* cleanup mechanisms such as {@link java.lang.ref.Cleaner} and remove the overriding
* {@code finalize} method.
*
* @implSpec
* If this {@code ZipFile} has been subclassed and the {@code close} method has
* been overridden, the {@code close} method will be called by the finalization
* when {@code ZipFile} is unreachable. But the subclasses should not depend on
* this specific implementation; the finalization is not reliable and the
* {@code finalize} method is deprecated to be removed.
*
* @author David Connelly
* @since 1.1
*/
@ -244,7 +236,7 @@ class ZipFile implements ZipConstants, Closeable {
this.name = name;
long t0 = System.nanoTime();
this.res = CleanableResource.get(this, file, mode);
this.res = new CleanableResource(this, file, mode);
PerfCounter.getZipFileOpenTime().addElapsedTimeFrom(t0);
PerfCounter.getZipFileCount().increment();
@ -825,44 +817,6 @@ class ZipFile implements ZipConstants, Closeable {
this.zsrc = Source.get(file, (mode & OPEN_DELETE) != 0);
}
/*
* If {@code ZipFile} has been subclassed and the {@code close} method is
* overridden, uses the {@code finalizer} mechanism for resource cleanup.
* So {@code close} method can be called when the the {@code ZipFile} is
* unreachable. This mechanism will be removed when {@code finalize} method
* is removed from {@code ZipFile}.
*/
static CleanableResource get(ZipFile zf, File file, int mode)
throws IOException {
Class<?> clz = zf.getClass();
while (clz != ZipFile.class && clz != JarFile.class) {
if (JLA.getDeclaredPublicMethods(clz, "close").size() != 0) {
return new FinalizableResource(zf, file, mode);
}
clz = clz.getSuperclass();
}
return new CleanableResource(zf, file, mode);
}
static class FinalizableResource extends CleanableResource {
ZipFile zf;
FinalizableResource(ZipFile zf, File file, int mode)
throws IOException {
super(file, mode);
this.zf = zf;
}
@Override
void clean() {
run();
}
@Override
@SuppressWarnings("deprecation")
protected void finalize() throws IOException {
zf.close();
}
}
}
/**
@ -891,25 +845,6 @@ class ZipFile implements ZipConstants, Closeable {
}
}
/**
* Ensures that the system resources held by this ZipFile object are
* released when there are no more references to it.
*
* @deprecated The {@code finalize} method has been deprecated and will be
* removed. It is implemented as a no-op. Subclasses that override
* {@code finalize} in order to perform cleanup should be modified to
* use alternative cleanup mechanisms and to remove the overriding
* {@code finalize} method. The recommended cleanup for ZipFile object
* is to explicitly invoke {@code close} method when it is no longer in
* use, or use try-with-resources. If the {@code close} is not invoked
* explicitly the resources held by this object will be released when
* the instance becomes unreachable.
*
* @throws IOException if an I/O error has occurred
*/
@Deprecated(since="9", forRemoval=true)
protected void finalize() throws IOException {}
private void ensureOpen() {
if (closeRequested) {
throw new IllegalStateException("zip file closed");