On my current project, I've felt the need to create a sort of simulated callback system in Java using reflection. However, I'm having issues getting my reflection to actually function. The code at fault follows:
public Callback(Object parentObj, String methodName, Class<?>...parameters) { if(parentObj == null) throw new IllegalArgumentException("parentObj cannot be null", new NullPointerException()); Class<?> clazz = parentObj.getClass(); // Trace debugging, see output for(Method m : clazz.getDeclaredMethods()) if(m.getName().equals("myMethod")) System.out.println (m); try { this.method = clazz.getMethod(methodName, parameters); } catch(NoSuchMethodException nsme) { nsme.printStackTrace(); } // Exception caught catch(SecurityException se) { se.printStackTrace(); } this.parentObj = parentObj; this.parameters = parameters; }
When I construct the Callback
object, I'm using syntax like this:
new Callback(this, "myMethod", boolean.class)
When I try to create my pseudo-callback, it hits the NoSuchMethodException
catch block. I've included some trace debugging above to show the output of one of my methods failing. The output:
private void my.package.MyClass.myMethod(boolean) java.lang.NoSuchMethodException: my.package.MyClass.myMethod(boolean) at java.lang.Class.getMethod(Class.java:1605) at my.package.other.Callback.<init>(Callback.java:63)
I couldn't figure the problem out, so I started hunting, to little avail. The best I could find was mention of versioning conflict between the compiled JAR and the runtime. However, MyJar.jar/META-INF/MANIFEST.MF
contains Created-By: 1.6.0_02 (Sun Microsystems Inc.)
. My IDE is running C:\Program Files\Java\jdk1.6.0_02\bin\javac.exe
to compile my project. I'm using C:\Program Files\Java\jdk1.6.0_02\bin\java.exe
to run my JAR.
I'm at a loss why Class.getMethod
is claiming the method doesn't exist, but Class.getMethods
seems to have no problem finding it. Help? :(
NoSuchMethodError is a runtime error in Java which occurs when a method is called that exists at compile-time, but does not exist at runtime. The Java Garbage Collector (GC) cannot free up the space required for a new object, which causes a java. lang.
Reflection is a feature in the Java programming language. It allows an executing Java program to examine or "introspect" upon itself, and manipulate internal properties of the program. For example, it's possible for a Java class to obtain the names of all its members and display them.
Dig into the do. something code, decompiling it if you don't have the source, and see what is actually thrown by it. Possibly if the exception gets thrown it might get wrapped in another exception. Make sure that anything thrown by the method does not get eaten (including by your own logging of it).
Your method is private but getMethod()
only returns public method.
You need to use getDeclaredMethod()
.
You need the parameter list to be absolutely correct for the method you want for the call to succeed.
I've found that tiny steps are important when doing reflection because the compiler doesn't help. Write a small snippet which actually invokes exactly the method you want to in this particular case, and then when that works, generalize it into the framework here. I would focus on the parameters passed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With