Skip to content

Add Collections.unmodifiableList() to JdkImmutableListSerializer. #909

Closed

Description

@jvdvegt

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.

Activity

  1. theigl commented on Aug 16, 2022

    @theigl
    Collaborator

    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.

    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

  2. jvdvegt commented on Aug 16, 2022

    @jvdvegt
    Author

    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:

    1. Write my own implementation and register it explicitly in Kryo, or
    2. 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?

  3. theigl commented on Aug 16, 2022

    @theigl
    Collaborator

    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.

  4. jvdvegt commented on Aug 17, 2022

    @jvdvegt
    Author

    Right, I'll be writing my own serializer. Thanks for the thorough, clear and timely responses!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions