[alibaba/fastjson]setSerializerFeatures中添加SerializerFeature.BrowserCompatible属性,对象字段数过多时报空指针异常

2024-05-23 160 views
8

setSerializerFeatures中添加SerializerFeature.BrowserCompatible属性,对象字段数过多时报空指针异常

对象中包含 List Integer Long Float等类型

截屏2020-03-21下午11 52 16

java.lang.NullPointerException: null at com.alibaba.fastjson.serializer.ASMSerializer_17_XXXXXXBO.writeNormal(Unknown Source) ~[na:na] at com.alibaba.fastjson.serializer.ASMSerializer_17_XXXXXXBO.write(Unknown Source) ~[na:na] at com.alibaba.fastjson.serializer.JSONSerializer.writeWithFieldName(JSONSerializer.java:333) ~[fastjson-1.2.58.jar:na] at com.alibaba.fastjson.serializer.ASMSerializer_13_DefaultResult.writeNormal(Unknown Source) ~[na:na] at com.alibaba.fastjson.serializer.ASMSerializer_13_DefaultResult.write(Unknown Source) ~[na:na] at com.alibaba.fastjson.serializer.JSONSerializer.write(JSONSerializer.java:285) ~[fastjson-1.2.58.jar:na] at com.alibaba.fastjson.JSON.writeJSONString(JSON.java:937) ~[fastjson-1.2.58.jar:na] at org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:226) ~[spring-web-4.3.18.RELEASE.jar:4.3.18.RELEASE] at com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter.write(FastJsonHttpMessageConverter.java:244) ~[fastjson-1.2.58.jar:na]

回答

2

问题没重现,需要帮忙提供一下testcase

3

问题没重现,需要帮忙提供一下testcase 具体问题可以在我的这个项目中复现https://github.com/ypw384556909/fastjson-test-case.git 详细描述请看 README.md

2

下载了你的testcase,在macbook上面没有重现,你用的os是@ypw384556909

2

问题未重现

5

我在本地测试时,直接在IDEA中运行了提供的Spring Boot demo,没有复现到NullPointException,但是JVM出现了 fatal error,异常退出了。我注意到提供的demo中也有类似的JVM异常的日志文件,所以想check下是否是同一个原因,或者这个属于另外的问题。

查阅文档后发现,在IDEA直接运行,默认会选中"Enable launch optimization",该选项会在VM参数中添加"-noverify"。

https://www.jetbrains.com/help/idea/run-debug-configuration-spring-boot.html#configuration-tab

正常情况下,验证字节码流程 以温少提供的demo testcase for #3075 为例,debug后发现,在用ASM生成一个ObjectSerializer字节码后,JVM加载验证字节码 ,会抛出 Invalid method Code length 70093 in class file com/alibaba/fastjson/serializer/ASMSerializer_2_TestBasicBOClassFormatError异常,fastjson捕获异常后会重新生成一个JavaBeanSerializer完成后续的序列化。

异常情况,不验证字节码流程 因为带有"-noverify"参数,会跳过字节码的验证阶段。所以会拿到的是有问题的字节码,在执行writer.write(this, object, null, null, 0);时,会因此而出现A fatal error has been detected by the Java Runtime Environment,JVM异常退出。

总结 其实这个问题和 SerializerFeature.BrowserCompatible 只是巧合。因为只有在字段数量小于256才会可能使用动态生成的ASMSerializer。当字段属性很多但是不足256,且开启了SerializerFeature.BrowserCompatible后,生成的writeNormal方法,超过了JVM规定的method Code的限制。

疑问 存在某些场景下,JVM应用就是关闭了verify的,这种情况下,fastjson需要处理这种极端情况吗?