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]反序列化Builder类错误 #2399

Closed
prog-ape opened this issue Apr 4, 2024 · 3 comments
Closed

[BUG]反序列化Builder类错误 #2399

prog-ape opened this issue Apr 4, 2024 · 3 comments
Labels
bug Something isn't working fixed
Milestone

Comments

@prog-ape
Copy link

prog-ape commented Apr 4, 2024

问题描述

User类是第三方jar里的,存入redis,反序列化时出现下面异常

环境信息

请填写以下信息:

  • OS信息: windows 11 64G
  • JDK信息: jdk 17
  • 版本信息:2.0.48

重现步骤

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import lombok.NonNull;


@JsonDeserialize(
        builder = UserBuilderImpl.class
)
public class User implements ApiObject {
    private static final String ID_FIELD = "id";
    private static final String FIRST_NAME_FIELD = "first_name";
    @JsonProperty("id")
    private @NonNull Long id;
    @JsonProperty("first_name")
    private @NonNull String firstName;

    protected User(User.UserBuilder<?, ?> b) {
        this.id = b.id;
        if (this.id == null) {
            throw new NullPointerException("id is marked non-null but is null");
        } else {
            this.firstName = b.firstName;
            if (this.firstName == null) {
                throw new NullPointerException("firstName is marked non-null but is null");
            }
        }
    }

    public static User.UserBuilder<?, ?> builder() {
        return new User.UserBuilderImpl();
    }

    public boolean equals(Object o) {
        if (o == this) {
            return true;
        } else if (!(o instanceof User)) {
            return false;
        } else {
            User other = (User)o;
            if (!other.canEqual(this)) {
                return false;
            } else {
                label143: {
                    Object this$id = this.getId();
                    Object other$id = other.getId();
                    if (this$id == null) {
                        if (other$id == null) {
                            break label143;
                        }
                    } else if (this$id.equals(other$id)) {
                        break label143;
                    }

                    return false;
                }

                label94: {
                    Object this$firstName = this.getFirstName();
                    Object other$firstName = other.getFirstName();
                    if (this$firstName == null) {
                        if (other$firstName == null) {
                            break label94;
                        }
                    } else if (this$firstName.equals(other$firstName)) {
                        break label94;
                    }

                    return false;
                }
                return true;
            }
        }
    }

    protected boolean canEqual(Object other) {
        return other instanceof User;
    }

    public int hashCode() {
        int PRIME = true;
        int result = 1;
        Object $id = this.getId();
        result = result * 59 + ($id == null ? 43 : $id.hashCode());
        Object $firstName = this.getFirstName();
        result = result * 59 + ($firstName == null ? 43 : $firstName.hashCode());
        return result;
    }

    public @NonNull Long getId() {
        return this.id;
    }

    public @NonNull String getFirstName() {
        return this.firstName;
    }


    @JsonProperty("id")
    public void setId(@NonNull Long id) {
        if (id == null) {
            throw new NullPointerException("id is marked non-null but is null");
        } else {
            this.id = id;
        }
    }

    @JsonProperty("first_name")
    public void setFirstName(@NonNull String firstName) {
        if (firstName == null) {
            throw new NullPointerException("firstName is marked non-null but is null");
        } else {
            this.firstName = firstName;
        }
    }

    public String toString() {
        Long var10000 = this.getId();
        return "User(id=" + var10000 + ", firstName=" + this.getFirstName()  + ")";
    }

    public User(@NonNull Long id, @NonNull String firstName) {
        if (id == null) {
            throw new NullPointerException("id is marked non-null but is null");
        } else if (firstName == null) {
            throw new NullPointerException("firstName is marked non-null but is null");
        }
    }

    public abstract static class UserBuilder<C extends User, B extends User.UserBuilder<C, B>> {
        private Long id;
        private String firstName;

        public UserBuilder() {
        }

        @JsonProperty("id")
        public B id(@NonNull Long id) {
            if (id == null) {
                throw new NullPointerException("id is marked non-null but is null");
            } else {
                this.id = id;
                return this.self();
            }
        }

        @JsonProperty("first_name")
        public B firstName(@NonNull String firstName) {
            if (firstName == null) {
                throw new NullPointerException("firstName is marked non-null but is null");
            } else {
                this.firstName = firstName;
                return this.self();
            }
        }


        protected abstract B self();

        public abstract C build();

