0

I'm writing a tester for myself that is meant to work with different classes whose names are given in the form of a string. Currently, my setup looks like this:

public class Tester {

    public static void main(String[] args) throws /** some exceptions **/ {

        Class<?> class = Class.forName("Ex");
        Method main = class.getDeclaredMethod("main", String[].class);
        main.invoke(null);

    }

}
//yes, these are in separate files
public class Ex {

    public static void main(String[] args) {

        //...

    }

}

At runtime, I'm thrown an exception with the following stack trace:

Exception in thread "main" java.lang.IllegalArgumentException: wrong number of arguments
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at Tester.main(Tester.java:56)
guninvalid
  • 411
  • 2
  • 5
  • 16
  • Why not use the `invoke(Object, Object...)` method instead and pass it some values which aren't `null` - `main` has a requirement that you pass it an array of `String` – MadProgrammer Sep 15 '19 at 05:52
  • 1
    The error message is correct. You should have passed `new String[0]`. The code in your title doesn't agree with the code in your question. – user207421 Sep 15 '19 at 05:59
  • See the documentation of [`Method#invoke(Object,Object...)`](https://docs.oracle.com/en/java/javase/12/docs/api/java.base/java/lang/reflect/Method.html#invoke(java.lang.Object,java.lang.Object...)). If the target method has parameters you need to pass the appropriate arguments, even when using reflection. – Slaw Sep 15 '19 at 06:01

2 Answers2

0

You need it pass Ex#main(String[]) it a String[]. That is why you are getting the exception. Ex#main(String[]) expects a single argument but you are not supplying any. You can fix your error by calling Method#invoke(Object,Object...) like this:

main.invoke(null, args); //<-- this will propagate current arguments

OR

main.invoke(null, new String[0]); //<-- this will pass an empty array as arguments

Alternatively, you can call the Ex#main(String[]) without using reflection like this:

Ex.main(args);

OR

Ex.main(new String[0]

after all, main is just another static function.

Doga Oruc
  • 783
  • 3
  • 16
0

You can do it like below:

final String[] args1 = {};
    final Class<?> classa = Class.forName("test.file.LatestClass");
    final Method main = classa.getDeclaredMethod("main", String[].class);
    main.invoke(null, new Object[]{args1});

As per Java Doc of invoke method:

@param obj the object the underlying method is invoked from

@param args the arguments used for the method call

So you can pass null as first argument, as for static method object is not required. But then you need to pass Object arguments array. In your case it will have only one element and that will be String[].

Gaurav Jeswani
  • 4,410
  • 6
  • 26
  • 47