From a175644c55bb0ba05b30f4e723f9a0cdae4ba5e7 Mon Sep 17 00:00:00 2001 From: lburgazzoli Date: Tue, 10 Feb 2015 15:40:27 +0100 Subject: [PATCH] CLOG-29 Bug when logging exception with the chronicle logback appender --- chronicle/pom.xml | 2 +- .../openhft/chronicle/IndexedChronicle.java | 13 ++++++- .../openhft/chronicle/VanillaChronicle.java | 37 +++++++++++-------- .../chronicle/IndexedChronicle2Test.java | 32 +++++++++++++++- .../chronicle/VanillaChronicle3Test.java | 37 ++++++++++++++++--- 5 files changed, 96 insertions(+), 25 deletions(-) diff --git a/chronicle/pom.xml b/chronicle/pom.xml index b88ad66487..8993da84c0 100755 --- a/chronicle/pom.xml +++ b/chronicle/pom.xml @@ -46,7 +46,7 @@ net.openhft lang - 6.5 + 6.5.2-SNAPSHOT net.openhft diff --git a/chronicle/src/main/java/net/openhft/chronicle/IndexedChronicle.java b/chronicle/src/main/java/net/openhft/chronicle/IndexedChronicle.java index 7b1fefa129..731ac3a1e1 100644 --- a/chronicle/src/main/java/net/openhft/chronicle/IndexedChronicle.java +++ b/chronicle/src/main/java/net/openhft/chronicle/IndexedChronicle.java @@ -22,6 +22,8 @@ import net.openhft.lang.io.NativeBytes; import net.openhft.lang.io.VanillaMappedBlocks; import net.openhft.lang.io.VanillaMappedBytes; +import net.openhft.lang.io.serialization.BytesMarshallableSerializer; +import net.openhft.lang.io.serialization.JDKObjectSerializer; import net.openhft.lang.io.serialization.impl.VanillaBytesMarshallerFactory; import net.openhft.lang.model.constraints.NotNull; import net.openhft.lang.model.constraints.Nullable; @@ -351,7 +353,16 @@ public String dumpState() { // inherited - long limitAddr; protected AbstractIndexedExcerpt() throws IOException { - super(new VanillaBytesMarshallerFactory(), NO_PAGE, NO_PAGE, null); + //super(new VanillaBytesMarshallerFactory(), NO_PAGE, NO_PAGE, null); + super( + BytesMarshallableSerializer.create( + new VanillaBytesMarshallerFactory(), + JDKObjectSerializer.INSTANCE), + NO_PAGE, + NO_PAGE, + null + ); + cacheLineSize = IndexedChronicle.this.builder.cacheLineSize(); cacheLineMask = (cacheLineSize - 1); dataBlockSize = IndexedChronicle.this.builder.dataBlockSize(); diff --git a/chronicle/src/main/java/net/openhft/chronicle/VanillaChronicle.java b/chronicle/src/main/java/net/openhft/chronicle/VanillaChronicle.java index 80cae0566c..cf229f12de 100644 --- a/chronicle/src/main/java/net/openhft/chronicle/VanillaChronicle.java +++ b/chronicle/src/main/java/net/openhft/chronicle/VanillaChronicle.java @@ -25,7 +25,9 @@ import net.openhft.lang.io.IOTools; import net.openhft.lang.io.NativeBytes; import net.openhft.lang.io.VanillaMappedBytes; -import net.openhft.lang.io.serialization.BytesMarshallerFactory; +import net.openhft.lang.io.serialization.BytesMarshallableSerializer; +import net.openhft.lang.io.serialization.JDKObjectSerializer; +import net.openhft.lang.io.serialization.ObjectSerializer; import net.openhft.lang.io.serialization.impl.VanillaBytesMarshallerFactory; import net.openhft.lang.model.constraints.NotNull; @@ -63,7 +65,7 @@ public class VanillaChronicle implements Chronicle { public static final long INDEX_DATA_OFFSET_MASK = -1L >>> -INDEX_DATA_OFFSET_BITS; private final String name; - private final ThreadLocal> marshallersCache; + private final ThreadLocal> marshallersCache; private final ThreadLocal> tailerCache; private final ThreadLocal> appenderCache; private final VanillaIndexCache indexCache; @@ -84,7 +86,7 @@ public class VanillaChronicle implements Chronicle { VanillaChronicle(ChronicleQueueBuilder.VanillaChronicleQueueBuilder builder) { this.builder = builder.clone(); - this.marshallersCache = new ThreadLocal>(); + this.marshallersCache = new ThreadLocal>(); this.tailerCache = new ThreadLocal>(); this.appenderCache = new ThreadLocal>(); this.name = builder.path().getName(); @@ -133,20 +135,23 @@ public int getEntriesForCycleBits() { return entriesForCycleBits; } - BytesMarshallerFactory acquireBMF() { - WeakReference bmfRef = marshallersCache.get(); - BytesMarshallerFactory bmf = null; - if (bmfRef != null) - bmf = bmfRef.get(); - if (bmf == null) { - bmf = createBMF(); - marshallersCache.set(new WeakReference(bmf)); + ObjectSerializer acquireSerializer() { + WeakReference serializerRef = marshallersCache.get(); + + ObjectSerializer serializer = null; + if (serializerRef != null) { + serializer = serializerRef.get(); + } + + if (serializer == null) { + serializer = BytesMarshallableSerializer.create( + new VanillaBytesMarshallerFactory(), + JDKObjectSerializer.INSTANCE); + + marshallersCache.set(new WeakReference(serializer)); } - return bmf; - } - BytesMarshallerFactory createBMF() { - return new VanillaBytesMarshallerFactory(); + return serializer; } @NotNull @@ -301,7 +306,7 @@ private abstract class AbstractVanillaExcerpt extends NativeBytes implements public AbstractVanillaExcerpt() { - super(acquireBMF(), NO_PAGE, NO_PAGE, null); + super(acquireSerializer(), NO_PAGE, NO_PAGE, null); } diff --git a/chronicle/src/test/java/net/openhft/chronicle/IndexedChronicle2Test.java b/chronicle/src/test/java/net/openhft/chronicle/IndexedChronicle2Test.java index 64246736b1..87c34c630a 100644 --- a/chronicle/src/test/java/net/openhft/chronicle/IndexedChronicle2Test.java +++ b/chronicle/src/test/java/net/openhft/chronicle/IndexedChronicle2Test.java @@ -22,8 +22,7 @@ import java.io.IOException; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; public class IndexedChronicle2Test extends IndexedChronicleTestBase { @@ -142,4 +141,33 @@ public void testIndexedChronicle_003() throws IOException { assertClean(basePath); } + + @Test + public void testExceptionSerialization() throws IOException { + final String basePath = getTestPath(); + + final Chronicle ch = ChronicleQueueBuilder.indexed(basePath).build(); + final ExcerptAppender ap = ch.createAppender(); + final ExcerptTailer tl = ch.createTailer(); + + ap.startExcerpt(); + ap.writeObject(new UnsupportedOperationException("UOE")); + ap.finish(); + ap.close(); + + assertTrue(tl.nextIndex()); + Object obj = tl.readObject(); + assertNotNull(obj); + assertTrue(obj instanceof Throwable); + assertTrue(obj instanceof UnsupportedOperationException); + + tl.finish(); + + assertFalse(tl.nextIndex()); + + tl.close(); + ch.close(); + + assertClean(basePath); + } } diff --git a/chronicle/src/test/java/net/openhft/chronicle/VanillaChronicle3Test.java b/chronicle/src/test/java/net/openhft/chronicle/VanillaChronicle3Test.java index 02e27f2979..fad9a2a2a0 100644 --- a/chronicle/src/test/java/net/openhft/chronicle/VanillaChronicle3Test.java +++ b/chronicle/src/test/java/net/openhft/chronicle/VanillaChronicle3Test.java @@ -25,19 +25,46 @@ import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; -import java.util.ArrayList; import java.util.Date; import java.util.HashSet; import java.util.Set; -import java.util.concurrent.atomic.AtomicLong; import static org.junit.Assert.*; -import static org.junit.Assert.assertEquals; public class VanillaChronicle3Test extends VanillaChronicleTestBase { @Test - public void testFinishAfterClose() throws IOException { + public void testExceptionSerialization() throws IOException { + final String basePath = getTestPath(); + + final Chronicle ch = ChronicleQueueBuilder.vanilla(basePath).build(); + final ExcerptAppender ap = ch.createAppender(); + final ExcerptTailer tl = ch.createTailer(); + + ap.startExcerpt(); + ap.writeObject(new UnsupportedOperationException("UOE")); + ap.finish(); + ap.close(); + + assertTrue(tl.nextIndex()); + Object obj = tl.readObject(); + assertNotNull(obj); + assertTrue(obj instanceof Throwable); + assertTrue(obj instanceof UnsupportedOperationException); + + tl.finish(); + + assertFalse(tl.nextIndex()); + + tl.close(); + ch.close(); + ch.clear(); + + assertFalse(new File(basePath).exists()); + } + + @Test + public void testVanillaFinishAfterClose() throws IOException { final String basePath = getTestPath(); final VanillaChronicle chronicle = (VanillaChronicle)ChronicleQueueBuilder.vanilla(basePath).build(); final ExcerptAppender appender = chronicle.createAppender(); @@ -137,7 +164,7 @@ public void testJira92() throws Exception { } @Test - public void testCheckedVanillaExcerpt_001() throws IOException { + public void testCheckedVanillaExcerpt() throws IOException { final String basePath = getTestPath(); final VanillaChronicle chronicle = (VanillaChronicle)ChronicleQueueBuilder.vanilla(basePath) .useCheckedExcerpt(true)