一次BUG定位的过程与总结
当前,现场运行的版本是B110,B110是5月24日发出去的。与B110同步拉了一个B111分支,用来定位B110的问题,并出补丁
今天现场发回了一个BUG,定位出来是ClassA出的问题,由于ClassA是个很少会改动的类,头脑一时发晕,就直接在主干上修改,出了补丁发到现场
结果这个问题解决了,却引入了一个新问题。有一段代码一直进不去,异常如下:
Caused by: java.lang.NoSuchMethodError: com.xxx.service.EndVerifyService.execute(Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/String;)Lnet/sf/json/JSONObject;
at cz.xxx.services.inbound_webservices_tickets.v1_0.saservice.InboundWebServicesTicketSaServiceSoapImpl.ttEndVerifyService(InboundWebServicesTicketSaServiceSoapImpl.java:135)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:166)
at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:82)
定位了一下,发现以下代码:
String pId = "abc";String str = XXXConstants.XXX + pId;
那现在一共只发到现场以下3个.class:主干上的ClassA、ClassB、InterfaceB,根本就没有发XXXConstants过去,怎么ClassB不报错呢?
后来想到了,ClassB是在主干上编译的,所以主干上的XXXConstants.XXX,已经作为常量编译到ClassB里了,不需要发补丁到现场
总结:
1、一定要根据实际运行的环境出补丁。像今天这种情况,现场跑的代码是B110版本,主干上的代码已经比B110推进了好多天,2套代码根本就不一致。如果我今天是从B111版本上出补丁,那后面的麻烦事就都没有了
2、如果方法进不去,检查一下这个方法的参数是否正确
3、发补丁时,不能只发修改的类,要把相关的类一起提交
4、要小心static常量的陷阱,比如在ClassC里,有一个String str = XXXConstants.XXX,然后已经编译成了ClassC.class,那str的值就已经确定了。这个时候再去修改XXXConstants.XXX的值,不会对ClassC.class产生影响