apache / dubbo

The java implementation of Apache Dubbo. An RPC and microservice framework.
https://dubbo.apache.org/
Apache License 2.0
40.54k stars 26.44k forks source link

[Bug] use record class error #14814

Closed lkhuge closed 4 weeks ago

lkhuge commented 1 month ago

Pre-check

Search before asking

Apache Dubbo Component

Java SDK (apache/dubbo)

Dubbo Version

Dubbo Java 3.3.1

Steps to reproduce this issue

use:

public interface Test1Service {
    void execute(Test1Request request);
}

public record Test1Request(
        String p1,
        Integer p2,
        Boolean p3,
        LocalDateTime p4
) implements Serializable {
}

result: (error in server(Deserializer) )

Caused by: java.lang.UnsupportedOperationException: can't get field offset on a record class: private final java.lang.String com.test.service.dto.Test1Request.p1
    at jdk.unsupported/sun.misc.Unsafe.objectFieldOffset(Unsafe.java:648)
    at com.alibaba.com.caucho.hessian.io.FieldDeserializer2FactoryUnsafe$StringFieldDeserializer.<init>(FieldDeserializer2FactoryUnsafe.java:434)
    at com.alibaba.com.caucho.hessian.io.FieldDeserializer2FactoryUnsafe.create(FieldDeserializer2FactoryUnsafe.java:146)
    at com.alibaba.com.caucho.hessian.io.UnsafeDeserializer.getFieldMap(UnsafeDeserializer.java:366)
    at com.alibaba.com.caucho.hessian.io.UnsafeDeserializer.<init>(UnsafeDeserializer.java:109)
    at org.apache.dubbo.common.serialize.hessian2.Hessian2SerializerFactory.getDefaultDeserializer(Hessian2SerializerFactory.java:76)
    at com.alibaba.com.caucho.hessian.io.SerializerFactory.loadDeserializer(SerializerFactory.java:545)
    at com.alibaba.com.caucho.hessian.io.SerializerFactory.getDeserializer(SerializerFactory.java:474)
    at com.alibaba.com.caucho.hessian.io.SerializerFactory.getObjectDeserializer(SerializerFactory.java:672)
    at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObjectInstance(Hessian2Input.java:2954)
    at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2289)
    at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2218)
    at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2262)
    at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2218)
    at org.apache.dubbo.common.serialize.hessian2.Hessian2ObjectInput.readObject(Hessian2ObjectInput.java:118)
    at org.apache.dubbo.common.serialize.DefaultSerializationExceptionWrapper$ProxyObjectInput.readObject(DefaultSerializationExceptionWrapper.java:161)

What you expected to happen

support record class

Anything else

dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2SerializerFactory.java


@Override
protected Deserializer getDefaultDeserializer(Class cl) {
try {
// pre-check if class is allow
defaultSerializeClassChecker.loadClass(getClassLoader(), cl.getName());
} catch (ClassNotFoundException e) {
// ignore
}
    checkSerializable(cl);

    if (isEnableUnsafeSerializer()) {
        return new UnsafeDeserializer(cl, getFieldDeserializerFactory());
    } else return new JavaDeserializer(cl, getFieldDeserializerFactory());
}

> hessian-lite/src/main/java/com/alibaba/com/caucho/hessian/io/SerializerFactory.java
```java
    protected Deserializer getDefaultDeserializer(Class cl) {
        if (InputStream.class.equals(cl))
            return InputStreamDeserializer.DESER;

        if (!Serializable.class.isAssignableFrom(cl)
                && !_isAllowNonSerializable) {
            throw new IllegalStateException("Serialized class " + cl.getName() + " must implement java.io.Serializable");
        }

        if (RecordUtil.isRecord(cl))
            return new RecordDeserializer(cl, _fieldDeserializerFactory);

        if (_isEnableUnsafeSerializer) {
            return new UnsafeDeserializer(cl, _fieldDeserializerFactory);
        } else
            return new JavaDeserializer(cl, _fieldDeserializerFactory);
    }

Are you willing to submit a pull request to fix on your own?

Code of Conduct

AlbumenJ commented 1 month ago

Can you please provide a demo? I cannot reproduce it.

image

Or have you ever configure the hessian-lite version. Hessian-lite 4.x has improved the compability with Record

lkhuge commented 1 month ago

This problem is not caused by Hessian-lite but by dubco-serialization-hessian2

Can you please provide a demo? I cannot reproduce it.

image

Or have you ever configure the hessian-lite version. Hessian-lite 4.x has improved the compability with Record

lkhuge commented 1 month ago

You can compare

https://github.com/apache/dubbo/blob/3.3/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2SerializerFactory.java

and

https://github.com/apache/dubbo-hessian-lite/blob/master/hessian-lite/src/main/java/com/alibaba/com/caucho/hessian/io/SerializerFactory.java

for

protected Deserializer getDefaultDeserializer(Class cl)

dubco-serialization-hessian2 is missing

if (RecordUtil.isRecord(cl))
return new RecordDeserializer(cl, _fieldDeserializerFactory);
AlbumenJ commented 1 month ago

Got it. Will be fixed in https://github.com/apache/dubbo/pull/14820