下面是在利用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
相关推荐
Java开发乱码问题解决方法汇总 ...Java开发乱码问题解决方法汇总中,我们总结了七种常见的解决方法。这些方法可以帮助读者避免乱码问题的发生。如果读者在实际开发中遇到乱码问题,可以尝试使用这些方法来解决问题。
Android 开发中常见的小问题总结 一、 Android 开发中 ProgressBar 的问题 在 Android 开发中,我们经常会遇到 ProgressBar 的问题,例如在设置控件 ProgressBar 时出现 “cannot cast from view to progressbar”...
eclipse插件开发经验汇总 ...本文档旨在为读者提供一个详细的eclipse插件开发经验总结,涵盖了SWT、JFace、EMF、Eclipse Forms等多个方面的开发笔记和经验总结,旨在帮助读者快速掌握eclipse插件开发的技术。
项目开发总结报告是软件开发过程中的重要文档,它详尽记录了项目的整个生命周期,包括从需求分析、设计、实现、测试到上线维护等各个阶段的关键活动、遇到的问题、解决方案以及项目成果。以下是对项目开发总结报告...
【软件项目开发总结报告】 软件项目开发总结报告的目的是对已完成的软件开发过程进行回顾,以便于团队在后续的项目中汲取经验教训,提升开发效率和产品质量。本报告以XXX公司的业务管理系统为例,涵盖项目背景、...
### 移动端开发工作总结与计划 #### 一、2015年工作总结 ##### 工作成就 - **项目完成情况**:2015年,在网络部领导的指导下,王俊林作为软件工程师成功完成了“兰州金易信息科技有限责任公司”门户网站及手机...
在开发过程中,开发者经常会遇到一些常见问题,本文将针对微信小程序点餐系统开发的后台开发相关问题进行汇总,并提供相应的解决方法。 首先,涉及到的问题是Java后台开发中的lombok包不存在的问题。Lombok是一个...
### Bug管理系统项目开发总结报告知识点解析 #### 一、引言 - **开发目的**: 随着信息技术的快速发展,软件应用已经渗透到社会的各个方面。在这个背景下,软件错误(通常称为“Bug”)的范围和可能性也随之扩大。...
【标题】中的“最新开发资料的一个汇总”表明这是一个集合了近期IT开发领域的各种参考资料的压缩包,可能包含最新的编程语言教程、框架更新说明、最佳实践指南等。而“一个很好的开发资料的帮助”则暗示这些资料对...
### 计算机软件开发实习报告总结中的关键知识点 #### 一、角色转换与适应社会 - **从校园到职场的转变**:实习生从学生身份转变为职场人士,需要学会适应不同的社会角色。在学校,主要任务是学习知识;而在职场,则...
### JAVA开发工具大汇总 #### 1. JDK (Java Development Kit) **简介**: JDK是由Sun Microsystems提供的免费Java开发工具包,随着Oracle收购Sun后继续维护和发展。它为开发者提供了丰富的语言特性和运行环境,同时...
在2015年度,软件开发部的质量工作围绕着几个关键目标展开,包括项目一次通过率98%以上,...这一年度工作总结不仅是对过去一年工作的反思,也是对未来改进方向的规划,彰显了软件开发部致力于高质量软件开发的决心。
基于Vue.js的跨平台多端应用前端框架uni-app一站式开发资源汇总 基于Vue.js的跨平台多端应用前端框架uni-app一站式开发资源汇总 基于Vue.js的跨平台多端应用前端框架uni-app一站式开发资源汇总 基于Vue.js的跨平台多...
本项目的意义在于为开发者提供一个开发移动应用程序的详细过程,安排精度、组织软件和开发与测试,撰写项目总结报告。该项目可以帮助开发者更好地理解软件开发的详细过程,并提供一个实用的移动应用程序的开发经验。...
一套个人在敏捷开发中总结的敏捷开发流程规范与流程每一步的输出制品。
《软件项目开发总结报告》是一份详实记录软件开发过程及其成果的重要文档,它涵盖了项目的整个生命周期,包括从启动到结束的各个阶段。本报告由作者XXXXX在2009年12月完成,旨在对进销存管理系统的开发进行回顾与...
MAPGIS二次开发常见问题汇总 本文档汇总了MAPGIS二次开发中常见的问题和解决方案,涵盖了Delphi生成MAPGIS明码文件、ATT_STRU和CATT_STRU的区别、解决“不能打开子图库”问题、获取工作区图元号、使用NearPnt函数、...
综上所述,本文通过对作者在过去一年中参与项目的工作总结,不仅分享了项目经历和个人成长,还深入剖析了工作中遇到的主要问题及其解决方案,同时提供了宝贵的工作心得和教训,为未来的软件开发工作提供了有益的指导...
2. **文档的重要性**:良好的文档是软件开发流程中不可或缺的一部分,它包括需求文档、设计文档、用户手册等。实习生可能需要花费大量时间撰写技术文档,尽管这看似繁琐,但文档能确保团队对项目有共同的理解,减少...