1

I am currently using Reflection to execute a set of methods in classes which reside in a different project than the one I am working on. These methods will in turn call other methods within this project. Although the method calling is succeeding, an InvocationTargetExceptioncaused by NoSuchMethodError is being thrown. I am presuming that this occurred because the methods I am calling using reflection call other methods. For this reason I have added to the class path the other project but this did not work.

Please note that the other project is an open source project I'm using from GitHub and am solely using it for analysis thus I do not want to manipulate with it.

Can anyone help me please?

Edit:

The following is my current code for reflection:

   public void runSelectedTests(MethodSignature test) throws Exception{
    //no paramater
    Class<?> noparams[] = {};

    try{
        //load the test at runtime
        //get the class
        Class<?> cls = Class.forName(test.getClassName());
        Constructor<?>[] cons = cls.getDeclaredConstructors();
        //can use the first constructor if there are multiple
        //if we instantiate with all constructors you end up calling the test methods depending on
        //how many constructors you have
        Constructor<?> cons1 = cons[0];
        Object params[] = null;
        if(cons1.getParameterTypes().length > 0){
            params = new Object[cons1.getParameterTypes().length];
        }
        for(int i = 0; i < cons1.getParameterTypes().length; i++){
            String type = cons1.getParameterTypes()[i].toString();
            if(type.equals("byte") || type.equals("short") || type.equals("int")){
                params[i] = 0;
            }else if(type.equals("long")){
                params[i] = (long)0.0;
            }else if(type.equals("float")){
                params[i] = (float)0.0; 
            }else if(type.equals("double")){
                params[i] = (double)0.0;
            }else if(type.equals("char")){
                params[i] = (char)0;
            }else if(type.equals("boolean")){
                params[i] = false;
            }else{
                params[i] = null;
            }   
        }

        Object obj = cons1.newInstance(params);
        //call the test method
        Method method = cls.getDeclaredMethod(test.getName(), noparams);
        method.invoke(obj, null);
    }catch(Exception e){
        System.out.println("exception "+e.getMessage());
    }
}

The object MethodSignature stores the method name and the fully qualified name of the class.

Stack Trace:

Exception in thread "main" java.lang.reflect.InvocationTargetException
    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 com.Evaluation.TestRunner.runSelectedTests(TestRunner.java:72)
    at com.Main.AnalyserFactory.main(AnalyserFactory.java:41)
Caused by: java.lang.NoSuchMethodError: org.apache.commons.io.IOUtils.closeQuietly([Ljava/io/Closeable;)V
    at org.apache.commons.io.IOUtilsTestCase.testCloseQuietly_AllCloseableIOException(IOUtilsTestCase.java:134)
    ... 6 more

Edit

This is the method I am trying to call:

public void testCloseQuietly_AllCloseableIOException() {
    final Closeable closeable = new Closeable() {
        public void close() throws IOException {
            throw new IOException();
        }
    };
    IOUtils.closeQuietly(closeable, null, closeable);
}

The error seems to be on the line:

   IOUtils.closeQuietly(closeable, null, closeable);
gracey
  • 213
  • 3
  • 14
  • 1
    can you modify your question with some code from your experiment work? This may help us to provide some answer. – sakura Mar 01 '14 at 15:31
  • just provided you with my code to perform reflection. – gracey Mar 01 '14 at 15:40
  • Post the whole stacktrace. Which line throws the exception? `method.invoke(obj, null);`? – m0skit0 Mar 01 '14 at 15:46
  • The line which invokes another method within the project. That is why I have tried to add to the class path the whole project. There is no error in my code. That is why an InvocationTargetException is being thrown! – gracey Mar 01 '14 at 15:49
  • Are you sure that the class you're invoking does have a method with that name which takes no arguments? Which method name are you invoking, against which class, and now does that class declare the method? (And are you sure that class is on the classpath? Can you call the method normally?) – keshlam Mar 01 '14 at 16:05
  • The class is on the classpath for sure because I can call it 'normally'. – gracey Mar 01 '14 at 16:25
  • @keshlam I have called the method 'normally' and did not return any compile-time errors this is why I said I am sure it's on the class path. But now I have run my project and gave me the same error. – gracey Mar 01 '14 at 16:31

2 Answers2

3

Class org.apache.commons.io.IOUtils does not have any method closeQuietly that takes java.io.Closeable as a parameter. It has following methods:

   closeQuietly(InputStream input) 
   closeQuietly(OutputStream output)
   closeQuietly(Reader reader)
   closeQuietly(Writer writer)

You shall pass your argument accordingly. Hope this helps.

Sanjeev
  • 9,876
  • 2
  • 22
  • 33
  • I have the source code which I downloaded from GitHub. I'm pretty sure there is a method closeQuietly with java.io.Closeable as a parameter. It's in the IOUtils.java class – gracey Mar 01 '14 at 16:19
  • than check if your code is referring correct source/jar – Sanjeev Mar 01 '14 at 16:27
  • I am suspecting that I have not specified the correct folder in the class path. – gracey Mar 01 '14 at 16:39
  • yeah, that is the only thing which can stop your code from executing rightly. – Sanjeev Mar 01 '14 at 16:40
  • The weird thing that is happening is that I am sure that there is a method closeQuietly(final Closeable... closeables). However, when my project calls a method from the commons-io project which invokes the closeQuietly(final Closeable... closeables) the error occurs. When calling a method which calls for example IOUtils.closeQuietly(selector), the error does not occur. Can one say that the exception java.lang.reflect.InvocationTargetException indicates that the problem is found in the code which got invoked using reflection and not in the code for reflection? – gracey Mar 01 '14 at 17:10
0

Since 1.5, all Method reflection methods are varargs for the parameter values/types.

This looks wrong:

method.invoke(obj, null);

If there are no parameters, call it thus:

method.invoke(obj);

Simlarly, this:

Method method = cls.getDeclaredMethod(test.getName(), noparams);

can/should be just

Method method = cls.getDeclaredMethod(test.getName());
Bohemian
  • 412,405
  • 93
  • 575
  • 722