• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

problems using a dynamic proxy with wait(); notify()

 
Nolan Evans
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello,

Currently i am working on a dynamic proxy, i can get it to work for most objects however when i am trying to use my dynamic proxy to record the performance of wait and notify calls.

However my invoke method in my proxy never appears to be called. I have tested the proxy with a RMI stub and it works, however i can't seem to get any of the methods of java.lang.object to be invoked...

Please help, i have tried googling to find a solution but i can't find anything...

Code bellow:

My proxy:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import java.io.*;

public class Logger implements InvocationHandler {
private Object delegate;

public Logger(Object o) {
delegate = o;
}

public static Object newInstance(Object obj) {
return java.lang.reflect.Proxy.newProxyInstance(
obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(),
new Logger(obj));
}

public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {

System.out.println("Test here");
BufferedWriter loggingWriter = new BufferedWriter( new FileWriter("log.txt"));
loggingWriter.write("Calling method " + method + " at " +System.currentTimeMillis());
loggingWriter.newLine();

try {
return method.invoke(delegate, args);
}
catch (InvocationTargetException e) {
throw e.getTargetException();
}
finally {
System.out.println("Test here");
loggingWriter.write("Called method " +method + " at " +System.currentTimeMillis());
loggingWriter.newLine();
loggingWriter.close();
}

}
}

synchronized(delegate) {
return method.invoke(delegate, args);
}

my test program is basically as follows:

private static RemoteInterface wrapper;
//blah blah
wrapper =
(RemoteInterface) Proxy.newProxyInstance(
this.getClass().getClassLoader(),
this.getClass().getInterfaces(),
new Logger(this));
//blah blah
//then within a syncronized call:

wrapper.wait();




The program still works 100% however it bypasses my invoke method in my proxy somehow, i can't figure it out for the life of me. Any help would be greatly apperciated.
 
Ernest Friedman-Hill
author and iconoclast
Marshal
Pie
Posts: 24212
35
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

Welcome to JavaRanch!

Only interface methods are dispatched to the dynamic proxy invoke() method, except for hashCode(), equals() and toString(). Any other Object methods get called on the Proxy instance itself -- i.e., you get the inherited java.lang.Object versions.
 
Nolan Evans
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
okay, well my next question then is how do i put a method into an argument so i can call invoke manually:

something like:

wrapper.invoke(this,wait,nothing);

it doesn't let me indentify wait as being a method...
 
Nolan Evans
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
btw thanks for pointing that out, it seems so obvious now, i can't believe i didn't realize that before, d'oh!
 
Ernest Friedman-Hill
author and iconoclast
Marshal
Pie
Posts: 24212
35
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
To call invoke() manually, you have to supply a java.lang.reflect.Method object. You can get the Method for wait() by asking the Class object corresponding to java.lang.Object using the getDeclaredMethods() method.
 
Nolan Evans
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
ah okay, i seem to be having trouble creating a wrapper that has this interface:

wrapper = (Logger)Logger.newInstance(new Logger(this));
gives me:

java.lang.ClassCastException
at Client.<init>(Client.java:31)
at Client.main(Client.java:220)
 
Ernest Friedman-Hill
author and iconoclast
Marshal
Pie
Posts: 24212
35
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The object returned by Proxy.newProxyInstance() is not an instance of the implementation class you pass in (Logger, here) -- i.e., it's not a subclass of that class, or related in any other way to that class. The Proxy instance, instead, implements all the interfaces you pass in to newProxyInstance(). So you can cast the result to any of those interface types, but not to the implementation class.
 
Nolan Evans
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hmm how do i go about using dynamic proxies to call a wait/notify command then?

i am afriad that i am at a total loss

could you point me in the right direction? is it even possible to do this?

thank you for all your assistance
 
Ernest Friedman-Hill
author and iconoclast
Marshal
Pie
Posts: 24212
35
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't think you can do it without modifying the target class, and I imagine that's not possible for you. If you can modify the target classes, you could define an interface "WaitNotify" which had the wait and notify methods in it, then have the target class declare that it implemented this interface. The proxy would then implement those methods -- I think. You'd have to try the experiment.
 
Nolan Evans
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks, tried that, can't because notify and wait are final


RemoteInterface.java:8: wait() in RemoteInterface cannot override wait() in java.lang.Object; overridden method is final
public void wait() throws InterruptedException;
^
RemoteInterface.java:9: notify() in RemoteInterface cannot override notify() in java.lang.Object; overridden method is final
public void notify() throws IllegalMonitorStateException;
^
2 errors
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic