0

I'm using a custom Classloader to create and return an instance of a class, this seems to work ok however when I try to call a method (via the Reflection API) and pass in a custom object as described below I get a NoSuchMethodException:

Supposing that the custom class loader creates and returns an instance like so:

Object obj = customClassLoader.load(String className,Class[] paramTypes,Object[] param)

Then I call a method (via reflection) and pass in a custom object:

NOTE: THIS IS THE LINE CAUSING THE ERROR

Method m = obj.getClass.getDeclaredMethod("mName",new Class[]{aCustomObject.class}) 

m.invoke(obj,new Object[]{new CustomObject() })

I'm stumped as to what could be causing the exception since a method definitely does exist which takes the specified custom object, I have confirmed this by using reflection to list all methods.

2
  • Did you try print out all available methods from this class and see if your method present there? Using getDeclaredMethods. Commented Nov 8, 2012 at 16:50
  • Yes, as mentioned above, I have successfully been able to print out all methods. I'm wondering if its because I'm using two classloaders. Commented Nov 8, 2012 at 21:00

1 Answer 1

2

How is your custom loader's load() method instantiating the object it is to return? Maybe the NoSuchMethodException arises during trying to find the correct constructor?

This example seems to work out OK:

package com.pholser;

import java.lang.reflect.Method;

public class ClassLoading {
    public static class CustomLoader extends ClassLoader {
        public Object load(String className, Class<?>[] paramTypes, Object[] params) throws Exception {
            Class<?> loaded = loadClass(className);
            return loaded.getConstructor(paramTypes).newInstance(params);
        }
    }

    public static class ACustomObject {
    }

    public void foo(ACustomObject a) {
        System.out.println("foo");
    }

    public static Object newCustomObject() throws Exception {
        return new CustomLoader().load("com.pholser.ClassLoading$ACustomObject", new Class<?>[0], new Object[0]);
    }

    public static void main(String[] args) throws Exception {
        ClassLoading obj = new ClassLoading();

        Method m = obj.getClass().getDeclaredMethod("foo", ACustomObject.class);

        m.invoke(obj, newCustomObject());
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

The last line should be: m.invoke(obj, new CustomObject()); I have updated my question to reflect this. Your example does work as expected and I suspect its because you are creating the new object with the SAME ClassLoader as the one that instantiated the ClassLoading class. In my example I try to pass in an object instantiated by the default classloader.
Additionally, thank you very much indeed for your detailed answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.