I am trying to run some method I load from another jar, that returns an integer, and then I want to return it to another class and pass it to my logic.
I made my method loading class pretty simple like this:
public class ModuleLoader {
private Class<?> cls;
public void initializeCommandModule(Module m) throws Exception {
URL url = this.getURL(m.getJar());
this.cls = this.loadClass(m.getMainClass(), url);
}
public int execute(Module m, ArrayList<String> args) throws Exception {
Method method = this.cls.getDeclaredMethod("execute", ArrayList.class);
return (int) method.invoke(this.cls.newInstance(), 1);
}
public int respond(ArrayList<String> args) throws Exception {
Method method = this.cls.getDeclaredMethod("response", ArrayList.class);
return (int) method.invoke(this.cls.newInstance(), 1);
}
private Class<?> loadClass(String cls, URL url) throws ClassNotFoundException, IOException {
URLClassLoader loader = new URLClassLoader(new URL[]{url});
Class<?> toReturn = loader.loadClass(cls);
loader.close();
return toReturn;
}
private URL getURL(String jar) throws MalformedURLException {
return new File(jar).toURI().toURL();
}
}
Take a look at the execute(Module m, ArrayList<String> args)
method, this line throws the error:
return (int) method.invoke(this.cls.newInstance());
The jar library I load looks like this:
public class Test {
public int execute(ArrayList<String> i) {
System.out.println("Hello world!");
return 0;
}
}
Why when I run that method I get the following exception thrown?
Exception in thread "main" java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at ben.console.modules.ModuleLoader.execute(ModuleLoader.java:24)
at ben.console.CommandProcessor.process(CommandProcessor.java:37)
at ben.console.Console.listen(Console.java:25)
at ben.console.Console.main(Console.java:31)
Thanks in advice!
You forgot to pass an argument to your method invocation.
return (int) method.invoke(this.cls.newInstance(), myArrayList);
You can also invoke with a null argument:
return (int) method.invoke(this.cls.newInstance(), (Object[])null);
In your execute()
method, you have this
return (int) method.invoke(this.cls.newInstance());
I think you wanted
return (int) method.invoke(this, args);
Likewise with respond()
,
Method method = this.cls.getDeclaredMethod("response", ArrayList.class);
return (int) method.invoke(this.cls.newInstance(), 1);
should be
return (int) method.invoke(this, args);
You may find my blog post here helpful.
As far as I understand you fetch method that accepts one argument of type ArrayList
:
Method method = this.cls.getDeclaredMethod("execute", ArrayList.class);
But then try to invoke it with argument of type that I cannot recognize that is obviously not ArrayList
(int) method.invoke(this.cls.newInstance());
What is the type of this.cls.newInstance()
? Value of cls
is assigned in method initializeCommandModule()
as following:
this.cls = this.loadClass(m.getMainClass(), url);
where m
is Module
. I have no idea what Module
is and therefore do not know what does getMainClass()
return.
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