Java: NoSuchMethodException when method clearly exists
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 NullPointerExceptio开发者_JS百科n());
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? :(
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.
The Javadoc for getMethod isn't explicit, but it looks like it might throw a NoSuchMethodException for methods that aren't public, and your method is private.
The versioning issue that can cause NoSuchMethodException isn't a difference between the compiler versions. It's a difference in the version of (in your case) MyClass
at compile time versus runtime.
Since you're using reflection you issue might have nothing to do with versioning, though. Certainly that would not explain different behavior between getMethod
and getDeclaredMethods
, because you're running them against the same Class instance, hence a version difference isn't really possible.
Are you sure that the parameters match your actual method?
精彩评论