Вызов метода путем отражения возвращает противоречивые результаты, если класс скомпилирован более одного раза во время выполнения - PullRequest
0 голосов
/ 29 июня 2018

Я компилирую класс во время выполнения, а затем вызываю методы этих классов. Если класс был скомпилирован более одного раза, логические методы всегда возвращают true вместо ответа, соответствующего аргументам.

Странная часть в том, что когда я отлаживаю, я вижу, что скомпилированный класс одинаков и корректен, правильный метод в правильном пути к классу найден, а аргументы одинаковы.

Метод, который компилирует код:

public static void compile(String conditionClass){
    try {
        String fullPath =  getClassPath() + "/" + target;

        File file = new File(fullPath + ".java");
        if (file.exists())
            file.delete();
        file.createNewFile();

        PrintWriter pw = new PrintWriter(file);
        pw.print(conditionClass);
        pw.flush();
        pw.close();

        JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
        String[] methodArgs = {fullPath + ".java"};
        javac.run(null, null, null, methodArgs);

        targetClass = Class.forName(target);

        file.delete();
    } catch (Exception e){
        e.printStackTrace();
    }

}

public static String getClassPath() throws Exception {
    for (String s : System.getProperty("java.class.path").split(":"))
        if (s.indexOf("/target/classes") + "/target/classes".length() == s.length())
            return s;
}

Метод, который вызывает код:

public boolean call(String methodName, String[][][] arg1, String[] arg2){
    try {
        Method m = targetClass.getMethod(methodName, new Class[]{String[][][].class, String[].class});
        Object[] args = new Object[]{arg1, arg2};
        Object response = m.invoke(null, args);
        return (boolean)response;
    } catch (Exception e){
        e.printStackTrace();
    }

    return true;
}

Класс, который компилируется: тело класса, которое передается как условиеClass:

public class TestClass{
    public static boolean method1(String[][][] arg1, String[] arg2){
        boolean res = true;

        if(path[0][0][0].equals("test target"))
            return false;

        return res;
    }
}

1 Ответ

0 голосов
/ 05 июля 2018

По рекомендации Т.Дж. Проблема была в том, что класс с тем же путем и именем не будет загружен снова.

Для моей задачи достаточно было просто поменять имя класса и загрузить его в JVM, но, тем не менее, это грубый подход, и его следует избегать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...