|
Library interposition has proven to be a very useful technique in C language programming. With this approach, it is not necessary to recompile any existing source code--or even have access to the source code--in order to trace, profile or debug function calls. The goal of this technical article is to explore a technique for interposing on Java methods. Solaris Library Interposition
The following example uses interposition to record the frequency of
The redefined exit function collects the memory allocation information stored in some data structures and prints it to a file. Setting the LD_PRELOAD environment variable to (some path)/malloc_hist.so ensures that the user-defined functions are loaded first. After some pre-processing, the system malloc functions are loaded (if necessary) and called. For more information about LD_PRELOAD and runtime linking, see the Linkers and Libraries Guide. Java Method InterpositionAn equivalent technique could be very useful for developers in tracing, profiling and debugging Java programs. Proxy class methods could be interposed in order to examine arguments, record the frequency of calls, timing information, and so forth, before or after calling the original method. This technique is not quite as simple for methods, however, since Java is a pure object-oriented language which does not allow any stand-alone (global) functions. Methods are not loaded individually, as C functions are, but rather are loaded as part of the class within which they are defined. Therefore, any override must start at the class level rather than at the method level. The CLASSPATH environment variable plays a role here similar to what LD_LIBRARY_PATH does for C programs. It provides an ordered search path for the classloader to find a needed classfile.
At class load time, the interposed class must be found before the original one. This can be readily accomplished through manipulation of the CLASSPATH environment
variable or a -classpath switch on the commandline. The interposed class must have the same full name as the original. For example, a class
There is a problem, however, if we now wish to dispatch to the original method. Since each classloader maintains a cache of unique class names, the interposed and original
classes Proxy Class Interposition
Before tackling those problems, let's look at a built-in Java language facility that can be used to simulate much of the functionality provided by C language interposition.
J2SE v1.3 has introduced a dynamic proxy class in the Java Reflection package. A dynamic proxy class implements a list of interfaces specified at runtime such that a
method invocation through one of the interfaces on an instance of the class will be encoded and dispatched to another object through a uniform interface. Proxy classes and
instances are created using static methods of the
For example:
Once a new proxy instance has been created, it is legal to cast it to any one of the interfaces that it implements, and to call any method supported by that interface.
For example:
Bar b = (Bar)
TraceProxy.newInstance(new BarImpl());
b.hello();
Method invocations on an instance of a dynamic proxy class are dispatched to the
With this facility, we may create our own proxy class which can intercept a method call, do some pre-processing, invoke the original method, then do some post-processing. This is exactly the method interposing behavior that we seek!
For example:
Following is the complete code for a simple example of method interposing using a dynamic proxy class. Foo.java
Bar.java
BarImpl.java
TraceProxy.java
ConclusionThe proxy class is relatively flexible and straightforward to use, but there are some distinct limitations on its use for method interposing. One limitation is that the method must be called through an instance of the proxy class. So nested methods calls, for instance, would not be intercepted. Another limitation is that the method must have been defined in an Interface that is implemented by the object being proxied. It can not be called through an instance of a class that does not implement an interface. The next article in this series will illustrate some techniques for overcoming these limitations. About the AuthorTom Harpin works in Market Development Engineering at Sun's Burlington, MA campus. He works primarily on Distributed System Management vendor integration efforts with WBEM, and JMX. Prior to Sun, Tom helped design and implement several client-server systems for Delta Airlines. For More Information
Proxy Class
Documentation Have a question about programming? Use Java Online Support. | ||||||||||||||||
Oracle is reviewing the Sun product roadmap and will provide guidance to customers in accordance with Oracle's standard product communication policies. Any resulting features and timing of release of such features as determined by Oracle's review of roadmaps, are at the sole discretion of Oracle. All product roadmap information, whether communicated by Sun Microsystems or by Oracle, does not represent a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. It is intended for information purposes only, and may not be incorporated into any contract.
|
| ||||||||||||