Use jdi to listen to Java programs

Source: Internet
Author: User

The VA virtual machine provides a set of interfaces for debugging (jvmdi) and monitoring (jvmpi). After Java 5, it is unified as jvmti:

Http://docs.oracle.com/javase/1.5.0/docs/guide/jvmti.

 

Jvmdi is divided into three parts: jvmdi, jdwp, and jdi.

Http://docs.oracle.com/javase/1.4.2/docs/guide/jpda/architecture.html

 

This article briefly introduces how to use jdi to monitor program running.

 

Assume that there is a simple program:

Java code
  1. Package test;
  2. Public class test {
  3. Public static void main (string [] ARGs ){
  4. New thread (){
  5. @ Override
  6. Public void run (){
  7. Test test = new test ();
  8. While (true ){
  9. Try {
  10. Sleep (5000 );
  11. } Catch (interruptedexception e ){
  12. E. printstacktrace ();
  13. }
  14. Test. printhello ();
  15. }
  16. }
  17. }. Start ();
  18. }
  19. Protected void printhello (){
  20. System. Out. println ("hello ");
  21. }
  22. }

 

In the program, the printhello () method is executed once every five seconds.

 

If you want to notify you every time printhell () is executed, what do you do without modifying the code? No way, right?

 

Let's take a look at the definition of jdi:

Java code
  1. Jdi-Java debug Interface
  2. Defines a high-level Java language interface which tool developers can easily use to write remote debugger applications.

 

So first, we start the test class in the form of remote debugging:

Java code
  1. Java-xdebug-agentlib: jdwp = transport = dt_socket, Server = Y, suspend = N, address = 8800-CP. Test. Test

 

Generally, the test class is debugged through socket transmission. The connection port for debugging is 8800, and the connection process is not suspended.

 

The following output is displayed after a volume is started:

 

Java code
  1. Listening for transport dt_socket at address: 8800
  2. Hello
  3. Hello
  4. Hello

 

In this way, the server is ready for debugging. The following is the write listener. The jdi interface provided by JDK is used here. To use this interface, we need to include tools. jar and other packages under JDK in the class path, which can be found under the <JDK>/lib directory.

1. Get the connector Java code
  1. Virtualmachinemanager vmm = Bootstrap. virtualmachinemanager ();
  2. List <attachingconnector> connectors = vmm. attachingconnectors ();
  3. Socketattachingconnector sac = NULL;
  4. For (attachingconnector AC: connectors ){
  5. If (AC instanceof socketattachingconnector ){
  6. SAC = (socketattachingconnector) AC;
  7. Break;
  8. }
  9. }
  10. If (SAC = NULL ){
  11. System. Out. println ("jdi error ");
  12. Return;
  13. }

 

2. Connect to the remote virtual machine Java code
  1. Map arguments = sac. defaultarguments ();
  2. Connector. Argument hostarg = (connector. argument) arguments. Get (host );
  3. Connector. Argument portarg = (connector. argument) arguments. Get (port );
  4. Hostarg. setvalue ("127.0.0.1 ");
  5. Portarg. setvalue (string. valueof (8800 ));
  6. Vm = sac. Attach (arguments );

 

3. Get the Java code of the classes and methods to be concerned
  1. List <referencetype> classesbyname = VM. classesbyname ("Test. Test ");
  2. If (classesbyname = NULL | classesbyname. Size () = 0 ){
  3. System. Out. println ("no class found ");
  4. Return;
  5. }
  6. Referencetype RT = classesbyname. Get (0 );
  7. List <method> methodsbyname = Rt. methodsbyname ("printhello ");
  8. If (methodsbyname = NULL | methodsbyname. Size () = 0 ){
  9. System. Out. println ("No Method Found ");
  10. Return;
  11. }
  12. Method method = methodsbyname. Get (0 );

 

4. Register and listen to Java code
  1. VM. setdebugtracemode (virtualmachine. trace_events );
  2. VM. Resume ();
  3. Eventrequestmanager erm = VM. eventrequestmanager ();
  4. Methodentryrequest = Erm. createmethodentryrequest ();
  5. Methodentryrequest. addclassfilter (RT );
  6. Methodentryrequest. setsuspendpolicy (eventrequest. suspend_none );
  7. Methodentryrequest. Enable ();
  8. Breakpointrequest = Erm
  9. . Createbreakpointrequest (method. Location ());
  10. Breakpointrequest. setsuspendpolicy (eventrequest. suspend_event_thread );
  11. Breakpointrequest. Enable ();
  12. Eventloop ();

 

Listen to each method entry, register a breakpoint on the method, and send a notification.

 

Iv. Java code for implementing eventloop ()
  1. Private Static void eventloop () throws exception {
  2. Eventqueue = VM. eventqueue ();
  3. While (true ){
  4. If (vmexit = true ){
  5. Break;
  6. }
  7. Eventset = eventqueue. Remove ();
  8. Eventiterator = eventset. eventiterator ();
  9. While (eventiterator. hasnext ()){
  10. Event event = (event) eventiterator. Next ();
  11. Execute (event );
  12. }
  13. }
  14. }
  15. Private Static void execute (event) throws exception {
  16. If (event instanceof vmstartevent ){
  17. System. Out. println ("VM started ");
  18. Eventset. Resume ();
  19. } Else if (event instanceof breakpointevent ){
  20. System. Out
  21. . Println ("reach method printhello of Test. Test ");
  22. Eventset. Resume ();
  23. } Else if (event instanceof methodentryevent ){
  24. Methodentryevent mee = (methodentryevent) event;
  25. Method method = Mee. Method ();
  26. System. Out. println (method. Name () + "was entered! ");
  27. Eventset. Resume ();
  28. } Else if (event instanceof vmdisconnectevent ){
  29. Vmexit = true;
  30. } Else {
  31. Eventset. Resume ();
  32. }
  33. }

 

Finally, let's look at the output:

Java code
  1. [Jdi: eventset: suspend_event_thread]
  2. [Jdi: Event: MethodEntryEvent@test.Test: 23 in thread-0]
  3. [Jdi: Event: BreakpointEvent@test.Test: 23 in thread-0]
  4. Printhello was entered!
  5. Reach method printhello of Test. Test
  6. [Jdi: eventset: suspend_event_thread]
  7. Printhello was entered!
  8. [Jdi: Event: MethodEntryEvent@test.Test: 23 in thread-0]
  9. [Jdi: Event: BreakpointEvent@test.Test: 23 in thread-0]
  10. Reach method printhello of Test. Test

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.