Closed ferdiknight closed 12 years ago
呃, 我看不太懂你问题的重点是什么?
我的假设是, 你使用trace -d
跟踪某个方法(能够说明是哪个吗?), 然后输出错误com.alibaba.fastjson.JONException:illegal getter
, 那么现在如果是我, 我会去问fastjson
的作者@wenshao 什么情况会抛出这样的异常.
或者, 请查看fastjson
的源码找寻原因.
PS: 如果你是使用版本0.2.4
, 请在出现上面的错误后, 使用last
命令查看错误信息的完整堆栈帮助分析原因.
PS: 下次提交issue
, 麻烦将代码内容使用下面的Markdown语法优化一下显示, 方便我阅读, 谢谢.
```java
some code
啊,抱歉,是我没表述清楚,那个fastjson的异常并不是来自我的代码,而是trace -d 在输出时序列化RelationChangeEvent这个参数对象的时候报的异常,是housemd抛出的异常
然后我本身对这个事件对象做序列化的时候也是用的fastjson,所以现在想请问下housemd在trace -d的时候是用的fastjson的哪个方法序列化对象的
跟踪的 public void onRelationChange(RelationEvent event) 这样一个方法,RelationChangeEvent 是 RelationEvent 的实现
现在的现象就是 trace是没问题的,但是-d 就会抛出这个异常,我猜大概是-d 时housemd输出是用标准的java bean格式去序列化的,所以append形式的get方法会抛异常
呃,点错按钮了……
com.alibaba.fastjson.JSONObject.invoke(JSONObject.java:397) $Proxy10.toString(Unknown Source) java.lang.String.valueOf(String.java:2826) scala.collection.mutable.StringBuilder.append(StringBuilder.scala:187) scala.collection.TraversableOnce$$anonfun$addString$1.apply(TraversableOnce.scala:300) scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:34) scala.collection.mutable.ArrayOps.foreach(ArrayOps.scala:38) scala.collection.TraversableOnce$class.addString(TraversableOnce.scala:298) scala.collection.mutable.ArrayOps.addString(ArrayOps.scala:38) scala.collection.TraversableOnce$class.mkString(TraversableOnce.scala:263) scala.collection.mutable.ArrayOps.mkString(ArrayOps.scala:38) com.github.zhongl.housemd.command.DetailWriter.write(Trace.scala:155) com.github.zhongl.housemd.command.Trace$$anon$1.exitWith(Trace.scala:71) com.github.zhongl.housemd.command.TransformCommand$$anon$2.exitWith(TransformCommand.scala:61) com.github.zhongl.housemd.instrument.Transform$$anonfun$handleAdviceEvent$1.apply(Transform.scala:87) com.github.zhongl.housemd.instrument.Transform$$anonfun$handleAdviceEvent$1.apply(Transform.scala:83) scala.actors.Actor$class.receiveWithin(Actor.scala:630) scala.actors.ActorProxy.receiveWithin(ActorProxy.scala:20) scala.actors.Actor$.receiveWithin(Actor.scala:208) com.github.zhongl.housemd.instrument.Transform.handleAdviceEvent(Transform.scala:83) com.github.zhongl.housemd.instrument.Transform.apply(Transform.scala:67) com.github.zhongl.housemd.command.TransformCommand.run(TransformCommand.scala:65) com.github.zhongl.yascli.Suite$class.run(Suite.scala:51) com.github.zhongl.yascli.Shell.run(Shell.scala:27) com.github.zhongl.yascli.Shell.parse$1(Shell.scala:50) com.github.zhongl.yascli.Shell.interact(Shell.scala:58) com.github.zhongl.yascli.Shell.main(Shell.scala:33) com.github.zhongl.housemd.duck.Telephone.run(Telephone.scala:54) java.lang.Thread.run(Thread.java:662)
根据异常堆栈信息:
com.github.zhongl.housemd.command.DetailWriter.write(Trace.scala:155)
可以看出trace -d
在尝试输出方法参数值, 但HouseMD
不会采用Java Bean
的方式序列化对象, 而是调用值对象的toString()
方法.
根据提供异常堆栈的信息前两行:
com.alibaba.fastjson.JSONObject.invoke(JSONObject.java:397) $Proxy10.toString(Unknown Source)
你跟踪的应用中, 可能存在有AOP的机制改写toString()
方法的实现, 即调用fastjson
来输出对象的字符串内容, 但fastjson
报错了.
所以, 这应该不是HouseMD
的问题, 而是实现没能很好的覆写toString
方法, 而这个问题被HouseMD
暴露出来了.
嗯,找到问题了~谢谢你的帮助~ 是fastjson parseObject的时候传入了接口的class实列,反序列化的时候不会抛异常,但是之后调用的所有方法都会被fastjson拦截,然后invoke只去解析setter和getter方法,所以toString就会直接抛异常了。
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Class<?>[] parameterTypes = method.getParameterTypes();
if (parameterTypes.length == 1) {
Class<?> returnType = method.getReturnType();
if (returnType != void.class) {
throw new JSONException("illegal setter");
}
String name = null;
JSONField annotation = method.getAnnotation(JSONField.class);
if (annotation != null) {
if (annotation.name().length() != 0) {
name = annotation.name();
}
}
if (name == null) {
name = method.getName();
if (!name.startsWith("set")) {
throw new JSONException("illegal setter");
}
name = name.substring(3);
if (name.length() == 0) {
throw new JSONException("illegal setter");
}
name = Character.toLowerCase(name.charAt(0)) + name.substring(1);
}
map.put(name, args[0]);
return null;
}
if (parameterTypes.length == 0) {
Class<?> returnType = method.getReturnType();
if (returnType == void.class) {
throw new JSONException("illegal getter");
}
String name = null;
JSONField annotation = method.getAnnotation(JSONField.class);
if (annotation != null) {
if (annotation.name().length() != 0) {
name = annotation.name();
}
}
if (name == null) {
name = method.getName();
if (name.startsWith("get")) {
name = name.substring(3);
if (name.length() == 0) {
throw new JSONException("illegal getter");
}
name = Character.toLowerCase(name.charAt(0)) + name.substring(1);
} else if (name.startsWith("is")) {
name = name.substring(2);
if (name.length() == 0) {
throw new JSONException("illegal getter");
}
name = Character.toLowerCase(name.charAt(0)) + name.substring(1);
} else {
throw new JSONException("illegal getter");
}
}
Object value = map.get(name);
return TypeUtils.cast(value, method.getGenericReturnType(), ParserConfig.getGlobalInstance());
}
throw new UnsupportedOperationException(method.toGenericString());
}
目标事件对象,setter getter使用了append模式,但是我系统内消息服务的时候就是用的fastjson做json序列化,fastjson-1.1.18