Open Finchleyy opened 4 years ago
问题没重现,需要帮忙提供一下testcase
问题没重现,需要帮忙提供一下testcase 具体问题可以在我的这个项目中复现https://github.com/ypw384556909/fastjson-test-case.git 详细描述请看 README.md
下载了你的testcase,在macbook上面没有重现,你用的os是@ypw384556909
问题未重现
我在本地测试时,直接在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_TestBasicBO
的 ClassFormatError
异常,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需要处理这种极端情况吗?
setSerializerFeatures中添加SerializerFeature.BrowserCompatible属性,对象字段数过多时报空指针异常
对象中包含 List Integer Long Float等类型
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]