Logo of the Java RMI Plug-in for Eclipse

RMI Plug-in for Eclipse
version 2.0

RMI Spy Effects


This document describes how using the RMI Spy will affect the execution of your applications.
In most situations you won't notice any difference in the application's behavior. However, if your applications starts to misbehave, you should consider this guide to understand the interaction of the RMI Spy with your application. This is a technical document and not the RMI Spy tutorial.

Table of contents

  1. What is the RMI Spy?
  2. How does the RMI Spy work?
  3. Differences between Run and Debug modes.
  4. JDK provider support.
  5. Stack traces generation.
  6. Helper threads.
  7. A shutdown hook.
  8. Using RMI logging properties.
  9. Using the Logging API.

1. What is the RMI Spy?

The RMI Spy collects and displays the RMI-related runtime events generated by your application. Specifically it monitors all the remote calls (both outgoing calls made by your application and incoming calls, made by another application and serviced by your application). It also displays the class loading events, to help you debug classloader problems that are common during the development of RMI systems.

2. How does the RMI Spy work?

Introduction

The RMI Spy is based on the Logging API that is used by the RMI implementation. Even if you don't use the RMI Spy, it is possible to manually turn on the logging properties (you can do that in the "RMI VM Properties" launcher tab) and monitor the output in the console window. For example, turning on the "java.rmi.server.logCalls" property, produces output similar to the following (line breaks added for clarity):

20/05/2006 13:35:06 sun.rmi.server.UnicastServerRef logCall
FINER: RMI TCP Connection(2)-192.168.2.100: [192.168.2.100: \
       demo.rmi.print.server.RemotePrinterImpl[1]: \
       public abstract int demo.rmi.print.server.RemotePrinter.submitJob( \
           java.lang.String) throws java.rmi.RemoteException]

Such output is not human-friendly and extracting any useful information requires much effort.

The RMI Spy Implementation

The RMI Spy does not parse the program's output (although in theory it could do that) because this method is not reliable - the program's output could interfere with the RMI log. Instead, it hooks into the RMI logging system and catches the events at the moment they are generated. The RMI Spy runtime component (that runs as part of the application) uses the Logging API to register its own handlers that collect RMI events and pass them to the RMI Plug-in where they are analyzed and displayed in the RMI Spy view.

To avoid modifying the application code, a launch wrapper is used. That means that the runtime components of the RMI Spy are running inside your application (of course, only when the RMI Spy is enabled). When you launch the application the RMI Spy JAR is added to the classpath and the launch wrapper (class net.genady.rmi.logger.Runner) is passed as the main class. Application's main class and arguments are passed as arguments to the launch wrapper.

The launch wrapper is responsible for registering the logging handlers, establishing a TCP connection with the RMI Plugin and passing the control to the real application. Obviously running the wrapper with your application in the same VM can affect application's behavior. The next sections describes these effects in further detail.

The use of instrumentation

The RMI Plug-in for Eclipse uses bytecode instrumentation ( the ASM library ) to implement some of the advanced features (such as call duration measurement). It should not have any particular effect on your application (except what is presented below), as the RMI Spy instruments only few system classes, but using instrumentation requires using JDK 1.5 or JDK 1.6 to operate (it will be automatically disabled if you use a different version) and it means you should take extra care if you use your own instrumentation (-javaagent) tools (but that's not a problem in most cases).

RMI Spy calls some methods on the objects that are passed as values (or return values) of remote calls. In particular it calls the toString() method for the following classes: all primitive types and their wrapper classes, URLs and URIs, InetAddress, enums, implementors of CharSequence and subclasses of a Number class. It also calls the size() method on implementors of a Collection. The potential danger here is that these methods may have unpredicted side effects, such as acquiring locks/monitors, making network connections etc. If you see that your program behaves strangely, try running it without the RMI Spy and if you see a difference email us to investigate the cause and provide you a patch for your configuration.

3. Differences between Run and Debug modes

The RMI Spy does not use the debugging APIs and therefore there is no difference in the operation of the RMI Spy between the Run and Debug modes.

4. JDK/JVM provider support

The RMI Spy relies on Sun's internal APIs. However, the RMI implementation of many JDK vendor was licensed from Sun so the RMI Spy can work with most stand-alone JVMs. For the up to date compatibility list, please visit our website.

5. Stack traces

The RMI Spy uses a simple launch wrapper that performs some configuration and then passes control to your main class through the reflection APIs. Therefore all stack traces generated in the main thread will have the following lines at their bottom (suppose your main class is demo.rmi.print.client.PrintClient):

   at demo.rmi.print.client.PrintClient.main(PrintClient.java:35)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(
                             NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(
                             DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:324)
   at net.genady.rmi.logger.Runner.main(Runner.java:138)

Stack traces generated in other threads are not affected.

6. Helper threads

The communication between the application and the RMI Plugin for Eclipse is performed through a local TCP connection. Even though a connection is local it can block for various reasons (for example a local firewall). Therefore when there is an event to be passed to the RMI Plugin, the runtime component places that event in the events queue and a dedicated daemon thread performs all the communications work. This way, the application threads are never blocked by the RMI plugin and the impact on the application is minimal. The name of the daemon thread is "RMI Plug-in for Eclipse Log Events Reporter" and it is idle for most of the time.

7. A Shutdown hook

It is not uncommon for an application to stop execution by calling System.exit() or similar method. In such case the RMI Spy's runtime component must ensure that all the events that were collected have been transferred to the RMI Spy part that is running inside Eclipse. In order to achieve this goal the RMI Plugin makes use of the shutdown hooks feature. Therefore it might take just a little longer for the application to terminate (until all the events are transferred). Usually it's only few milliseconds longer, but for RMI-intensive applications it can be another 10 or 100 milliseconds until the application terminates.

8. Using the RMI Logging properties

The RMI Spy does not use any logging properties directly, so you can turn them on to see the regular console-based logs. However, setting some properties, such as "sun.rmi.server.suppressStackTraces" can cause the RMI Spy to lose some information. Therefore it is best to let the RMI Spy to display the log information and avoid modifying the logging properties directly.

9. Using the Logging API

(This is a bit more technical and requires understanding of the Logging APIs) The RMI Spy changes the logging level of the RMI loggers to "ALL". The reason why you don't see the RMI logs on the console is that the RMI logging handlers have a higher logging level (the default is "SILENT"). If for some reason the logging level of the handlers is changed, or another handler is registered to the RMI loggers, they will receive events that they wouldn't receive if the RMI Spy wasn't used. Of course if you modify the logging level of the RMI loggers manually, you can affect the behavior of the RMI Spy.


© 2002-18 Genady Beryozkin, rmi-info@genady.net. Read our Privacy policy. Hosted on RimuHosting. Visit Javalobby.