Home > Software design >  Java reflection java.lang.ClassNotFoundException. Related to finding the full class name
Java reflection java.lang.ClassNotFoundException. Related to finding the full class name

Time:09-25

I am currently trying to develop a method for invoking a specific class. The problem I am having is that I need to get the fully-qualified name or full class name when I invoke the class.

public static void testAlgorithm(String className, String methodName, long n) throws Exception 
{
    Class<?> myClass = null;
    Object myObject = null;
    try {
        
        myClass = Class.forName(className);
        myObject = myClass.newInstance();
        
        Class<?>[] params = new Class[1];
        params[0]=Long.TYPE;
        
        Method m = myClass.getMethod(methodName, params);
        
        m.invoke(myObject, n);
    }catch(Throwable e) {
        System.err.println(e);
    }
}

I call it from main

try {
    testAlgorithm("Algorithms", "linear", 50);      
    } catch (Exception e) {
        e.printStackTrace();
    }

I tried passing different arguments for className and I also directly modified the method inside to try to get the full class name but I didn't get anything to work. I have the class in the same project file Session01 and in the same package as well lab01.

I also checked out a similar question here.

And it leed me to also trying out:

Class currentClass = new Object() {}.getClass().getEnclosingClass();

inside the Algorithms class but I don't get the java.lang.String that I need to use for the method I am working on.

CodePudding user response:

If you just want to invoke method on given class - you can always refer to it using .class so you could change parameter of your method from String className to Class<?> myClass and simply remove Class<?> myClass = null; from your method's body.

However, if you want to keep your method's signature as it is and find a class by its simple name instead of fully-qualified name - you can also do this. I could suggest usage of https://github.com/ronmamo/reflections which makes things a lot easier.

Then you can find your class using code like this:

Set<Class<? extends Object>> classes = new Reflections("packageName").getSubTypesOf(Object.class);
Class<?> myClass = classes.stream().filter(clazz -> clazz.getSimpleName().equals(className))
                                   .findAny()
                                   .orElseThrow(() -> new IllegalArgumentException("No class with name: "   className));

Keep in mind that you need to replace "packageName" with root package where you want to scan classes so only classes inside this package or its subpackages will be found. The less classes in a package - the faster will be the scan but you need to make sure that you class will be in the package.

Also keep in mind that you can have multiple classes with same name in different packages - this method will any of them. You can change this behaviour if you need.

You can also restrict classes to subtype of more concrete class than Object.class.

  • Related