Skip to content

CompatibleFieldSerializer throws IllegalArgumentException #784

@dalibegovic

Description

@dalibegovic

I assume the underlying problem is same as in: #774, but just to double check.

Version used is 5.0.0.

When we run:

class KryoSerializerDemo {
    public static void main(String[] args) {
        Kryo kryo = new Kryo();

        kryo.setRegistrationRequired(false);
        CompatibleFieldSerializer.CompatibleFieldSerializerConfig config = new CompatibleFieldSerializer.CompatibleFieldSerializerConfig();
        kryo.setDefaultSerializer(new SerializerFactory.CompatibleFieldSerializerFactory(config));

        Output output = new Output(4096, Integer.MAX_VALUE);
        kryo.writeClassAndObject(output, new Car(new Electric()));
        output.reset();
        kryo.writeClassAndObject(output, new Car(new Petrol()));
    }

    static class Car {
        private Motor motor;

        public Car(Motor motor) {
            this.motor = motor;
        }
    }

    interface Motor {

    }

    static class Electric implements Motor {
        private String range = "371km";
    }

    static class Petrol implements Motor {
        private int horsePower = 115;
    }
}

The output is:

Exception in thread "main" com.esotericsoftware.kryo.KryoException: java.lang.IllegalArgumentException: Can not set java.lang.String field KryoSerializerDemo$Electric.range to KryoSerializerDemo$Petrol
Serialization trace:
motor (KryoSerializerDemo$Car)
	at com.esotericsoftware.kryo.serializers.ReflectField.write(ReflectField.java:96)
	at com.esotericsoftware.kryo.serializers.CompatibleFieldSerializer.write(CompatibleFieldSerializer.java:107)
	at com.esotericsoftware.kryo.Kryo.writeClassAndObject(Kryo.java:644)
	at KryoSerializerDemo.main(KryoSerializerDemo.java:17)
Caused by: java.lang.IllegalArgumentException: Can not set java.lang.String field KryoSerializerDemo$Electric.range to KryoSerializerDemo$Petrol
	at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
Caused by: java.lang.IllegalArgumentException: Can not set java.lang.String field KryoSerializerDemo$Electric.range to KryoSerializerDemo$Petrol

	at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
	at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58)
	at java.base/jdk.internal.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:36)
	at java.base/java.lang.reflect.Field.get(Field.java:419)
	at com.esotericsoftware.kryo.serializers.CompatibleFieldSerializer.write(CompatibleFieldSerializer.java:93)
	at com.esotericsoftware.kryo.Kryo.writeObject(Kryo.java:575)
	at com.esotericsoftware.kryo.serializers.ReflectField.write(ReflectField.java:86)
	... 3 more

After some debugging, the problem seems to be that when writing Car class with Petrol engine (second call), cached fields from first write call are returned here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions