阿里巴巴 fastjson-1.2.12.jar json解析异常java.lang.ClassFormatError: Invalid method Code length 66865 in class file com/alibaba/fastjson/serializer/ASMSerializer_6_UserKdlb
之前在线上用的版本是fastjson-1.2.7.jar 一切正常,更换以后时间解析看似一切正常。
因为在系统中设计json反序列化的地方比较多,刚刚放到生产环境,app那边的接口报错了
- java.lang.ClassFormatError: Invalid method Code length 66865 in class file com/alibaba/fastjson/serializer/ASMSerializer_6_UserKdlb
- at java.lang.ClassLoader.defineClass1(Native Method)
- at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
- at com.alibaba.fastjson.util.ASMClassLoader.defineClassPublic(ASMClassLoader.java:174)
- at com.alibaba.fastjson.serializer.ASMSerializerFactory.createJavaBeanSerializer(ASMSerializerFactory.java:396)
- at com.alibaba.fastjson.serializer.SerializeConfig.createASMSerializer(SerializeConfig.java:95)
- at com.alibaba.fastjson.serializer.SerializeConfig.createJavaBeanSerializer(SerializeConfig.java:163)
- at com.alibaba.fastjson.serializer.SerializeConfig.createJavaBeanSerializer(SerializeConfig.java:117)
- at com.alibaba.fastjson.serializer.SerializeConfig.getObjectWriter(SerializeConfig.java:504)
- at com.alibaba.fastjson.serializer.SerializeConfig.getObjectWriter(SerializeConfig.java:320)
- at com.alibaba.fastjson.JSON.toJSON(JSON.java:884)
- at com.alibaba.fastjson.JSON.toJSON(JSON.java:812)
- at com.alibaba.fastjson.JSON.toJSON(JSON.java:853)
- at com.alibaba.fastjson.JSON.toJSON(JSON.java:812)
- at com.alibaba.fastjson.JSON.toJSON(JSON.java:840)
- at com.alibaba.fastjson.JSON.toJSON(JSON.java:812)
- at com.alibaba.fastjson.JSON.toJSON(JSON.java:892)
- at com.alibaba.fastjson.JSON.toJSON(JSON.java:812)
- at com.xxx.pointlocationapp.controller.AppPointLocationControllerNew.getList(AppPointLocationControllerNew.java:204)
- at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
- at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
- at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
- at java.lang.reflect.Method.invoke(Method.java:498)
- at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
- at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
- at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
- at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:832)
- at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:743)
- at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
- at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:961)
- at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:895)
- at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967)
- at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:869)
- at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
- at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843)
- at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
- at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)
- at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
- at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
- at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
- at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
- at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121)
- at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
- at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
- at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
- at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
- at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:94)
- at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:492)
- at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
- at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
- at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:620)
- at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
- at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:502)
- at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1152)
- at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:684)
- at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1539)
- at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1495)
- at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
- at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
- at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
找到相应的方法,签名如下
- @RequestMapping("/list")
- @ResponseBody
- public JSONObject getList(@RequestBody String body, UserKdlb userKdlb, Pager<UserKdlb> pagers,
- HttpServletRequest request, HttpServletResponse response) {
- AppUtils.setHeader(request, response);
- JSONObject obj = null;
- ReturnParam rp = new ReturnParam();
- ...
- obj = (JSONObject) JSON.toJSON(rp);
- return obj;
- }
这是一直运行的代码,按常理来说如果有bug早就反应出来了。
codereview发现,这个json对象之前的步骤中插入一个list,相关代码如下
- List<UserKdlb> list = null;
- public class UserKdlb implements Serializable{
- private Byte pre_distribution_work_for_outsourcing_companies;//建设外包公司预分配工作
- private String company_employees_must_complete_the_commissioning_time;//公司员工调试必须完成时间
- //室外周报关联查询列表添加页面显示字段
- private Integer number_of_points_entered_into_outdoor_construction_sites;
- //室外点位资料字表对应字段;
- private List<PointLocationFaultRecord> ltPLFR;
- //管理合同表查询此字段进而在页面显示样式,点位表f_htbh 存的可能是合同关联字段,也可能是项目关联字段,所以要查询两次;
- private String whxfxq;
- //关联点位子记录最新一条添加记录显示列
- private String estimated_date_of_repair;//预计修复日期
- private String dname;//同一故障点位名称
- private String application_stop_instruction;//申请停用说明
- private String son_estimated_date_of_repair;//子记录最新预计修复日期
- private String son_application_stop_instruction;//子记录申请停用说明
- //最新连接时间
- private String ping_time;
- private int prediction_and_debugging_amount;//(预-调试完)总量
- private int debugging_completion_difficulty;//调试完成难度
- private int count;//项目数量
- private int sum;//项目和
- private int count_percent;
- private float total_commissioning_percent;
- private float debugging_completion_difficulty_percent;
- private float prediction_and_debugging_amount_percent;
- private float prediction_and_debugging_difficulty_percent;
- private Float projectPoints;//项目金额
- private Integer projectCount;//项目个数
网上的说法是方法名太长,超过了65535(2^16-1,64K),里面有很多参数名比较长,可能在生成Getter/Setter时候过长,报错了。
由于记录这篇博文的时间比较仓促,笔者没有时间去深究java中方法(method)相关的结构信息,各位看官可以去了解一下
https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.6
https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.3
经过在网上一番搜索,说是非java编译生成的类,在运行时被进行检测,防止有恶意代码被注入。
Start-up time, I'd say. Verification that classes are correct takes some time when the class is loaded. Since classes might be loaded in a lazy fashion (not on app start, but when being used for the first time), this might cause unexpected and undesired runtime delays.
Actually the class does not need to be checked in general. The compiler will not emit any invalid bytecode or class construct. The reason for verification is that the class may be build on one system, get hosted online and is transmitted to you through the unprotected internet. On this path, a malicious attacker might modify the bytecode and create something the compiler might never create; something that can crash the JVM or possibly circumvents security restrictions. Thus the class is verified before it is used. If this is a local application, there is usually no need to check the bytecode again.
JVM加载class文件时会做字节码校验(bytecode verification)。这篇文档非常详细地讲了JVM会做哪些校验。 如果你的class文件是由java源文件通过javac编译出来的,那么基本上不用担心bytecode verification。 如果class文件是由asm、cglib等动态生成出来的或者由其它编译器生成的,那么JVM在校验它的bytecode时就有可能失败。 失败的原因可能是你生成的bytecode有bug,也可能是由于新版本的JVM加入了新的验证条件后导致原来可以通过验证的bytecode现在不能通过了。
很多Java框架都会动态生成class文件,再加上JVM版本也会时不时地修改它的bytecode verification行为。 所以,运行代码时偶尔会遇到
java.lang.VerifyError
错误。 在不能修改框架代码或者切换JVM实现的情况下,JVM提供了一些选项可以让你改变或者绕过bytecode verification。-XX:-UseSplitVerifier
-XX:-UseSplitVerifier
可以让JVM不开启“type-checking verifier”。 这样就不强制要求class文件含有StackMapTable(所有Java 7 version 51之后的class文件默认要求含有StackMapTable)。-noverify
-noverify
选项可以关闭bytecode verification。有的观点认为某些bytecode verification除了给动态生成bytecode增加麻烦之外,并没有什么大用。 但是这篇文章强烈建议不要关闭bytecode verification,特别是在生产环境里。 因为bytecode verification可以检测到恶意代码或者代码中的bug。 特别是代码中的bug,因为没有人可以保证(动态产生的)字节码是百分百bug free的。
回到我的问题,由于
PactProviderRule
类来自于外部依赖,CI上的JVM也不能替换 (CI上用的是非oracle的JVM实现,该测试代码在本地的官方JVM上是可以运行通过,所以CI上的失败有一定可能是其用的JVM实现的原因), 所以一个简单的方法是在maven跑测试代码时,给JVM加上-noverify
选项。
按照以上方法给jvm加了参数 -noverify -XX:-UseSplitVerifier启动后并未凑效也没解决问题。
最终放弃添加jvm参数,按照官方的bug修复跟踪,替换成了1.2.13版本了,修复代码在167行,至此,线上正常接口运行了。
相关参考:
Ensuring JVM method size limit is never exceeded #661
Use of -noverify when launching java apps
阿里巴巴 fastjson-1.2.12.jar json解析异常java.lang.ClassFormatError: Invalid method Code length 66865 in class file com/alibaba/fastjson/serializer/ASMSerializer_6_UserKdlb的更多相关文章
- maven项目依赖其他jar包的时候,idea运行没问题,java -jar 报错:java.lang.SecurityException: Invalid signature file digest
当项目依赖其他jar包的时候,打出的jar包执行出错,抛出这个异常. 原因:因为依赖jar包中的META-INF中有多余的.SF文件与当前jar包冲突, 解决方案 一 在打包前删除依赖jar包的.SF ...
- 执行打的maven jar包时出现“Exception in thread "main" java.lang.SecurityException: Invalid signature file digest for Manifest main attributes”
Exception in thread "main" java.lang.SecurityException: Invalid signature file digest for ...
- struts2 action中字符串转json对象出错 java.lang.NoClassDefFoundError: org/apache/commons/lang/exception/NestableRuntimeException
commons-lang包有错,要么是引入错误,要么是没引入. 报不同错误,引入不同包. commons-beanutils-1.8.0.jar不加这个包 java.lang.NoClassDefFo ...
- 【转】Android中引入第三方Jar包的方法(java.lang.NoClassDefFoundError解决办法)
原文网址:http://www.blogjava.net/anchor110/articles/355699.html 1.在工程下新建lib文件夹,将需要的第三方包拷贝进来.2.将引用的第三方包,添 ...
- 【Java】java运行jar时,报 java.lang.UnsupportedClassVersionError
问题现象: java运行jar时,报 java.lang.UnsupportedClassVersionError java -jar main.jar -h 192.168.221.171 - ...
- Intellij打包jar文件,“java.lang.SecurityException: Invalid signature file digest for Manifest main attrib
下面是使用Intellij 打包jar文件的步骤,之后会有运行jar文件时遇到的错误. 打包完成. ================================================== ...
- 封装jar问题java.lang.SecurityException: Invalid signature file digest for Manifest main attributes以及maven依赖重提解决
1.jar包封装完成后,其他项目引用jar,启动时报错java.lang.SecurityException: Invalid signature file digest for Manifest m ...
- idea的jar文件,“java.lang.SecurityException: Invalid signature file digest for Manifest main attribute
感谢大佬:https://blog.csdn.net/mingyuli/article/details/84674483 命令行运行jar出现问题: 1.找不到主类.打开jar文件包,在MANIFES ...
- 十七、springboot配置FastJson为Spring Boot默认JSON解析框架
前提 springboot默认自带json解析框架,默认使用jackson,如果使用fastjson,可以按照下列方式配置使用 1.引入fastjson依赖库: maven: <dependen ...
随机推荐
- Can you answer these queries V SPOJ - GSS5 (分类讨论+线段树维护区间最大子段和)
recursion有一个整数序列a[n].现在recursion有m次询问,每次她想知道Max { A[i]+A[i+1]+...+A[j] ; x1 <= i <= y1 , x2 &l ...
- java线程基础巩固---Thread API综合实战之编写ThreadService实现暴力结束线程
上篇中在最后抛出一个问题,具体问题可以查看此篇[http://www.cnblogs.com/webor2006/p/7995229.html],这里不再概述,其实要实现这个需求可以用咱们之前学习的守 ...
- VUE-练习
作业一:有红黄蓝三个按钮,以及一个200*200矩形box,点击不同按钮,box的颜色会被切换为指定的颜色 <!DOCTYPE html> <html lang="en&q ...
- Newnode's NOI(P?)模拟赛 第三题 (主席树优化建图 + tarjan)
题目/题解戳这里 这道题题目保证a,b,ca,b,ca,b,c各是一个排列-mdzz考场上想到正解但是没看到是排列,相等的情况想了半天-然后写了暴力60分走人- 由于两两间关系一定,那么就是一个竞赛图 ...
- java学习记录--ThreadLocal使用案例(转)
本文借由并发环境下使用线程不安全的SimpleDateFormat优化案例,帮助大家理解ThreadLocal. 最近整理公司项目,发现不少写的比较糟糕的地方,比如下面这个: public class ...
- Codeforces 833B / B34D The Bakery
题 OwO http://codeforces.com/contest/833/problem/B 解 首先读入的时候把数据读入到2 ~ n+1的位置(因为线段树处理不到0,所以后移了一格) dp[i ...
- Vue:选中商品规格改变字体和边框颜色(默认选中第一种规格)
效果图: CSS: <div class="label"> <p>标签类别</p> <ul> <li v-for=" ...
- 「HNOI2014」世界树
题目链接 问题分析 首先观察数据范围可以知道要用虚树.但是要考虑怎么维护原树的距离信息. 如果只有两个关键点,我们可以很方便地找到中点将整棵树划分为两部分.而如果有多个关键点,看起来有效的方法就是多源 ...
- JavaWeb-RESTful(三)_使用SpringMVC开发RESTful_下
JavaWeb-RESTful(一)_RESTful初认识 传送门 JavaWeb-RESTful(二)_使用SpringMVC开发RESTful_上 传送门 JavaWeb-RESTful(三)_使 ...
- 微信小程序_(组件)swiper轮播图
微信小程序swiper轮播图组件官方文档 传送门 Learn: swiper组件 一.swiper组件 indicator-dots:是否显示面板指示点[默认值false] autoplay:是否自动 ...