下面是在利用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
相关推荐
一套个人在敏捷开发中总结的敏捷开发流程规范与流程每一步的输出制品。
一、shell命令 1、内建命令 2、外部命令 3、实用程序 4、用户程序 5、shell脚本 二、命令帮助文档 1、命令自身的帮助功能 2、man手册 3、在线帮助文档 三、分类介绍 (一)文件、目录操作命令 (二)查看文件内容...
此报告是一个建议的软件项目开发总结报告格式,。里面的内容是本人项目开发实习自己的一个总结,非常粗糙。
历年自考软件开发工具汇总 答案只有一部分历年自考软件开发工具汇总 答案只有一部分
Android是一种基于Linux的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由Google公司和开放手机联盟领导及开发。尚未有统一中文名称,中国大陆地区较多人使用“安卓”或“安致”。...
它是为了解决企业应用开发的复杂性而创建的。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。 Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,可以应用在任何使用...
今天在Visual Studio 2008中调试某个程序时遇到一个奇怪问题 就是在某个源文件中设置的断点老是无效,提示“当前不会命中断点。源代码与原始版本不同”信息 清理项目、重编项目、重新拷贝原文件都解决不了问题 ...
一位工程师的FPGA项目开发经验总结 fpga开发.pdf
最新开发资料的一个汇总,一个很好的开发资料的帮助,一个帮助格式的wp资料的开发8
android安卓app开发教程之--总结了50条安卓开发经验.zip 34. 建议整个应用维护一个dbhelper实例,只要db没有关闭,全局就只有一个db实例,多线程并发写入db不会lock,严格交替进行写入:123123123。。。(123代表...
AndroiBLE开发总结: 在Android BLE开发中,设备、服务、特征和描述它们之间的关系如下: - 设备(Device):指BLE设备,如蓝牙耳机、传感器等。 - 服务(Service):指BLE设备所提供的服务,一个BLE设备可以提供多...
敏捷软件开发是一个开发软件的管理新模式,用来替代以文件驱动开发的瀑布开发模式。 敏捷开发集成了新型开发模式的共同特点,它重点强调: 1.敏捷就是“快”。快才可以适应目前社会的快节奏,要快就要发挥个人的...
花了很大的经历,搜集并整理了v4l2开发的文档,这些文档写的比较好,并非网上胡编乱造乱转发的资料,先汇总后共享给大家,资源列表: ①linux驱动学习笔记Camif ②V4L2 spec 中文 v0.625 ③v4l2-api-document ④v4l2...
华为鸿蒙HarmonyOS开发整理资料汇总,共38份。 1学前必读:HarmonyOS学习资源主题分享 2学前必读:OpenHarmony-联盟生态资料合集 3-1.HarmonyOS概述:技术特性 3-2.HarmonyOS概述:开发工具与平台 3-3.HarmonyOS...
年终将至,上传一个给大家。程序员年终总结,个人总结,个人年终总结
tomcat 8 直接启动startup.bat 一闪没有了 eclipse 新建项目把原来的代理复制进去编译出现classNotFound 异常 数据库链接加密处理 springMVC 多数据源配置 springMVC与mybatis整合 inux 启动tomcat 进入tomcat安装...
nc开发过程中的问题总结, 1、在单据中添加字段 2、单据添加定义自定义按钮 3、在报表查询面板上添加一个条件
每天在写Java程序, 其实里面有一些细节大家可能没怎么注意, 这不, 有人总结了一个我们编程中常见的问题. 虽然一般没有什么大问题, 但是最好别这样做.
蓝桥杯 第八届到第十一届 嵌入式设计与开发项目 省赛 决赛 客观试题 答案 汇总 第十一届 蓝桥杯 嵌入式设计与开发项目 决赛 第一部分 客观试题(30 分) 大学组 1) 以下电路反映了哪种逻辑关系( A )。 A. F = A · B ...
一..HTML 页面转UTF-8 编码问题 二.PHP 页面转UTF-8 编码问题 三.MYSQL 数据库使用UTF-8 编码的问题 四.JS 相关的UTF-8 编码问题 五.FLASH 相关的UTF-8 编码问题 内容来自互联网 LAMP 中国QQ 群: 34513293 WEB 前端...