Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG]JSONB开启FieldBased和NotWriteHashMapArrayListClassName序列化后再反序列化时存在问题 #2691

Closed
rowstop opened this issue Jun 12, 2024 · 1 comment
Labels
bug Something isn't working fixed
Milestone

Comments

@rowstop
Copy link
Contributor

rowstop commented Jun 12, 2024

当存在一个默认值是不可变的 List 字段时存在问题(使用场景:dubbo 响应了一个 mybatis plus分页结果的Page对象)

public class Page<T> implements IPage<T> {
    /**
     * 查询数据列表
     */
    protected List<T> records = Collections.emptyList();
}
java.lang.UnsupportedOperationException
	at java.util.AbstractList.add(AbstractList.java:148)
	at java.util.AbstractList.add(AbstractList.java:108)
	at com.alibaba.fastjson2.reader.ORG_1_1_UnmodifiableList.readJSONBObject(Unknown Source)
	at com.alibaba.fastjson2.JSONB.parseObject(JSONB.java:799)
	at com.alibaba.fastjson2.issues_2600.MybatisPlusPageTest.writeReade(MybatisPlusPageTest.java:70)
	at com.alibaba.fastjson2.issues_2600.MybatisPlusPageTest.testUnmodifiableList(MybatisPlusPageTest.java:46)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at java.util.ArrayList.forEach(ArrayList.java:1259)
	at java.util.ArrayList.forEach(ArrayList.java:1259)

经检查是这段代码取了默认值,后面调用了它的 add 方法
com.alibaba.fastjson2.reader.ObjectReaderCreatorASM:3737
image
复现代码

package com.alibaba.fastjson2.issues_2600;

import com.alibaba.fastjson2.JSONB;
import com.alibaba.fastjson2.JSONReader;
import com.alibaba.fastjson2.JSONWriter;
import com.alibaba.fastjson2.internal.asm.MethodWriter;
import com.alibaba.fastjson2.reader.FieldReader;
import com.alibaba.fastjson2.reader.ObjectReaderCreatorASM;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import org.apache.dubbo.common.serialize.fastjson2.FastJson2ObjectInput;
import org.apache.dubbo.common.serialize.fastjson2.FastJson2ObjectOutput;
import org.junit.jupiter.api.Test;

import java.lang.reflect.Type;
import java.util.*;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

/**
 * @author 张治保
 * @since 2024/6/12
 */
public class Issue2691 {

    /**
     *  failed
     * @see Page#records
     * @see FastJson2ObjectOutput#writeObject(Object)
     * @see FastJson2ObjectInput#readObject(Class)
     * @see ObjectReaderCreatorASM#genReadFieldValueList(FieldReader, String, MethodWriter, int, int, int, int, int, Map, int, int, int, boolean, boolean, Class, Class, Type, long, Type, String, Integer)
     */
    @Test
    void testUnmodifiableList() {
        UnmodifiableList list = new UnmodifiableList();
        ArrayList<String> strings = new ArrayList<>();
        strings.add("1");
        list.setList(strings);
        writeReade(list);
    }

    /**
     * passed
     */
    @Test
    void testUnmodifiableMap(){
        UnmodifiableMap map = new UnmodifiableMap();
        Map<String,String> stringMap = new HashMap<>();
        stringMap.put("1","1");
        map.setMap(stringMap);
        writeReade(map);
    }

    /**
     * passed
     */
    @Test
    void testUnmodifiableSet(){
        UnmodifiableSet set = new UnmodifiableSet();
        Set<String> stringSet = new HashSet<>();
        stringSet.add("1");
        set.setSet(stringSet);
        writeReade(set);
    }

    void writeReade(Object value){
        byte[] bytes = JSONB.toBytes(
                value,
                JSONWriter.Feature.WriteClassName,
                JSONWriter.Feature.FieldBased,
                JSONWriter.Feature.NotWriteHashMapArrayListClassName
        );

        // readObject
        Object result = JSONB.parseObject(
                bytes,
                value.getClass(),
                JSONReader.Feature.FieldBased);
        assertNotNull(result);
        assertEquals(result,value);
    }


    @Getter
    @Setter
    @EqualsAndHashCode
    @Accessors(chain = true)
    private static class UnmodifiableList {
        private List<String> list = Collections.emptyList();
    }
    @Getter
    @Setter
    @EqualsAndHashCode
    @Accessors(chain = true)
    private static class UnmodifiableSet {
        private Set<String> set = Collections.emptySet();
    }

    @Getter
    @Setter
    @EqualsAndHashCode
    @Accessors(chain = true)
    private static class UnmodifiableMap {
        private  Map<String,String> map = Collections.emptyMap();
    }
}
@rowstop rowstop added the bug Something isn't working label Jun 12, 2024
wenshao pushed a commit that referenced this issue Jun 25, 2024
* fix unsupported operation error when field is Collections.EMPTY_LIST, for issue #2691 and issue #1835
@wenshao wenshao added this to the 2.0.52 milestone Jun 25, 2024
@wenshao wenshao added the fixed label Jun 25, 2024
@wenshao
Copy link
Member

wenshao commented Jul 14, 2024

@wenshao wenshao closed this as completed Jul 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working fixed
Projects
None yet
Development

No branches or pull requests

2 participants