        public String toString() {
            return "User.UserBuilder(id=" + this.id + ", firstName=" + this.firstName + ")";
        }
    }

    @JsonPOJOBuilder(
            withPrefix = "",
            buildMethodName = "build"
    )
    static final class UserBuilderImpl extends User.UserBuilder<User, User.UserBuilderImpl> {
        private UserBuilderImpl() {
        }

        protected User.UserBuilderImpl self() {
            return this;
        }

        public User build() {
            return new User(this);
        }
    }
}


import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import java.io.Serializable;

@JsonIgnoreProperties(
    ignoreUnknown = true
)
@JsonInclude(Include.NON_NULL)
public interface ApiObject extends Serializable {
}


public class FastJsonCodec extends BaseCodec {
    static final Filter autoTypeFilter = JSONReader.autoTypeFilter(
            "com.test"
    );

    private final Encoder encoder = in -> {
        ByteBuf out = ByteBufAllocator.DEFAULT.buffer();
        try {
            ByteBufOutputStream os = new ByteBufOutputStream(out);
            JSON.writeTo(os, in, JSONWriter.Feature.WriteClassName);
            return os.buffer();
        } catch (Exception e) {
            out.release();
            throw new IOException(e);
        }
    };

    private final Decoder<Object> decoder = (buf, state) ->
            JSON.parseObject(new ByteBufInputStream(buf).readAllBytes(), Object.class, autoTypeFilter);

    @Override
    public Decoder<Object> getValueDecoder() {
        return decoder;
    }

    @Override
    public Encoder getValueEncoder() {
        return encoder;
    }
}
  1. 使用 xxx.xxx 方法
  2. 输入 ... 数据
  3. 出现 ... 错误
示例代码
RedisUtils.set("xxxx",user);

User caUser=RedisUtils.get("xxxx");


### 相关日志输出
Caused by: com.alibaba.fastjson2.JSONException: invoke constructor error, public com.test.objects.User(java.lang.Long,java.lang.String)
	at com.alibaba.fastjson2.reader.ConstructorFunction.apply(ConstructorFunction.java:222)
	at com.alibaba.fastjson2.reader.ConstructorFunction.apply(ConstructorFunction.java:15)
	at com.alibaba.fastjson2.reader.ObjectReaderNoneDefaultConstructor.readObject(ObjectReaderNoneDefaultConstructor.java:344)
	at com.alibaba.fastjson2.reader.ObjectReaderImplObject.readObject(ObjectReaderImplObject.java:129)
	at com.alibaba.fastjson2.JSON.parseObject(JSON.java:1463)
	at com.test.config.FastJsonCodec.lambda$new$1(FastJsonCodec.java:46)
	at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:433)
	at org.redisson.client.handler.CommandDecoder.decodeCommand(CommandDecoder.java:216)
	at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:144)
	at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:120)
	at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:529)
	at io.netty.handler.codec.ReplayingDecoder.callDecode(ReplayingDecoder.java:366)
	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:290)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562)
	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	... 1 more
Caused by: java.lang.reflect.InvocationTargetException
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
	at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
	at com.alibaba.fastjson2.reader.ConstructorFunction.apply(ConstructorFunction.java:219)
	... 28 more
Caused by: java.lang.NullPointerException: firstName is marked non-null but is null
	at com.test.objects.User.<init>(User.java:25)
	... 34 more
@prog-ape prog-ape added the bug Something isn't working label Apr 4, 2024
@wenshao wenshao added this to the 2.0.49 milestone Apr 6, 2024
@wenshao
Copy link
Member

wenshao commented Apr 6, 2024

https://oss.sonatype.org/content/repositories/snapshots/com/alibaba/fastjson2/fastjson2/2.0.49-SNAPSHOT/
问题已经修复,请帮忙用2.0.49-SNAPSHOT版本验证,2.0.49版本预计在4月底发布

@wenshao wenshao added the fixed label Apr 6, 2024
@prog-ape
Copy link
Author

prog-ape commented Apr 7, 2024

https://oss.sonatype.org/content/repositories/snapshots/com/alibaba/fastjson2/fastjson2/2.0.49-SNAPSHOT/ 问题已经修复,请帮忙用2.0.49-SNAPSHOT版本验证,2.0.49版本预计在4月底发布

感谢,可以了

@prog-ape prog-ape closed this as completed Apr 7, 2024
@wenshao
Copy link
Member

wenshao commented Apr 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