【问题标题】:JavaCompiler didn't really compile the classJavaCompiler 并没有真正编译该类
【发布时间】:2016-09-05 01:55:35
【问题描述】:

我想用反射来获取一个新创建的java类的所有方法。如下所示,我通过从另一个文件复制创建了 java 类,然后使用 JavaCompiler 编译新创建的 Java。但我不知道为什么没有创建目标类文件。 PS:如果我给出了错误的源目标java文件路径,就会有类似"javac: cannot find file: codeGenerator/Service.java"的编译信息。谢谢大家。

private static Method[] createClassAndGetMethods(String sourceFilePath) throws IOException {
    File targetFile = new File("Service.java");
    File sourceFile = new File(sourceFilePath);
    Files.copy(sourceFile, targetFile);

    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    compiler.run(null, null, null, targetFile);
    Thread.sleep(5000);

    //After the Service.java compiled, use the class getDeclaredMethods() method.
    Method[] declaredMethods = Service.class.getDeclaredMethods();
    return declaredMethods;
}

编译方法:

        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        compiler.run(null, null, null, targetFile);

【问题讨论】:

    标签: java java-compiler-api javacompiler


    【解决方案1】:
    Method[] declaredMethods = Service.class.getDeclaredMethods();
    

    您不能编写直接依赖于Service.class 的代码,除非Service 已经编译。您必须动态加载该类并从那里获取方法。目前很难看出包含此代码的类是如何加载的,而且它肯定不会给出正确的答案,除非在加载类时存在Service.class 的版本,在这种情况下,您的代码将给出那个版本的方法,而不是新编译的版本。

    您需要从整个源代码中删除对Service.class 或实际上是Service 的所有引用,并在编译后使用Class.forName() 加载Service。执行干净的构建以确保您的部署中不存在 Service.class 文件。

    【讨论】:

    • Method[] declaredMethods = Class.forName("codeGenerator.Service").getDeclaredMethods();如果我这样使用,我仍然无法得到正确的输出。事实是这个类没有被编译。
    • @leo 见here
    【解决方案2】:
    public static void compile(String sourceFilePath, String classPath) throws IOException {
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
        Iterable sourcefiles = fileManager.getJavaFileObjects(sourceFilePath);
        Iterable<String> options = Arrays.asList("-d", classPath);
        compiler.getTask(null, fileManager, null, options, null, sourcefiles).call();
        fileManager.close();
    }
    

    最后我以上述方式成功编译了目标Service.java。谢谢大家。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-10
      • 1970-01-01
      • 2010-12-30
      • 2023-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多