This is an automated email from the ASF dual-hosted git repository.

chaokunyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fury.git


The following commit(s) were added to refs/heads/main by this push:
     new 594278ef fix(java): fix serialization npe of collection with all null 
elems (#2111)
594278ef is described below

commit 594278ef23c46c50063e124033fce563a46ea099
Author: Shawn Yang <[email protected]>
AuthorDate: Sat Mar 22 15:52:22 2025 +0800

    fix(java): fix serialization npe of collection with all null elems (#2111)
    
    ## What does this PR do?
    
    ## Related issues
    
    Closes #2109
    
    ## Does this PR introduce any user-facing change?
    
    <!--
    If any user-facing interface changes, please [open an
    issue](https://github.com/apache/fury/issues/new/choose) describing the
    need to do so and update the document if necessary.
    -->
    
    - [ ] Does this PR introduce any public API change?
    - [ ] Does this PR introduce any binary protocol compatibility change?
    
    ## Benchmark
    
    <!--
    When the PR has an impact on performance (if you don't know whether the
    PR will have an impact on performance, you can submit the PR first, and
    if it will have impact on performance, the code reviewer will explain
    it), be sure to attach a benchmark data here.
    -->
---
 .../org/apache/fury/resolver/ClassResolver.java    |  2 +
 .../org/apache/fury/serializer/NoneSerializer.java | 46 ++++++++++++++++++++++
 .../collection/AbstractCollectionSerializer.java   |  3 ++
 .../fury-core/native-image.properties              |  1 +
 .../collection/CollectionSerializersTest.java      | 29 ++++++++++++++
 5 files changed, 81 insertions(+)

diff --git 
a/java/fury-core/src/main/java/org/apache/fury/resolver/ClassResolver.java 
b/java/fury-core/src/main/java/org/apache/fury/resolver/ClassResolver.java
index c62aa6bc..995994f4 100644
--- a/java/fury-core/src/main/java/org/apache/fury/resolver/ClassResolver.java
+++ b/java/fury-core/src/main/java/org/apache/fury/resolver/ClassResolver.java
@@ -123,6 +123,7 @@ import org.apache.fury.serializer.JdkProxySerializer;
 import org.apache.fury.serializer.LambdaSerializer;
 import org.apache.fury.serializer.LocaleSerializer;
 import org.apache.fury.serializer.MetaSharedSerializer;
+import org.apache.fury.serializer.NoneSerializer;
 import org.apache.fury.serializer.NonexistentClass;
 import org.apache.fury.serializer.NonexistentClass.NonexistentMetaShared;
 import org.apache.fury.serializer.NonexistentClass.NonexistentSkip;
@@ -322,6 +323,7 @@ public class ClassResolver {
 
   private void addDefaultSerializers() {
     // primitive types will be boxed.
+    addDefaultSerializer(void.class, NoneSerializer.class);
     addDefaultSerializer(String.class, new StringSerializer(fury));
     PrimitiveSerializers.registerDefaultSerializers(fury);
     Serializers.registerDefaultSerializers(fury);
diff --git 
a/java/fury-core/src/main/java/org/apache/fury/serializer/NoneSerializer.java 
b/java/fury-core/src/main/java/org/apache/fury/serializer/NoneSerializer.java
new file mode 100644
index 00000000..c7cc3e81
--- /dev/null
+++ 
b/java/fury-core/src/main/java/org/apache/fury/serializer/NoneSerializer.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fury.serializer;
+
+import org.apache.fury.Fury;
+import org.apache.fury.memory.MemoryBuffer;
+
+@SuppressWarnings("rawtypes")
+public class NoneSerializer extends Serializer {
+  public NoneSerializer(Fury fury, Class type) {
+    super(fury, type);
+  }
+
+  @Override
+  public void write(MemoryBuffer buffer, Object value) {}
+
+  @Override
+  public Object read(MemoryBuffer buffer) {
+    return null;
+  }
+
+  @Override
+  public void xwrite(MemoryBuffer buffer, Object value) {}
+
+  @Override
+  public Object xread(MemoryBuffer buffer) {
+    return null;
+  }
+}
diff --git 
a/java/fury-core/src/main/java/org/apache/fury/serializer/collection/AbstractCollectionSerializer.java
 
b/java/fury-core/src/main/java/org/apache/fury/serializer/collection/AbstractCollectionSerializer.java
index 495c8993..ee0cab84 100644
--- 
a/java/fury-core/src/main/java/org/apache/fury/serializer/collection/AbstractCollectionSerializer.java
+++ 
b/java/fury-core/src/main/java/org/apache/fury/serializer/collection/AbstractCollectionSerializer.java
@@ -192,6 +192,9 @@ public abstract class AbstractCollectionSerializer<T> 
extends Serializer<T> {
       bitmap |= CollectionFlags.NOT_SAME_TYPE | 
CollectionFlags.NOT_DECL_ELEMENT_TYPE;
       buffer.writeByte(bitmap);
     } else {
+      if (elemClass == null) {
+        elemClass = void.class;
+      }
       // Write class in case peer doesn't have this class.
       if (!fury.getConfig().isMetaShareEnabled() && elemClass == 
declareElementType) {
         buffer.writeByte(bitmap);
diff --git 
a/java/fury-core/src/main/resources/META-INF/native-image/org.apache.fury/fury-core/native-image.properties
 
b/java/fury-core/src/main/resources/META-INF/native-image/org.apache.fury/fury-core/native-image.properties
index 3d5ae0bd..d28b1af1 100644
--- 
a/java/fury-core/src/main/resources/META-INF/native-image/org.apache.fury/fury-core/native-image.properties
+++ 
b/java/fury-core/src/main/resources/META-INF/native-image/org.apache.fury/fury-core/native-image.properties
@@ -302,6 +302,7 @@ 
Args=--initialize-at-build-time=org.apache.fury.memory.MemoryBuffer,\
     org.apache.fury.serializer.LambdaSerializer$ReplaceStub,\
     org.apache.fury.serializer.LambdaSerializer,\
     org.apache.fury.serializer.LocaleSerializer,\
+    org.apache.fury.serializer.NoneSerializer,\
     org.apache.fury.serializer.NonexistentClassSerializers$ClassFieldsInfo,\
     
org.apache.fury.serializer.NonexistentClassSerializers$NonexistentClassSerializer,\
     
org.apache.fury.serializer.NonexistentClassSerializers$NonexistentEnumClassSerializer,\
diff --git 
a/java/fury-core/src/test/java/org/apache/fury/serializer/collection/CollectionSerializersTest.java
 
b/java/fury-core/src/test/java/org/apache/fury/serializer/collection/CollectionSerializersTest.java
index 68c93173..c13abc91 100644
--- 
a/java/fury-core/src/test/java/org/apache/fury/serializer/collection/CollectionSerializersTest.java
+++ 
b/java/fury-core/src/test/java/org/apache/fury/serializer/collection/CollectionSerializersTest.java
@@ -904,4 +904,33 @@ public class CollectionSerializersTest extends 
FuryTestBase {
       copyCheck(fury, test);
     }
   }
+
+  @Test(dataProvider = "enableCodegen")
+  public void testCollectionAllNullElements(boolean enableCodegen) {
+    Fury fury =
+        Fury.builder()
+            .withCodegen(true)
+            .withRefTracking(true)
+            .requireClassRegistration(false)
+            .build();
+    List<Foo> fooList = new ArrayList<>();
+    fooList.add(null);
+    // serDeCheck(fury, fooList);
+
+    CollectionAbstractTest obj = new CollectionAbstractTest();
+    // fill elemTypeCache
+    obj.fooList = ofArrayList(new Foo1());
+    serDeCheck(fury, obj);
+
+    obj.fooList = fooList;
+    serDeCheck(fury, obj);
+
+    fury =
+        Fury.builder()
+            .withCodegen(enableCodegen)
+            .withRefTracking(true)
+            .requireClassRegistration(false)
+            .build();
+    serDeCheck(fury, obj);
+  }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to