You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Add Collections.unmodifiableList() to JdkImmutableListSerializer. #909
Is your feature request related to a problem? Please describe.
The list returned by Collections.unmodifiableList(someList) is not serializable when using the default Kryo serializers.
Describe the solution you'd like
Default JDK classes should be serializable as much as possible without using external libraries.
Describe alternatives you've considered
When I create a copy of the class ImmutableCollectionsSerializers.JdkImmutableListSerializer and register it to be used for unmodifiable lists, they seem to work fine: kryo.register(Collections.unmodifiableList(new ArrayList<>()).getClass(), new CopyOfJdkImmutableListSerializer());
Exposing instances of the JdkImmutable*Serializer classes so I can register them myself would be second-best, I suppose.
Additional context
The same holds for Collections.unmodifiableSet and probably for Collections.unmodifiableMap.
The problem is that Collections.unmodifiableList(someList) may wrap an arbitrary list and it is impossible to determine the underlying list type without resorting to reflection. The same problem applies to sets and maps, but is further complicated by possible sorted implementations, where the comparator has to be serialized as well.
Your workaround only works for wrapped ArrayList types and as a side-effect changes the type of the list to ImmutableCollections.ListN.
Thanks for the thorough explanation. I'm currently using the javakaffee serializer you mentioned, but as it causes warnings about reflective access I am trying to get rid of it.
I am not interested in the exact type of list wrapped by unmodifiableList(): deserializing into any unmodifiable/immutable list is fine. So the JdkImmutableListSerializer works for me, and it seems there are now two way to use it:
Write my own implementation and register it explicitly in Kryo, or
Use reflection to access the class in Kryo and register it explicitly in Kryo.
Would exposing an instance of the JdkImmutableListSerializer so I could register it explicitly be an option?
Since most other serializers are currently public it shouldn't be a problem to expose them. If you want, you can create a PR for this.
However, I'd recommend that you write your own serializer that wraps the list in the same unmodifiable wrapper with Collections.unmodifiableList() instead of List.of(). I find it confusing when field types get changed during serialization.
Activity
theigl commentedon Aug 16, 2022
The problem is that
Collections.unmodifiableList(someList)may wrap an arbitrary list and it is impossible to determine the underlying list type without resorting to reflection. The same problem applies to sets and maps, but is further complicated by possible sorted implementations, where the comparator has to be serialized as well.Your workaround only works for wrapped
ArrayListtypes and as a side-effect changes the type of the list toImmutableCollections.ListN.Kryo only provides safe serializers, i.e. serializers that do not rely on implementation details and reflection. However, you can use the implementation provided by the kryo-serializers project: https://github.com/magro/kryo-serializers/blob/master/src/main/java/de/javakaffee/kryoserializers/UnmodifiableCollectionsSerializer.java
jvdvegt commentedon Aug 16, 2022
Thanks for the thorough explanation. I'm currently using the javakaffee serializer you mentioned, but as it causes warnings about reflective access I am trying to get rid of it.
I am not interested in the exact type of list wrapped by
unmodifiableList(): deserializing into any unmodifiable/immutable list is fine. So theJdkImmutableListSerializerworks for me, and it seems there are now two way to use it:Would exposing an instance of the
JdkImmutableListSerializerso I could register it explicitly be an option?theigl commentedon Aug 16, 2022
Since most other serializers are currently
publicit shouldn't be a problem to expose them. If you want, you can create a PR for this.However, I'd recommend that you write your own serializer that wraps the list in the same unmodifiable wrapper with
Collections.unmodifiableList()instead ofList.of(). I find it confusing when field types get changed during serialization.jvdvegt commentedon Aug 17, 2022
Right, I'll be writing my own serializer. Thanks for the thorough, clear and timely responses!