Chronicle-Logger icon indicating copy to clipboard operation
Chronicle-Logger copied to clipboard

Infinite loop when mysql-connector-java or netty is on the classpath

Open Jire opened this issue 5 years ago • 2 comments

An infinite loop occurs when trying to use Chronicle-Logger when mysql-connector-java is on the classpath and also netty.

[main] WARN net.openhft.chronicle.wire.WireMarshaller - Found this$0, in class com.mysql.cj.PerConnectionLRUFactory$PerConnectionLRU which will be ignored!
java.lang.StackOverflowError
	at net.openhft.chronicle.bytes.NativeBytesStore.addressForWrite(NativeBytesStore.java:544)
	at net.openhft.chronicle.bytes.AbstractBytes.addressForWritePosition(AbstractBytes.java:968)
	at net.openhft.chronicle.bytes.MappedBytes.append8bit0(MappedBytes.java:647)
	at net.openhft.chronicle.bytes.MappedBytes.append8bit(MappedBytes.java:620)
	at net.openhft.chronicle.bytes.MappedBytes.append8bit(MappedBytes.java:46)
	at net.openhft.chronicle.bytes.ByteStringAppender.append8bit(ByteStringAppender.java:249)
	at net.openhft.chronicle.wire.BinaryWire.writeField0(BinaryWire.java:1170)
	at net.openhft.chronicle.wire.BinaryWire.writeField(BinaryWire.java:1154)
	at net.openhft.chronicle.wire.BinaryWire.write(BinaryWire.java:1113)
	at net.openhft.chronicle.wire.WireMarshaller$FieldAccess.write(WireMarshaller.java:509)
	at net.openhft.chronicle.wire.WireMarshaller.writeMarshallable(WireMarshaller.java:197)
	at net.openhft.chronicle.wire.Wires.writeMarshallable(Wires.java:329)
	at net.openhft.chronicle.wire.BinaryWire$FixedBinaryValueOut.marshallable(BinaryWire.java:1879)
	at net.openhft.chronicle.wire.ValueOut.typedMarshallable(ValueOut.java:451)
	at net.openhft.chronicle.wire.ValueOut.object(ValueOut.java:671)
	at net.openhft.chronicle.wire.ValueOut.object(ValueOut.java:516)
	at net.openhft.chronicle.wire.WireMarshaller$ObjectFieldAccess.getValue(WireMarshaller.java:663)
	at net.openhft.chronicle.wire.WireMarshaller$FieldAccess.write(WireMarshaller.java:516)
	at net.openhft.chronicle.wire.WireMarshaller.writeMarshallable(WireMarshaller.java:197)
	at net.openhft.chronicle.wire.Wires.writeMarshallable(Wires.java:329)
	at net.openhft.chronicle.wire.ValueOut.lambda$object$20(ValueOut.java:689)
	at net.openhft.chronicle.wire.BinaryWire$FixedBinaryValueOut.marshallable(BinaryWire.java:1840)
	at net.openhft.chronicle.wire.ValueOut.object(ValueOut.java:689)
	at net.openhft.chronicle.wire.ValueOut.object(ValueOut.java:516)
	at net.openhft.chronicle.wire.WireMarshaller$ObjectFieldAccess.getValue(WireMarshaller.java:663)
	at net.openhft.chronicle.wire.WireMarshaller$FieldAccess.write(WireMarshaller.java:516)
	at net.openhft.chronicle.wire.WireMarshaller.writeMarshallable(WireMarshaller.java:197)
	at net.openhft.chronicle.wire.Wires.writeMarshallable(Wires.java:329)
	at net.openhft.chronicle.wire.BinaryWire$FixedBinaryValueOut.marshallable(BinaryWire.java:1879)
	at net.openhft.chronicle.wire.ValueOut.typedMarshallable(ValueOut.java:451)
	at net.openhft.chronicle.wire.ValueOut.object(ValueOut.java:671)
	at net.openhft.chronicle.wire.ValueOut.object(ValueOut.java:516)
	at net.openhft.chronicle.wire.WireMarshaller$ObjectFieldAccess.getValue(WireMarshaller.java:663)
	at net.openhft.chronicle.wire.WireMarshaller$FieldAccess.write(WireMarshaller.java:516)
	at net.openhft.chronicle.wire.WireMarshaller.writeMarshallable(WireMarshaller.java:197)
	at net.openhft.chronicle.wire.Wires.writeMarshallable(Wires.java:329)
	at net.openhft.chronicle.wire.ValueOut.lambda$object$20(ValueOut.java:689)
	at net.openhft.chronicle.wire.BinaryWire$FixedBinaryValueOut.marshallable(BinaryWire.java:1840)
	at net.openhft.chronicle.wire.ValueOut.object(ValueOut.java:689)
	at net.openhft.chronicle.wire.ValueOut.object(ValueOut.java:516)

These are my full Gradle dependencies:

dependencies {
	implementation group: 'net.openhft', name: 'chronicle-logger', version: '4.21ea1', ext: 'pom'
	implementation group: 'net.openhft', name: 'chronicle-logger-slf4j', version: '4.21ea1'
	implementation group: 'net.openhft', name: 'chronicle-logger-core', version: '4.21ea1'
	implementation 'net.openhft:chronicle-logger-tools:4.20ea2'
	
	implementation group: 'commons-io', name: 'commons-io', version: '2.8.0'
	implementation group: 'mysql', name: 'mysql-connector-java', version: '8.0.22'
	implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.11'
	implementation group: 'com.zaxxer', name: 'HikariCP', version: '3.4.5'
	implementation group: 'org.slf4j', name: 'slf4j-api', version: '1.7.30'
	implementation group: 'io.netty', name: 'netty-all', version: '4.1.53.Final'
	implementation group: 'org.jctools', name: 'jctools-core', version: '3.1.0'
	implementation group: 'it.unimi.dsi', name: 'fastutil', version: '8.4.3'
}

And my chronicle-logger.properties:

# shared properties
chronicle.base=data/chronicle-logs/
# logger : default
chronicle.logger.root.path=data/chronicle-logs/
chronicle.logger.root.level=debug
# optional tweaks
chronicle.logger.root.cfg.rollCycle=SMALL_DAILY

Jire avatar Jan 10 '21 06:01 Jire

Temporary fix is to define Wires.java and add ignore cases to the top of the method:

public static void writeMarshallable(@NotNull Object marshallable, @NotNull WireOut wire) {

Like so:

    public static void writeMarshallable(@NotNull Object marshallable, @NotNull WireOut wire) {
        String packageName = marshallable.getClass().getPackageName();
        if (packageName.contains("com.mysql.cj") || packageName.contains("io.netty")) return;
        WireMarshaller wm = WireMarshaller.WIRE_MARSHALLER_CL.get(marshallable.getClass());
        wm.writeMarshallable(marshallable, wire);
    }

This is definitely not good for performance though, and it seems to corrupt the logs so that they can't be read with ChroniCat etc.

Jire avatar Jan 10 '21 06:01 Jire

Wires has a limitation that it can't serialize objects which are not trees i.e. contain no circular references. Detecting and handling such circular references is expensive. A simpler approach is to make the fields transient

peter-lawrey avatar Jun 16 '21 16:06 peter-lawrey

Closing - transient is the best way to handle this

JerryShea avatar Jun 06 '23 06:06 JerryShea