Win a copy of Murach's Python Programming this week in the Jython/Python forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

reflection: method.invoke(Object, Object[])  RSS feed

 
Matt Holloway
Ranch Hand
Posts: 53
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am having a problem similar to the earlier post on reflection. What I am doing is passing in a file and using a StringTokenizer to get the infomation from the file. The file contains classes that are to be executed by a main program (file is formatted as follows)
class1(time);
class2(time + 5000);
class3(time + 3000);
etc.
I use the tokenizer to gather the name of the class, and the parameter passed in. time would be the system time held in a variable in the main app. Each of the classes extends Thread, and when run is invoked, they will validate the current time vs the time the thread is to run, then run at that time.
What I can do:
- get the class with Class.forName()
- get the constructor
- invoke the constructor with .newInstance()
- get the desired method (run) with .getMethod()
What I cannot do:
- successfully invoke the method run with .invoke()
About the method:
- name: public void run()
Here is my code currently:

NOTE: package name is test
Here is my error message:
Error java.lang.IllegalArgumentException: object is not an instance of declaring class.
 
Ernest Friedman-Hill
author and iconoclast
Sheriff
Posts: 24215
37
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Matt,
Welcome to JavaRanch!
I've got good news for you, which is that some of this hard work you actually don't have to do. Because you know the name of the method and the name of the parent class at compile time, you can compile this knowledge into your code, and then you don't need to use reflection at all, other than to create the object. So you want to do something like this:

That's it! You don't need to mess with "Method" at all.
Note that you call "start" to start a Thread, not "run". If for some reason, that's really what you want to do, it's OK, I guess. But calling "start" will create a new Thread, while calling "run" will just execute the method synchronously -- i.e., it will block the calling thread until "run" completes.
The exception you're getting is because you're passing a Class object as the first argument to invoke() -- actually, the first argument is supposed to be an instance of the class you're loading in, not the Class object itself. You create an instance using the Constructor.newInstance() method, but you don't assign it to a variable, so it gets lost; you would have needed to save it in a variable of type Object and pass it to invoke().
But anyway, you don't need to do that; just cast to Thread and call the appropriate method.
 
Matt Holloway
Ranch Hand
Posts: 53
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the speedy response! Your tips were bang on the money. I've had a hard time finding any good sources of information on Reflection. I tried both methods you described (both with saving the newInstance to an object and using reflection, and by casting it to a Thread and starting the thread), and both work perfectly.
I've had a difficult time finding much information on Reflection. I've gone through the Sun tutorial on it, and I have several Java books (J2EE in a nutshell, Java in a nutshell, Java examples in a nutshell, Thinking in Java, The Complete Reference Java 3rd Edition), but none really put much meat into the Reflection API.
Thanks again for your rapid and accurate response.
 
Ernest Friedman-Hill
author and iconoclast
Sheriff
Posts: 24215
37
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It's not as well documented as it should be, that's for sure. In particular, I remember not being able to find out what the first argument to invoke() should be if the method is static (although I'm looking at the current javadoc to check, and it clearly states that it can just be null. I don't think the original javadocs specified this.)
Sorry, but if I knew of a better reference that what you've already mentioned, I'd tell you.
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!