Drop finalize() Now it is solely embedders responisbility to close things that hold native resources. No more "safety net". Consider "try-with-resources". For longer lasting items (e.g. native PreparedDictionary) use Cleaner as a last resort. PiperOrigin-RevId: 807135470
diff --git a/java/org/brotli/wrapper/dec/Decoder.java b/java/org/brotli/wrapper/dec/Decoder.java index a2228d1..24c7a27 100644 --- a/java/org/brotli/wrapper/dec/Decoder.java +++ b/java/org/brotli/wrapper/dec/Decoder.java
@@ -15,7 +15,7 @@ /** * Base class for InputStream / Channel implementations. */ -public class Decoder { +public class Decoder implements AutoCloseable { private static final ByteBuffer EMPTY_BUFFER = ByteBuffer.allocate(0); private final ReadableByteChannel source; private final DecoderJNI.Wrapper decoder; @@ -129,7 +129,8 @@ return limit; } - void close() throws IOException { + @Override + public void close() throws IOException { if (closed) { return; } @@ -140,9 +141,9 @@ /** Decodes the given data buffer starting at offset till length. */ public static byte[] decompress(byte[] data, int offset, int length) throws IOException { - DecoderJNI.Wrapper decoder = new DecoderJNI.Wrapper(length); - ArrayList<byte[]> output = new ArrayList<byte[]>(); + ArrayList<byte[]> output = new ArrayList<>(); int totalOutputSize = 0; + DecoderJNI.Wrapper decoder = new DecoderJNI.Wrapper(length); try { decoder.getInputBuffer().put(data, offset, length); decoder.push(length);
diff --git a/java/org/brotli/wrapper/dec/DecoderJNI.java b/java/org/brotli/wrapper/dec/DecoderJNI.java index 7b8dace..726a6d6 100644 --- a/java/org/brotli/wrapper/dec/DecoderJNI.java +++ b/java/org/brotli/wrapper/dec/DecoderJNI.java
@@ -122,14 +122,5 @@ nativeDestroy(context); context[0] = 0; } - - @Override - protected void finalize() throws Throwable { - if (context[0] != 0) { - /* TODO(eustas): log resource leak? */ - destroy(); - } - super.finalize(); - } } }
diff --git a/java/org/brotli/wrapper/enc/BrotliOutputStream.java b/java/org/brotli/wrapper/enc/BrotliOutputStream.java index 09cbd5a..10595d1 100644 --- a/java/org/brotli/wrapper/enc/BrotliOutputStream.java +++ b/java/org/brotli/wrapper/enc/BrotliOutputStream.java
@@ -6,10 +6,10 @@ package org.brotli.wrapper.enc; -import org.brotli.enc.PreparedDictionary; import java.io.IOException; import java.io.OutputStream; import java.nio.channels.Channels; +import org.brotli.enc.PreparedDictionary; /** * Output stream that wraps native brotli encoder.
diff --git a/java/org/brotli/wrapper/enc/Encoder.java b/java/org/brotli/wrapper/enc/Encoder.java index 4071c9c..ab0e5aa 100644 --- a/java/org/brotli/wrapper/enc/Encoder.java +++ b/java/org/brotli/wrapper/enc/Encoder.java
@@ -17,7 +17,7 @@ /** * Base class for OutputStream / Channel implementations. */ -public class Encoder { +public class Encoder implements AutoCloseable { private final WritableByteChannel destination; private final List<PreparedDictionary> dictionaries; private final EncoderJNI.Wrapper encoder; @@ -65,12 +65,6 @@ public Parameters() { } - private Parameters(Parameters other) { - this.quality = other.quality; - this.lgwin = other.lgwin; - this.mode = other.mode; - } - /** * Setup encoder quality. * @@ -199,7 +193,8 @@ encode(EncoderJNI.Operation.FLUSH); } - void close() throws IOException { + @Override + public void close() throws IOException { if (closed) { return; } @@ -221,10 +216,10 @@ return empty; } /* data.length > 0 */ + ArrayList<byte[]> output = new ArrayList<>(); + int totalOutputSize = 0; EncoderJNI.Wrapper encoder = new EncoderJNI.Wrapper(length, params.quality, params.lgwin, params.mode); - ArrayList<byte[]> output = new ArrayList<byte[]>(); - int totalOutputSize = 0; try { encoder.getInputBuffer().put(data, offset, length); encoder.push(EncoderJNI.Operation.FINISH, length);
diff --git a/java/org/brotli/wrapper/enc/EncoderJNI.java b/java/org/brotli/wrapper/enc/EncoderJNI.java index b8e32d2..2f7ef30 100644 --- a/java/org/brotli/wrapper/enc/EncoderJNI.java +++ b/java/org/brotli/wrapper/enc/EncoderJNI.java
@@ -6,9 +6,9 @@ package org.brotli.wrapper.enc; -import org.brotli.enc.PreparedDictionary; import java.io.IOException; import java.nio.ByteBuffer; +import org.brotli.enc.PreparedDictionary; /** * JNI wrapper for brotli encoder. @@ -28,7 +28,7 @@ FINISH } - private static class PreparedDictionaryImpl implements PreparedDictionary { + private static class PreparedDictionaryImpl implements AutoCloseable, PreparedDictionary { private ByteBuffer data; /** Reference to (non-copied) LZ data. */ private ByteBuffer rawData; @@ -43,15 +43,11 @@ } @Override - protected void finalize() throws Throwable { - try { - ByteBuffer data = this.data; - this.data = null; - this.rawData = null; - nativeDestroyDictionary(data); - } finally { - super.finalize(); - } + public void close() { + ByteBuffer data = this.data; + this.data = null; + this.rawData = null; + nativeDestroyDictionary(data); } } @@ -168,14 +164,5 @@ nativeDestroy(context); context[0] = 0; } - - @Override - protected void finalize() throws Throwable { - if (context[0] != 0) { - /* TODO(eustas): log resource leak? */ - destroy(); - } - super.finalize(); - } } }