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

[Java] deserialize object,error 'A cannot be cast to class B' occurred #2005

Open
yyjyc opened this issue Jan 13, 2025 · 3 comments
Open

[Java] deserialize object,error 'A cannot be cast to class B' occurred #2005

yyjyc opened this issue Jan 13, 2025 · 3 comments
Labels
question Further information is requested

Comments

@yyjyc
Copy link

yyjyc commented Jan 13, 2025

Question

I use fury in my projects, in one of the projects i serialize the object of ProductPO.class where fury is created like "furySerializer" in following code, in the other project i deseralize the byte[] using fury like “furyDeSerializer1” in following code.
however,when i deseralize the byte[],an error occurred and made me confused:

java.lang.ClassCastException: class ...RateDetailPO cannot be cast to class ...ProductPO (...RateDetailPO and ...ProductPO are in unnamed module of loader 'app')
	at ...FuryTestV2.test1(FuryTestV2.java:73)
	at ...main(FuryTestV2.java:63)

my code is like:

public class FuryTestV2{
    private static ThreadSafeFury furySerializer = null;
    private static ThreadSafeFury furyDeSerializer1 = null;
    private static ThreadSafeFury furyDeSerializer2 = null;
    static {
        furySerializer = new ThreadLocalFury(classLoader -> {
            Fury f = Fury.builder().withCompatibleMode(CompatibleMode.COMPATIBLE).withLanguage(Language.JAVA).withClassLoader(classLoader)
                    .withDeserializeNonexistentClass(true).build();
            f.register(ProductPO.class);
            return f;
        });

        furyDeSerializer1 = new ThreadLocalFury(classLoader -> {
            Fury f = Fury.builder().withCompatibleMode(CompatibleMode.COMPATIBLE).withLanguage(Language.JAVA).withClassLoader(classLoader)
                    .withDeserializeNonexistentClass(true).build();
            f.register(RateDetailPO.class);
            f.register(PersonRulePO.class);
            f.register(DailyInfoPO.class);
            f.register(DailyInfoList.class);
            f.register(GregorianCalendar.class);
            f.register(com.ctrip.hotel.productsearchfilter.ProductPO.class);
            return f;
        });

        furyDeSerializer2 = new ThreadLocalFury(classLoader -> {
            Fury f = Fury.builder().withCompatibleMode(CompatibleMode.COMPATIBLE).withLanguage(Language.JAVA).withClassLoader(classLoader)
                    .withDeserializeNonexistentClass(true).build();
            f.register(com.ctrip.hotel.productsearchfilter.ProductPO.class);
            f.register(RateDetailPO.class);
            f.register(PersonRulePO.class);
            f.register(DailyInfoPO.class);
            f.register(DailyInfoList.class);
            f.register(GregorianCalendar.class);
            return f;
        });
    }

    public static void main(String[] args) {
        // 构建序列化的对象
        ProductPO productPO = createProductPO();
        // 序列化
        System.out.println("test1:" + test1(productPO)); // false
        System.out.println("test2:" + test2(productPO)); // true

    }

    private static boolean test1(ProductPO productPO) {
        try {
            // 序列化
            byte[] serialize = furySerializer.serialize(productPO);
            // 反序列化
            com.ctrip.hotel.productsearchfilter.ProductPO result = (com.ctrip.hotel.productsearchfilter.ProductPO) furyDeSerializer1.deserialize(serialize);
            System.out.println(SSJsonSerializerUtils.serialize(result));
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
    private static boolean test2(ProductPO productPO) {
        try {
            // 序列化
            byte[] serialize = furySerializer.serialize(productPO);
            // 反序列化
            com.ctrip.hotel.productsearchfilter.ProductPO result = (com.ctrip.hotel.productsearchfilter.ProductPO) furyDeSerializer2.deserialize(serialize);
            System.out.println(SSJsonSerializerUtils.serialize(result));
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    public static ProductPO createProductPO() {
        ProductPO productPO = new ProductPO();
        productPO.setProductId(1112324L);
        productPO.setHotelId(1234);
        productPO.setMasterHotelId(1235);
        productPO.setBasicRoomId(54435);
        productPO.setMasterBasicRoomId(6234);
        productPO.setRateCodeId(564332);
        productPO.setVendorId(6564);
        productPO.setRoomClass(6563423525L);
        productPO.setPerson(5);
        productPO.setResourceType(3);
        productPO.setPromoteRoomType(true);
        return productPO;
    }

}
@yyjyc yyjyc added the question Further information is requested label Jan 13, 2025
@yyjyc yyjyc changed the title [Question] <Java>when i deserialize object,error 'A cannot be cast to class B' occurred [Java] deserialize object,error 'A cannot be cast to class B' occurred Jan 13, 2025
@chaokunyang
Copy link
Collaborator

Hi @yyjyc , you need to make class registration consistent between serialization and deserialization, otherwise you will get class clast exception. With inconsistent class registration order, one class on serialization will be mapped to another class in deserialization

@yyjyc
Copy link
Author

yyjyc commented Jan 14, 2025

@chaokunyang Thank you for your reply. I register ProductPO.class when serialization, register RateDetailPO.class、PersonRulePO.class、DailyInfoPO.class、DailyInfoList.class、GregorianCalendar.class、com.ctrip.hotel.productsearchfilter.ProductPO.class when deserialization.

ProductPO.class is the same as com.ctrip.hotel.productsearchfilter.ProductPO.class except for the package name.

I serialize a ProductPO object but get a RateDetailPO object, then cause the exception like 'class ...RateDetailPO cannot be cast to class ...ProductPO'.

so,i have two questions:
1.package name must keep same between serialization and deserialization?
2.why i got a RateDetailPO object by deserialization ? I thought i would get a ProductPO object, even though ClassCastException may still occur like 'class ProductPO cannot be cast to class com.ctrip.hotel.productsearchfilter.ProductPO'

@chaokunyang
Copy link
Collaborator

Seems it's same issue as #1972

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants