Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java reflection for private static method with parameters

I have a problem using the invoke method in java.

I have a method to use to provide me a Method object and it looks like:

 public static Method provideMethod(String methodName, Class targetClass) throws NoSuchMethodException {
    Method method = targetClass.getDeclaredMethod(methodName,null);

    //Set accessible provide a way to access private methods too
    method.setAccessible(true);

    return method;
}

Ok this method works perfectly when I'm trying to access methods, from any context (static, or non static), that have no arguments.

Now the problem is that I can't call invoke and pass arguments to a method that have arguments, for instance:

I have the following method :

private static boolean createDirectory(String path, String fileName) {
  ... 
}

And I want to invoke it like this:

 Boolean created = (Boolean) DataUtils.provideMethod("createDirectory", FileUtils.class).
            invoke(null, String.class, String.class);

But I'm getting java.lang.NoSuchMethodException: createDirectory [].

Does somebody knows how can I invoke a private static method that have parameters ?

And, how can I pass values to that methods arguments?

Thanks, Arkde

like image 520
Aurelian Cotuna Avatar asked Nov 13 '12 12:11

Aurelian Cotuna


People also ask

Can we call private method using reflection Java?

You can access the private methods of a class using java reflection package.

How do you call a static method using reflection?

In the example above, we first obtain the instance of the class we want to test, which is GreetingAndBye. After we have the class instance, we can get the public static method object by calling the getMethod method. Once we hold the method object, we can invoke it simply by calling the invoke method.

How do you set up a private field in a reflection?

If we want to access Private Field and method using Reflection we just need to call setAccessible(true) on the field or method object which you want to access. Class. getDeclaredField(String fieldName) or Class. getDeclaredFields() can be used to get private fields.

How private fields can be called using reflection?

Accessing private fields in Java using reflection In order to access a private field using reflection, you need to know the name of the field than by calling getDeclaredFields(String name) you will get a java. lang. reflect. Field instance representing that field.


2 Answers

You're explicitly calling a reflection method which looks for a method declared with the given parameter types - but you're not providing any parameter types.

If you want to find any method with the given name, use getDeclaredMethods() and just filter by name... but then when you call invoke, you need to provide the string values, not the parameter types.

Alternatively, change your provideMethod call to also accept the parameter types, so you can use:

DataUtils.provideMethod("createDirectory", FileUtils.class,
                        String.class, String.class)
         .invoke(null, "foo", "bar")
like image 148
Jon Skeet Avatar answered Oct 26 '22 07:10

Jon Skeet


You're specifically only looking up methods with no arguments when you call

Method method = targetClass.getDeclaredMethod(methodName,null)

In order to find the createDirectory method, you'd need to call

targetClass.getDeclaredMethod("createDirectory", String.class, String.class)

but at present your provideMethod method has no way of doing this.

I would suggest that you change the signature of provideMethod so that it allows the caller to pass in the classes of the arguments that they're looking for, like so:

public static Method provideMethod(String methodName, Class targetClass, Class... parameterTypes) throws NoSuchMethodException {
    Method method = targetClass.getDeclaredMethod(methodName, parameterTypes);

    //Set accessible provide a way to access private methods too
    method.setAccessible(true);

    return method;
}
like image 45
Andrzej Doyle Avatar answered Oct 26 '22 07:10

Andrzej Doyle