From 6b23d6c1801b570eeac9943ba0757956bdafe12a Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Thu, 31 Aug 2023 09:53:27 +0100 Subject: [PATCH 1/5] support IOContext closing in GeneratorBase --- .../jackson/core/base/GeneratorBase.java | 28 ++++++++++++++++--- .../jackson/core/json/JsonGeneratorImpl.java | 8 ------ 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/fasterxml/jackson/core/base/GeneratorBase.java b/src/main/java/com/fasterxml/jackson/core/base/GeneratorBase.java index 74ee07afaf..b8667ccd38 100644 --- a/src/main/java/com/fasterxml/jackson/core/base/GeneratorBase.java +++ b/src/main/java/com/fasterxml/jackson/core/base/GeneratorBase.java @@ -1,6 +1,7 @@ package com.fasterxml.jackson.core.base; import com.fasterxml.jackson.core.*; +import com.fasterxml.jackson.core.io.IOContext; import com.fasterxml.jackson.core.json.DupDetector; import com.fasterxml.jackson.core.json.JsonWriteContext; import com.fasterxml.jackson.core.json.PackageVersion; @@ -69,6 +70,8 @@ public abstract class GeneratorBase extends JsonGenerator */ protected int _features; + protected IOContext _ioContext; + /** * Flag set to indicate that implicit conversion from number * to JSON String is needed (as per @@ -101,11 +104,18 @@ public abstract class GeneratorBase extends JsonGenerator /********************************************************** */ - @SuppressWarnings("deprecation") + @Deprecated // since 2.16 protected GeneratorBase(int features, ObjectCodec codec) { + this(features, codec, (IOContext) null); + } + + // @since 2.16 + @SuppressWarnings("deprecation") + protected GeneratorBase(int features, ObjectCodec codec, IOContext ioContext) { super(); _features = features; _objectCodec = codec; + _ioContext = ioContext; DupDetector dups = Feature.STRICT_DUPLICATE_DETECTION.enabledIn(features) ? DupDetector.rootDetector(this) : null; _writeContext = JsonWriteContext.createRootContext(dups); @@ -113,12 +123,17 @@ protected GeneratorBase(int features, ObjectCodec codec) { } // @since 2.5 - @SuppressWarnings("deprecation") + @Deprecated // since 2.16 protected GeneratorBase(int features, ObjectCodec codec, JsonWriteContext ctxt) { + this(features, codec, null, ctxt); + } + + // @since 2.16 + protected GeneratorBase(int features, ObjectCodec codec, IOContext ioContext, JsonWriteContext jsonWriteContext) { super(); _features = features; _objectCodec = codec; - _writeContext = ctxt; + _writeContext = jsonWriteContext; _cfgNumbersAsStrings = Feature.WRITE_NUMBERS_AS_STRINGS.enabledIn(features); } @@ -413,7 +428,12 @@ public void writeTree(TreeNode rootNode) throws IOException { */ @Override public abstract void flush() throws IOException; - @Override public void close() throws IOException { _closed = true; } + @Override public void close() throws IOException { + if (!_closed) { + _closed = true; + _ioContext.close(); + } + } @Override public boolean isClosed() { return _closed; } /* diff --git a/src/main/java/com/fasterxml/jackson/core/json/JsonGeneratorImpl.java b/src/main/java/com/fasterxml/jackson/core/json/JsonGeneratorImpl.java index ad2eaa3fa0..ea9b452188 100644 --- a/src/main/java/com/fasterxml/jackson/core/json/JsonGeneratorImpl.java +++ b/src/main/java/com/fasterxml/jackson/core/json/JsonGeneratorImpl.java @@ -120,14 +120,6 @@ public abstract class JsonGeneratorImpl extends GeneratorBase /********************************************************** */ - @Override - public void close() throws IOException { - if (!isClosed()) { - super.close(); - _ioContext.close(); - } - } - @SuppressWarnings("deprecation") public JsonGeneratorImpl(IOContext ctxt, int features, ObjectCodec codec) { From 070d7fa92acf148e9a5c44af768a16ae0a8546fc Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Thu, 31 Aug 2023 09:58:22 +0100 Subject: [PATCH 2/5] Update GeneratorBase.java --- .../java/com/fasterxml/jackson/core/base/GeneratorBase.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/fasterxml/jackson/core/base/GeneratorBase.java b/src/main/java/com/fasterxml/jackson/core/base/GeneratorBase.java index b8667ccd38..f97bbd2cea 100644 --- a/src/main/java/com/fasterxml/jackson/core/base/GeneratorBase.java +++ b/src/main/java/com/fasterxml/jackson/core/base/GeneratorBase.java @@ -133,6 +133,7 @@ protected GeneratorBase(int features, ObjectCodec codec, IOContext ioContext, Js super(); _features = features; _objectCodec = codec; + _ioContext = ioContext; _writeContext = jsonWriteContext; _cfgNumbersAsStrings = Feature.WRITE_NUMBERS_AS_STRINGS.enabledIn(features); } @@ -430,8 +431,10 @@ public void writeTree(TreeNode rootNode) throws IOException { @Override public abstract void flush() throws IOException; @Override public void close() throws IOException { if (!_closed) { + if (_ioContext != null) { + _ioContext.close(); + } _closed = true; - _ioContext.close(); } } @Override public boolean isClosed() { return _closed; } From 04a8d07be82ac872f91ea0cfca2fdfc6c0a39a82 Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Thu, 31 Aug 2023 10:14:22 +0100 Subject: [PATCH 3/5] Update GeneratorBase.java --- src/main/java/com/fasterxml/jackson/core/base/GeneratorBase.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/fasterxml/jackson/core/base/GeneratorBase.java b/src/main/java/com/fasterxml/jackson/core/base/GeneratorBase.java index f97bbd2cea..26d5e88da4 100644 --- a/src/main/java/com/fasterxml/jackson/core/base/GeneratorBase.java +++ b/src/main/java/com/fasterxml/jackson/core/base/GeneratorBase.java @@ -129,6 +129,7 @@ protected GeneratorBase(int features, ObjectCodec codec, JsonWriteContext ctxt) } // @since 2.16 + @SuppressWarnings("deprecation") protected GeneratorBase(int features, ObjectCodec codec, IOContext ioContext, JsonWriteContext jsonWriteContext) { super(); _features = features; From 09d0d9e21676c5bb35f4601a328e47cc2c95fd1f Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Thu, 31 Aug 2023 11:35:44 +0100 Subject: [PATCH 4/5] fix test --- .../jackson/core/base/GeneratorBase.java | 3 ++- .../jackson/core/json/JsonGeneratorImpl.java | 5 +---- .../jackson/core/io/BufferRecyclerPoolTest.java | 16 +++++++--------- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/fasterxml/jackson/core/base/GeneratorBase.java b/src/main/java/com/fasterxml/jackson/core/base/GeneratorBase.java index 26d5e88da4..75b87d2539 100644 --- a/src/main/java/com/fasterxml/jackson/core/base/GeneratorBase.java +++ b/src/main/java/com/fasterxml/jackson/core/base/GeneratorBase.java @@ -70,7 +70,8 @@ public abstract class GeneratorBase extends JsonGenerator */ protected int _features; - protected IOContext _ioContext; + // since 2.16 + protected final IOContext _ioContext; /** * Flag set to indicate that implicit conversion from number diff --git a/src/main/java/com/fasterxml/jackson/core/json/JsonGeneratorImpl.java b/src/main/java/com/fasterxml/jackson/core/json/JsonGeneratorImpl.java index ea9b452188..3c8a2923d2 100644 --- a/src/main/java/com/fasterxml/jackson/core/json/JsonGeneratorImpl.java +++ b/src/main/java/com/fasterxml/jackson/core/json/JsonGeneratorImpl.java @@ -45,8 +45,6 @@ public abstract class JsonGeneratorImpl extends GeneratorBase /********************************************************** */ - protected final IOContext _ioContext; - /** * @since 2.16 */ @@ -123,8 +121,7 @@ public abstract class JsonGeneratorImpl extends GeneratorBase @SuppressWarnings("deprecation") public JsonGeneratorImpl(IOContext ctxt, int features, ObjectCodec codec) { - super(features, codec); - _ioContext = ctxt; + super(features, codec, ctxt); _streamWriteConstraints = ctxt.streamWriteConstraints(); if (Feature.ESCAPE_NON_ASCII.enabledIn(features)) { // inlined `setHighestNonEscapedChar()` diff --git a/src/test/java/com/fasterxml/jackson/core/io/BufferRecyclerPoolTest.java b/src/test/java/com/fasterxml/jackson/core/io/BufferRecyclerPoolTest.java index 2381f520b1..1436f570fa 100644 --- a/src/test/java/com/fasterxml/jackson/core/io/BufferRecyclerPoolTest.java +++ b/src/test/java/com/fasterxml/jackson/core/io/BufferRecyclerPoolTest.java @@ -12,28 +12,28 @@ public class BufferRecyclerPoolTest extends BaseTest { - public void testNoOp() { + public void testNoOp() throws IOException { // no-op pool doesn't actually pool anything, so avoid checking it checkBufferRecyclerPoolImpl(BufferRecyclerPool.NonRecyclingPool.shared(), false); } - public void testThreadLocal() { + public void testThreadLocal() throws IOException { checkBufferRecyclerPoolImpl(BufferRecyclerPool.ThreadLocalPool.shared(), true); } - public void testLockFree() { + public void testLockFree() throws IOException { checkBufferRecyclerPoolImpl(BufferRecyclerPool.LockFreePool.nonShared(), true); } - public void testConcurrentDequeue() { + public void testConcurrentDequeue() throws IOException { checkBufferRecyclerPoolImpl(BufferRecyclerPool.ConcurrentDequePool.nonShared(), true); } - public void testBounded() { + public void testBounded() throws IOException { checkBufferRecyclerPoolImpl(BufferRecyclerPool.BoundedPool.nonShared(1), true); } - private void checkBufferRecyclerPoolImpl(BufferRecyclerPool pool, boolean checkPooledResource) { + private void checkBufferRecyclerPoolImpl(BufferRecyclerPool pool, boolean checkPooledResource) throws IOException { JsonFactory jsonFactory = JsonFactory.builder() .bufferRecyclerPool(pool) .build(); @@ -50,14 +50,12 @@ private void checkBufferRecyclerPoolImpl(BufferRecyclerPool pool, boolean checkP } } - protected final BufferRecycler write(Object value, JsonFactory jsonFactory, int expectedSize) { + private BufferRecycler write(Object value, JsonFactory jsonFactory, int expectedSize) throws IOException { BufferRecycler bufferRecycler; NopOutputStream out = new NopOutputStream(); try (JsonGenerator gen = jsonFactory.createGenerator(out)) { bufferRecycler = ((JsonGeneratorImpl) gen).ioContext()._bufferRecycler; gen.writeObject(value); - } catch (IOException e) { - throw new RuntimeException(e); } assertEquals(expectedSize, out.size); return bufferRecycler; From 6f972ff70db72b29cf1b023c614b3088f727e94a Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Thu, 31 Aug 2023 16:38:50 +0100 Subject: [PATCH 5/5] Update BufferRecyclerPoolTest.java --- .../core/io/BufferRecyclerPoolTest.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/test/java/com/fasterxml/jackson/core/io/BufferRecyclerPoolTest.java b/src/test/java/com/fasterxml/jackson/core/io/BufferRecyclerPoolTest.java index 1436f570fa..9132e06e1f 100644 --- a/src/test/java/com/fasterxml/jackson/core/io/BufferRecyclerPoolTest.java +++ b/src/test/java/com/fasterxml/jackson/core/io/BufferRecyclerPoolTest.java @@ -12,28 +12,28 @@ public class BufferRecyclerPoolTest extends BaseTest { - public void testNoOp() throws IOException { + public void testNoOp() throws Exception { // no-op pool doesn't actually pool anything, so avoid checking it checkBufferRecyclerPoolImpl(BufferRecyclerPool.NonRecyclingPool.shared(), false); } - public void testThreadLocal() throws IOException { + public void testThreadLocal() throws Exception { checkBufferRecyclerPoolImpl(BufferRecyclerPool.ThreadLocalPool.shared(), true); } - public void testLockFree() throws IOException { + public void testLockFree() throws Exception { checkBufferRecyclerPoolImpl(BufferRecyclerPool.LockFreePool.nonShared(), true); } - public void testConcurrentDequeue() throws IOException { + public void testConcurrentDequeue() throws Exception { checkBufferRecyclerPoolImpl(BufferRecyclerPool.ConcurrentDequePool.nonShared(), true); } - public void testBounded() throws IOException { + public void testBounded() throws Exception { checkBufferRecyclerPoolImpl(BufferRecyclerPool.BoundedPool.nonShared(1), true); } - private void checkBufferRecyclerPoolImpl(BufferRecyclerPool pool, boolean checkPooledResource) throws IOException { + private void checkBufferRecyclerPoolImpl(BufferRecyclerPool pool, boolean checkPooledResource) throws Exception { JsonFactory jsonFactory = JsonFactory.builder() .bufferRecyclerPool(pool) .build(); @@ -50,7 +50,7 @@ private void checkBufferRecyclerPoolImpl(BufferRecyclerPool pool, boolean checkP } } - private BufferRecycler write(Object value, JsonFactory jsonFactory, int expectedSize) throws IOException { + private BufferRecycler write(Object value, JsonFactory jsonFactory, int expectedSize) throws Exception { BufferRecycler bufferRecycler; NopOutputStream out = new NopOutputStream(); try (JsonGenerator gen = jsonFactory.createGenerator(out)) { @@ -61,10 +61,10 @@ private BufferRecycler write(Object value, JsonFactory jsonFactory, int expected return bufferRecycler; } - public class NopOutputStream extends OutputStream { + private static class NopOutputStream extends OutputStream { protected int size = 0; - public NopOutputStream() { } + NopOutputStream() { } @Override public void write(int b) throws IOException { ++size; }