I will not write about ‘reflection’ as in ‘meditation’. This entry will be about ‘reflection’ as in ‘looking inside an object of an OOP-language’…
My friend Clemens encountered the following question in his last oral examination: Consider you wanted to display some debugging-information on entering and exiting some method of an object (in Java). Of course, you don’t want to hardcode
system.out.println into that method. What other ways to achieve that kind of functionality are there?
That’s actually a rather tough question. The prof mumbled something about reflection and classloaders but was no more specific.
Since the answer was not obvious to us, our, at least my, striving for correct answers was stimulated. To my knowledge Java’s reflection facility only allows for looking into an object and invoking methods. It does not allow to change the behavior of a method. But that would be needed in order to augment a method with the debugging-information.
When I first heard that question I thought Decorator!
. Changes to the original code would be needed, though. Not what I’d call minimal invasive technique. I’d rather have something nobody would notice, something external. Some pseudocode should illustrate that idea:
def original_function(*somearguments):
do_something
return something #if needed
def wrapper(orig_function):
def decorator(*somearguments):
print 'print debugging information'
result = orig_function(*somearguments)
print 'print debugging information'
return result
return decorator
original_function = wrapper(original_function)
That pseudocode assumes that functions (and methods) are first-class objects which can be passed and stored inside variables. It further assumes that lexical scoping is used, i.e. variables (and functions) are resolved in the context of their declaration, not their calling environment. That enables the use of closures: orig_function is closed into the declaration of the decorator-function and can be used there even within another context.
That was my idea on first thought. Still, that code would have to be injected into the existing code, somehow. One would have to change the example to work on methods (functions of objects) and run it before the first call to the thusly augmented method. Complicated and risky. Debugging code that could augmented in such a way will be difficult.
I decided to follow the track given by the hint to reflection. As already mentioned I was quite sure that it could not be done with the standard-reflection I know. There must be some more voodoo to it. (What do I mean by voodoo
in this context? Have a look at the Apache-tutorial for mod_rewrite…)
I contacted my local voodoo-Houngan: Alex. He, too, found interest in that subject and referred me to the tutorial on Dynamic Proxy Classes. Given those keywords I’ve found another page dealing with that subject: Java Reflection in Action: Using Java’s Dynamic Proxy.
The idea behind dynamic proxies is that interfaces can be ‘implemented’ by some instance of java.lang.reflect.InvocationHandler at runtime (let’s call it P for proxy). An instance of the original object (let’s call it O) is given to P. Additionally P’s interface is extended to mimic the one of O. Now everytime a method from O’s interface is called in P, the invoke-method, obtained from java.lang.reflect.InvocationHandler and implemented in P, is called. That’s the time to display the debugging-information and call the original implementation of the mehtod in O. That’s it. The tutorial linked above goes into much greater detail. There are some links in the DenkzeitBlog: reflection-voodoo
Still, using dynamic proxies the original code would have to be touched. At least the proxy must be introduced into the system, references to the original object (O) must be replaced with references to the proxy (P).
The question arises: Is there some more elegant solution?
There is. Actually I stumbled over two. I’d consider the first one to be a more abstract use of reflection: Aspect Oriented Programming. The second one is quite more voodoo and much more elegant: Metaclasses. I’ll write about these in one of the next installments of DenkZeit…





{ 2 } Trackbacks
[...] DenkZEITDas Blog von Steffen Glückselig
Heute, 2005/4/23
The voodoo of reflection>> Interludium pro magus nigris
File [...]
[...] This is the last part of a three parts-series on adding functionality to existing code. In The voodoo of reflection I shortly described how this could be achieved [...]
Post a Comment