- 浏览: 977092 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
运乃强谦:
老哥,你确定这个wsdl 地址 可以访问?
[CXF] Server与Client实现方式五:HTTPS -
wangyudong:
由CXF实现的微服务需要有比较好的工具去测试RESTful A ...
[CXF] Server与Client实现方式四:JMS -
dengmiao:
JAXB学习三 (验证) -
panamera:
你好。可以提供maven pom配置是怎么配置的?不知道你使用 ...
[CXF] Server与Client实现方式四:JMS -
u010221220:
请问楼主一二三部分的代码都应该放在哪个函数体中。
使用JDI监听Java程序运行
Java虚拟机提供了一套用于调试(JVMDI)和监视(JVMPI)的接口,Java5之后统一为JVMTI: http://docs.oracle.com/javase/1.5.0/docs/guide/jvmti/ 。
其中JVMDI分为三个部分:JVMDI,JDWP和JDI . http://docs.oracle.com/javase/1.4.2/docs/guide/jpda/architecture.html
这篇就是简单的介绍一下怎么使用JDI去监视程序的运行的。
首先假设有一个简单的程序:
package test; public class Test { public static void main(String[] args) { new Thread() { @Override public void run() { Test test = new Test(); while (true) { try { sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } test.printHello(); } } }.start(); } protected void printHello() { System.out.println("hello"); } }
程序中,每隔五秒种,printHello()方法就会执行一次。
如果你希望每次printHell()被执行的时候通知你一下,在不修改代码的情况下,你要怎么办?没办法吧?
看看JDI的定义:
JDI - Java Debug Interface Defines a high-level Java language interface which tool developers can easily use to write remote debugger applications.
所以首先,我们先以远程调试的方式启动上面的Test类:
java -Xdebug -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8800 -cp . test.Test
大致就是以socket传输的方式调试Test类,调试的连接端口为8800,并且连接过程不挂起。
一量启动,就可以看到如下的输出:
Listening for transport dt_socket at address: 8800 hello hello hello
这样Server被调试端就准备好了,下面就是写监听端了。这里就要用到jdk中提供的JDI接口了。要使用此接口,我们需要在类路径里包含JDK下的tools.jar等包,可以在<JDK>/lib目录下找着。
一、取得连接器
VirtualMachineManager vmm = Bootstrap.virtualMachineManager(); List<AttachingConnector> connectors = vmm.attachingConnectors(); SocketAttachingConnector sac = null; for (AttachingConnector ac : connectors) { if (ac instanceof SocketAttachingConnector) { sac = (SocketAttachingConnector) ac; break; } } if (sac == null) { System.out.println("JDI error"); return; }
二、连接到远程虚拟器
Map arguments = sac.defaultArguments(); Connector.Argument hostArg = (Connector.Argument) arguments.get(HOST); Connector.Argument portArg = (Connector.Argument) arguments.get(PORT); hostArg.setValue("127.0.0.1"); portArg.setValue(String.valueOf(8800)); vm = sac.attach(arguments);
三、取得要关注的类和方法
List<ReferenceType> classesByName = vm.classesByName("test.Test"); if (classesByName == null || classesByName.size() == 0) { System.out.println("No class found"); return; } ReferenceType rt = classesByName.get(0); List<Method> methodsByName = rt.methodsByName("printHello"); if (methodsByName == null || methodsByName.size() == 0) { System.out.println("No method found"); return; } Method method = methodsByName.get(0);
四、注册监听
vm.setDebugTraceMode(VirtualMachine.TRACE_EVENTS); vm.resume(); EventRequestManager erm = vm.eventRequestManager(); MethodEntryRequest methodEntryRequest = erm.createMethodEntryRequest(); methodEntryRequest.addClassFilter(rt); methodEntryRequest.setSuspendPolicy(EventRequest.SUSPEND_NONE); methodEntryRequest.enable(); BreakpointRequest breakpointRequest = erm .createBreakpointRequest(method.location()); breakpointRequest.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD); breakpointRequest.enable(); eventLoop();
这里监听每次方法入口的时候,以及在方法上注册一个断点,发一个通知。
四、eventLoop()的实现
private static void eventLoop() throws Exception { eventQueue = vm.eventQueue(); while (true) { if (vmExit == true) { break; } eventSet = eventQueue.remove(); EventIterator eventIterator = eventSet.eventIterator(); while (eventIterator.hasNext()) { Event event = (Event) eventIterator.next(); execute(event); } } } private static void execute(Event event) throws Exception { if (event instanceof VMStartEvent) { System.out.println("VM started"); eventSet.resume(); } else if (event instanceof BreakpointEvent) { System.out .println("Reach Method printHello of test.Test"); eventSet.resume(); } else if (event instanceof MethodEntryEvent) { MethodEntryEvent mee = (MethodEntryEvent) event; Method method = mee.method(); System.out.println(method.name() + " was Entered!"); eventSet.resume(); } else if (event instanceof VMDisconnectEvent) { vmExit = true; } else { eventSet.resume(); } }
最后看输出:
[JDI: EventSet: SUSPEND_EVENT_THREAD] [JDI: Event: MethodEntryEvent@test.Test:23 in thread Thread-0] [JDI: Event: BreakpointEvent@test.Test:23 in thread Thread-0] printHello was Entered! Reach Method printHello of test.Test [JDI: EventSet: SUSPEND_EVENT_THREAD] printHello was Entered! [JDI: Event: MethodEntryEvent@test.Test:23 in thread Thread-0] [JDI: Event: BreakpointEvent@test.Test:23 in thread Thread-0] Reach Method printHello of test.Test
发表评论
-
自定义Spring MVC中的数据绑定
2015-02-01 18:27 1432默认情况下,spring mvc的数据映射的实现是自动查找请 ... -
Java单例(Singleton)
2014-05-22 11:40 1855【译自:http://www.journaldev.com ... -
Java函数式编程学习二
2014-06-05 10:58 2621上一节里,介绍了一个函数接口: java.uti ... -
Java函数式编程学习一
2014-05-07 22:02 7299一、缺省方法 首先看一段用Java 8写的代码: ... -
快速排序的几种实现
2014-05-06 23:13 1612快速排序是最经典的 ... -
计算Fibonacci数列
2014-05-04 15:37 1601Fibonacci数列的定义如 ... -
(转)Java函数式编程系列文章
2014-04-11 16:52 698转载: Java函数式编程(一) Java函数式编程( ... -
Java中的动态代理
2014-04-02 15:11 2305在使用CXF的时候,尤其是创建针对REST或SOAP服务的 ... -
Java 7中的Path
2014-04-01 17:33 0package test; public ... -
HashMap对HashTable和ArrayList对Vector
2014-03-26 14:16 813有人面试总喜欢问比 ... -
Java国际化:BreakIterator
2014-03-21 11:51 2924【译自:http://tutorials.jenkov.c ... -
Java中使用StreamTokenizer
2014-03-21 09:44 3255按照Javadoc里的描述:StreamTokenizer ... -
Java中枚举的用法
2014-03-19 15:31 2750Java 5里新引用了枚举类型,这篇文章简单介绍一下它的基 ... -
Java线程类三
2014-03-06 11:18 1107一、Callable 最早创建线程要么是通过实现Runn ... -
Java线程类二
2014-03-05 14:21 1152一、java.util.concurrent.Exchan ... -
Java线程类一
2014-03-04 17:25 912一、java.util.concurrent.CountD ... -
基于Java的Dropbox文件操作
2014-01-22 11:15 4281Dropbox提供了基于各种类型的API和应用类型的开发工 ... -
使用特殊字符控制Console输出
2013-11-28 10:39 1024如果要在console上打印 Hello + 1到10,最简 ... -
控制JAXB的输入输出
2013-11-27 16:06 4054上一节介绍了如何在解析模型的时候构建模型之间的父子链,其实 ... -
JAXB中怎么构建对父对象的链接
2013-11-27 11:17 3525还是以在第一节介绍JAXB的schema为例: < ...
相关推荐
NULL 博文链接:https://fly-hyp.iteye.com/blog/1997213
JDIVisitor JDIVisitor是一个Java库,用于使用Java调试接口(JDI)和访问者设计模式来构建自定义调试器应用程序。 它从的项目中汲取了灵感。 但是,JDIVisitor避开了jdiscript的类似脚本的设计,而改用了更具Java...
JDI, JDI是用于UI测试自动化的测试框架 用户界面测试自动化框架 JavaCI 软件包 版权所有( c ) 2017,EPAM系统许可证:GPL版本的GPL许可。简介JDI - 是UI测试自动化的测试框架。 它扩展了页面对
JPDA(Java Platform Debugger Architecture)是 Java 平台调试体系结构的缩写,通过 JPDA 提供的 API,开发人员可以方便灵活的搭建 Java 调试应用程序。 JPDA 主要由三个部分组成:Java 虚拟机工具接口(JVMTI),...
直接在桌面适用的JAVA反编译工具。将JAR包或者CLASS文件拖进去即可以反编译成JAVA代码。
jdi - 一个JavaScript的文档生成器
git-2.19.0-64-bit,
利用JDI的接口,在不修改现有程序代码的情况,可以跟踪java Thread中的method 调用及exception的工具,使用方式很简单,先使用以下方式启动要跟踪调试的JAVA 应用 * java -classpath %JAVA_HOME%/lib/tools.jar;. -...
解决Failed to connect to remote VM com.sun.jdi.connect.spi.ClosedConnectionException错误,tomcat远程调试
jdi借鉴了ios输出口的概念,与其他框架使用注解实现绑定不同, jdi明确规定了绑定规则,绑定规则的基础是jdi规定的项目结构 和控件id的命名规则.规范开发行为. 注:jdi为控件绑定和业务对象类文件生产提供了相应的生成...
JPDA(Java Platform Debugger Architecture)是 Java 平台调试体系结构的缩写,通过 JPDA 提供的 API,开发人员可以方便灵活的搭建 Java 调试应用程序。 JPDA 主要由三个部分组成:Java 虚拟机工具接口(JVMTI),...
要一次性构建所有项目,请确保您正在使用JDK 11,并只需运行: mvn package 也可以通过输入子项目来单独构建项目。 某些项目可能需要以这种方式构建依赖项目的mvn install 。 运行项目 检查子文件夹中的README.md...
jdi反编译工具(class到java)简单,清晰,直接运行就可以使用。
Sbt Tools Jar插件查找并将JDK tools.jar添加到sbt的非托管jar中,从而可以访问Java调试器接口(JDI)。安装sbt 1.0 将以下内容添加到project/plugins.sbt : addSbtPlugin( " org.scala-debugger " % " sbt-jdi-...
很棒的程序 解决 k shortest path 的 c 与java
JDI Dark –是服务测试的测试框架,可以使您的测试快速且可持续地进行,并提供明显且可预测的测试运行结果 强调 -显而易见的服务对象模型,可帮助减少测试开发工作并提高其速度-REST和SOAP Web服务设计支持-保留了...
JPDA主要由三个部分组成:Java虚拟机工具接口(JVMTI),Java调试线协议(JDWP),以及Java调试接口(JDI),本系列将会详细介绍这三个模块的内部细节、通过实例为读者揭开JPDA的面纱。本文是该系列的第一篇,将会...
JDI LT070ME05000 规格书 Datasheet 通用LT070ME05111
JPDA主要由三个部分组成:Java虚拟机工具接口(JVMTI)、Java调试线协议(JDWP),以及Java调试接口(JDI)。本系列将会详细介绍这三个模块的内部细节,并通过实例为读者揭开JPDA的面纱。本系列的第1部分从整体上...
sa-jdi-1.8.0.jar 位图BitMap