下面是在利用JDK的Instrument来编写调试工具的时候出现的一些问题总结
1、java.io.Console 类的读取操作将会阻塞掉写入操作,造成写入操作不能异步进行。
原因是该类中加入了读写锁。代码如下:
public String readLine(String fmt, Object ... args) { String line = null; synchronized (writeLock) { synchronized(readLock) { if (fmt.length() != 0) pw.format(fmt, args); try { char[] ca = readline(false); if (ca != null) line = new String(ca); } catch (IOException x) { throw new IOError(x); } } } return line; }
2、Class.getSimpleName 方法在scala 下有可能抛出异常
例如:
Exception in thread "agent thread" java.lang.InternalError: Malformed class name at java.lang.Class.getSimpleName(Class.java:1133) at cn.zhxing.trace.agent.instrument.ClassFilter.match(ClassFilter.java:41) at cn.zhxing.trace.util.InstrumentUtil.findMatchClassAndMethods(InstrumentUtil.java:111) at cn.zhxing.trace.agent.command.LoaderCommand.run(LoaderCommand.java:40) at cn.zhxing.trace.agent.Client.listen(Client.java:43) at cn.zhxing.trace.agent.Main$1.run(Main.java:62) at java.lang.Thread.run(Thread.java:662)
经过查询发现该类为:scala.collection.SeqLike$$anonfun$occCounts$1,这类有个特征是连续有两个$符号,正是这个情况导致。网上也有类似的错误:http://www.scala-lang.org/node/7691
3、asm.jar使用中有可能出现ClassNotFoundException 的异常(在使用instrument的时候容易出现)
例如下面的方法,调用accept的时候抛出
ClassReader reader = new ClassReader(classfileBuffer); ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_FRAMES); reader.accept(vistor, ClassReader.SKIP_FRAMES);//error
异常堆栈部分如下:
TraceTransformer:reader.acceptjava.lang.RuntimeException: java.lang.ClassNotFoundException: exceptions/ServiceException at org.objectweb.asm.ClassWriter.getCommonSuperClass(Unknown Source) at org.objectweb.asm.ClassWriter.a(Unknown Source) at org.objectweb.asm.Frame.a(Unknown Source) at org.objectweb.asm.Frame.a(Unknown Source) at org.objectweb.asm.MethodWriter.visitMaxs(Unknown Source) at org.objectweb.asm.commons.LocalVariablesSorter.visitMaxs(Unknown Source) at cn.zhxing.trace.agent.instrument.MethodInstrument.visitMaxs(MethodInstrument.java:137) at org.objectweb.asm.ClassReader.accept(Unknown Source) at org.objectweb.asm.ClassReader.accept(Unknown Source)
仔细分析了asm的代码发现,代码如下:
protected String getCommonSuperClass(final String type1, final String type2) { Class<?> c, d; ClassLoader classLoader = getClass().getClassLoader(); try { //这里可以看出classloader是直接在getClass().getClassLoader();中获取的本地classloader,如果该class不在该classloader中时就会出现异常 c = Class.forName(type1.replace('/', '.'), false, classLoader); d = Class.forName(type2.replace('/', '.'), false, classLoader); } catch (Exception e) { throw new RuntimeException(e.toString()); } if (c.isAssignableFrom(d)) { return type1; } if (d.isAssignableFrom(c)) { return type2; } if (c.isInterface() || d.isInterface()) { return "java/lang/Object"; } else { do { c = c.getSuperclass(); } while (!c.isAssignableFrom(d)); return c.getName().replace('.', '/'); } }
修改如下:
新建一个新的Class 继承ClassWriter,重写getCommonSuperClass 方法,如下:
public class TraceClassWriter extends ClassWriter { //省略其他代码 public TraceClassWriter(ClassReader classReader, int flags, ClassLoader loader) { super(classReader, flags); this.loader = loader; } protected String getCommonSuperClass(final String type1, final String type2) { Class c, d; try { c = Class.forName(type1.replace('/', '.'), true, loader); d = Class.forName(type2.replace('/', '.'), true, loader); } catch (Exception e) { logger.error(e, "type1=%s,type2=%s,loader=%s", type1, type2, loader); throw new RuntimeException(e.toString()); } if (c.isAssignableFrom(d)) { return type1; } if (d.isAssignableFrom(c)) { return type2; } if (c.isInterface() || d.isInterface()) { return "java/lang/Object"; } else { do { c = c.getSuperclass(); } while (!c.isAssignableFrom(d)); return c.getName().replace('.', '/'); } } }
使用的时候是这样:
ClassReader reader = new ClassReader(classfileBuffer); //由外部传入classloader ClassWriter writer = new TraceClassWriter(reader, ClassWriter.COMPUTE_FRAMES,loader); reader.accept(vistor, ClassReader.SKIP_FRAMES);
类似错误也可看:http://www.avaje.org/topic-180.html
相关推荐
Android 开发中常见的小问题总结 一、 Android 开发中 ProgressBar 的问题 在 Android 开发中,我们经常会遇到 ProgressBar 的问题,例如在设置控件 ProgressBar 时出现 “cannot cast from view to progressbar”...
eclipse插件开发经验汇总 ...本文档旨在为读者提供一个详细的eclipse插件开发经验总结,涵盖了SWT、JFace、EMF、Eclipse Forms等多个方面的开发笔记和经验总结,旨在帮助读者快速掌握eclipse插件开发的技术。
项目开发总结报告是软件开发过程中的重要文档,它详尽记录了项目的整个生命周期,包括从需求分析、设计、实现、测试到上线维护等各个阶段的关键活动、遇到的问题、解决方案以及项目成果。以下是对项目开发总结报告...
Electron-Vue 开发环境内存泄漏问题汇总 本文主要介绍了 Electron-Vue 开发环境中内存泄漏问题的解决方案。 Electron-Vue 是一个基于 Electron 和 Vue.js 的开发框架,用于构建桌面应用程序。然而,在开发环境中,...
【软件项目开发总结报告】 软件项目开发总结报告的目的是对已完成的软件开发过程进行回顾,以便于团队在后续的项目中汲取经验教训,提升开发效率和产品质量。本报告以XXX公司的业务管理系统为例,涵盖项目背景、...
### 移动端开发工作总结与计划 #### 一、2015年工作总结 ##### 工作成就 - **项目完成情况**:2015年,在网络部领导的指导下,王俊林作为软件工程师成功完成了“兰州金易信息科技有限责任公司”门户网站及手机...
在开发OPC(OLE for Process Control)客户端的过程中,开发者往往会面临一系列挑战,这些挑战涉及到通信协议、数据交换、错误处理等多个方面。以下是对OPC客户端开发中常见问题及解决方案的详细解析。 首先,理解...
在软件开发过程中,总结文档是至关重要的,它们记录了项目的全过程,包括设计思路、实现细节、测试策略以及问题解决方法,对于团队协作和项目维护都有着不可忽视的作用。本压缩包中的"wenben"文件可能是一个包含多种...
在开发过程中,开发者经常会遇到一些常见问题,本文将针对微信小程序点餐系统开发的后台开发相关问题进行汇总,并提供相应的解决方法。 首先,涉及到的问题是Java后台开发中的lombok包不存在的问题。Lombok是一个...
综上所述,本文通过对作者在过去一年中参与项目的工作总结,不仅分享了项目经历和个人成长,还深入剖析了工作中遇到的主要问题及其解决方案,同时提供了宝贵的工作心得和教训,为未来的软件开发工作提供了有益的指导...
### Bug管理系统项目开发总结报告知识点解析 #### 一、引言 - **开发目的**: 随着信息技术的快速发展,软件应用已经渗透到社会的各个方面。在这个背景下,软件错误(通常称为“Bug”)的范围和可能性也随之扩大。...
【标题】中的“最新开发资料的一个汇总”表明这是一个集合了近期IT开发领域的各种参考资料的压缩包,可能包含最新的编程语言教程、框架更新说明、最佳实践指南等。而“一个很好的开发资料的帮助”则暗示这些资料对...
### 计算机软件开发实习报告总结中的关键知识点 #### 一、角色转换与适应社会 - **从校园到职场的转变**:实习生从学生身份转变为职场人士,需要学会适应不同的社会角色。在学校,主要任务是学习知识;而在职场,则...
基于Vue.js的跨平台多端应用前端框架uni-app一站式开发资源汇总 基于Vue.js的跨平台多端应用前端框架uni-app一站式开发资源汇总 基于Vue.js的跨平台多端应用前端框架uni-app一站式开发资源汇总 基于Vue.js的跨平台多...
总结来说,Java项目开发中的常见问题涉及多个层面,从基本的编码规范到复杂的性能优化,再到框架的熟练运用。开发者需要不断学习和实践,以提升个人技能,减少问题的发生,从而提高项目的成功率和质量。通过规范的...
这一总结,不仅体现了我们对高质量软件开发的承诺,更代表了我们对未来持续创新和卓越追求的决心。在新的一年里,我们将一如既往地努力,以更加专业的态度,更加严谨的标准,迎接每一个挑战,创造更加辉煌的业绩。
一套个人在敏捷开发中总结的敏捷开发流程规范与流程每一步的输出制品。
《软件项目开发总结报告》是一份详实记录软件开发过程及其成果的重要文档,它涵盖了项目的整个生命周期,包括从启动到结束的各个阶段。本报告由作者XXXXX在2009年12月完成,旨在对进销存管理系统的开发进行回顾与...
本项目的意义在于为开发者提供一个开发移动应用程序的详细过程,安排精度、组织软件和开发与测试,撰写项目总结报告。该项目可以帮助开发者更好地理解软件开发的详细过程,并提供一个实用的移动应用程序的开发经验。...