[Scala] Native mode rebuilds IntMap, LongMap, BitSet, mutable.LongMap and StringBuilder as a different collection class

Abierto
#4,102 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
4/5
Tiempo estimado
3-5 días
Aptitud para principiantes
68/100
Tipo de issue
Error
Claridad
Bastante claro
Estado de actividad
Activo
Stack tecnológico
scala
Área
backend

Línea de trabajo

Start with ScalaCollectionSerializer, ScalaSeqSerializer and ScalaSortedSetSerializer in CollectionSerializer.scala, plus ScalaMapSerializer in MapSerializer.scala. Review the tests being added for #4100 and reproduce the listed collection cases across the affected modes. Done means round trips preserve each concrete collection type and ArraySeq representation without ClassCastException in typed fields.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

bug scala
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
import scala.collection.immutable

case class Holder(m: immutable.IntMap[String])

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

fory.deserialize(fory.serialize(Holder(immutable.IntMap(1 -> "a"))))
// DeserializationException caused by
// ClassCastException: scala.collection.immutable.Map$Map1 cannot be cast to scala.collection.immutable.IntMap
What did you expect to see?

A native-mode round trip should rebuild the same collection class, as it already does for List, Vector, HashMap, TreeMap, LinkedHashMap and others.

What did you see instead?

The native Scala collection serializers write the value's generic factory, iterableFactory, mapFactory or sortedIterableFactory. For these specialised kinds that factory builds a different class. The same happens in compatible and schema-consistent modes:

Written Read back as As a declared case class field
immutable.IntMap immutable.Map$Map1 / Map ClassCastException
immutable.LongMap immutable.Map$Map1 / Map ClassCastException
mutable.BitSet mutable.TreeSet ClassCastException
mutable.LongMap mutable.HashMap ClassCastException
mutable.StringBuilder mutable.ArrayBuffer[Char] ClassCastException
immutable.ArraySeq[Int] (ArraySeq$ofInt) ArraySeq$ofRef (boxed) works, but loses the unboxed representation

As a root value, the decoded collection compares equal to the original, so the change goes unnoticed until a typed field or a pattern match depends on the concrete class.

Anything Else?

The factories are chosen in ScalaCollectionSerializer, ScalaSeqSerializer, ScalaSortedSetSerializer and ScalaMapSerializer (CollectionSerializer.scala and MapSerializer.scala). These kinds probably need their specific factory or a dedicated serializer, for example IntMap/LongMap factories, BitSet from its bitmask, StringBuilder as a string, and ArraySeq keeping its element ClassTag.

Related: #4101 covers the registration gap for several of the same types. Found while adding tests in #4100.

Are you willing to submit a PR?
  • I'm willing to submit a PR!
Lenguaje dominante
Java
Estrellas
4.6k
Forks
470
Merge medio
9 h 28 min
PR fusionados (30 d)
33

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de apache/fory

Todos los issues de apache/fory

Issues similares

Más issues de Java

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.