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

Đang mở
#4,102 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức phù hợp với người mới
68/100
Loại issue
Lỗi
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
scala
Lĩnh vực
backend

Hướng nghiên cứu

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.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

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!
Ngôn ngữ chính
Java
Star
4.6k
Fork
470
Merge trung bình
9 giờ 28 phút
Pull request đã merge (30 ngày)
33

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của apache/fory

Tất cả issue của apache/fory

Issue tương tự

Thêm issue về Java

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.