Skip to content

[Scala] Native-mode Fory.copy fails for Scala collections and Range #4103

Description

@pjfanning

Search before asking

  • I had searched in the issues and found no similar issues.

Version

main (1.8.0-SNAPSHOT), Scala 2.13.18 and 3.3.8

Component(s)

Scala

Minimal reproduce step

import org.apache.fory.scala.ForyScala

val fory = ForyScala.builder()
  .withXlang(false)
  .withRefTracking(true)
  .withRefCopy(true)
  .requireClassRegistration(false)
  .build()

fory.copy(List(1, 2))
// CopyException caused by
// UnsupportedOperationException: Copy for class scala.collection.immutable.$colon$colon is not supported

What did you expect to see?

Fory.copy should deep-copy Scala collections in native mode, as it already does in xlang mode (ScalaXlangSerializerTest covers xlang copy of mutable collections, including cyclic ones). Case classes that contain Scala collection fields should be copyable too.

What did you see instead?

In native mode, in both compatible and schema-consistent modes, copy throws UnsupportedOperationException: Copy for class ... is not supported for every Scala collection kind tried. That includes immutable kinds (::, Nil, Vector, Set1, Map1, TreeSet, TreeMap), mutable kinds (ArrayBuffer, ListBuffer, HashSet, HashMap, LinkedHashMap) and Range.

The copy also fails when the collection is nested, for example a case class with a List[String] field. Some and tuples copy fine.

Anything Else?

AbstractScalaCollectionSerializer, AbstractScalaMapSerializer, RangeSerializer and NumericRangeSerializer don't implement copy. The xlang serializers in XlangCollectionSerializer.scala do.

A native implementation could:

  • return immutable collections and ranges as-is, since they're immutable, or rebuild them through the same factory with copied elements when a deep copy of the elements is needed
  • for mutable collections, create the result, publish it with copyContext.reference before copying the elements (so cyclic graphs work), and then copy each element

Found while adding tests in #4100.

Are you willing to submit a PR?

  • I'm willing to submit a PR!

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingscala

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions