Problem calling method from a newly loaded class

Asked

Viewed 215 times

0

I made a code that dynamically compiles a java file, and through . class generated can load this class, create an instance and invoke its methods using the method getDeclaredMethod(). So far so good. But now I’m facing a mistake when I try to do this same process in a test class. It compiles and loads, but I can’t access the methods. The class name is Teste and within it I have the method test(). When I try to invoke the method teste() the error that is returned to me says: java.lang.NoSuchMethodException: Teste.test() Can anyone tell why this is happening to this class? Follow the codes:

Class that compiles and loads java files:

public class ReflectApp{

    public static void main(String[] args) throws IOException, NoSuchMethodException {
        String arquivo = "/C:/teste/Teste.java";

        PrintWriter saida = new PrintWriter(new FileWriter("logCompilacao.txt"));
        int resultadoCompilacao1 = com.sun.tools.javac.Main.compile(new String[]{arquivo},saida);
        System.out.println("Show: " + resultadoCompilacao1);


    try{

        URL classUrl;
        classUrl = new URL("file:///C:/teste/");
        URL[] classUrls = { classUrl };
        URLClassLoader ucl = new URLClassLoader(classUrls);
        Class c = ucl.loadClass("Teste");

        Object obj = c.newInstance();   
        Method method = c.getDeclaredMethod("test", null);
        System.out.println(method.invoke(obj, null));


    }catch(Exception ex){
        ex.printStackTrace();
    }
   }
}

Class from where I want to invoke the methods:

public class Teste {

    @Test
    public void test() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, IOException {

        ExternalClassBuilder my_class = new ExternalClassBuilder();
        Class c = my_class.run("/C:/teste/", "Operation");
        Object obj = c.newInstance();   

        Method method = c.getDeclaredMethod("sum", int.class, int.class);
        System.out.println(method.invoke(obj, 1, 2));
        int numero = (int) method.invoke(obj, 1, 2);
        if(numero == 3){
            System.out.println("Método correto");
        }else{
            System.err.println("Método SUM incorreto");
            fail("Valor não corresponde ao esperado");
        }
        Method method2 = c.getDeclaredMethod("hello", null);
        System.out.println(method2.invoke(obj));    

    }

}

Independent of the method test() makes, the problem I see is that the method is not even found.

1 answer

-1

To call a method straight from the class like this Teste.test() you need to change the line:

public void test() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, IOException {

To:

public static void test() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, IOException {

The difference is that I have added Static which will make your method static and thus can be 'seen' in needing to standardize the 'Test' class'.

If you do not want to make the above change, you need to instantiate the class to call the method, so it can be:

Teste objTeste = new Teste();
objTeste.test();

Or so:

(new Teste()).test();

Try the answer and pass feedback!

  • Not that this is an error (because it is not) but neither need involve with parentheses this last line of code to work.

  • 1

    Exactly! I imagine the author is a beginner, so I found it more didactic... hehe

  • I tried to leave the method as Static but the error remains. Regarding creating the instance, it is not possible in the way it is explaining, as it would be trying to use the class that has just been compiled as a type. And this is not possible because java is a strong type language. The class is not inside the project, it is outside in any folder. I can only instantiate the class using this line: Object obj = c.newInstance(); And to invoke its method, only using getDeclaredMethod()

  • And you can’t call the method on the instantiated object by c.newInstance()?

  • Exactly. That’s the error I’m reporting. From the error message it seems that for some reason the method is not found

  • Try to change c.getDeclaredMethod("test", null); for c.getMethod("test");

  • It doesn’t work, I’ve tried it.

  • Dude, so I can only help you by playing in the IDE, and I can’t right now. In case you still don’t have an answer you can solve until I get home, I’ll help you.

  • 1

    The answer was well-intentioned, but she totally missed the point of the question. The AP is not beginner, nor is what it wants to do something simple.

Show 4 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.