2

I want to use reflection to get all the methods of a newly created java class. Like bellow I created the java Class by copying from another file, then I use JavaCompiler to compile the newly created Java. But I don't know why the target class file was not created. PS: If I give the wrong source target java file path, there will be compile info like "javac: cannot find file: codeGenerator/Service.java". Thank you all.

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;
}

compile method:

        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        compiler.run(null, null, null, targetFile);
user207421
  • 305,947
  • 44
  • 307
  • 483
leo
  • 583
  • 2
  • 7
  • 20

2 Answers2

1
Method[] declaredMethods = Service.class.getDeclaredMethods();

You can't write code that directly depends on Service.class unless Service is already compiled. You would have to dynamically load the class and get the methods from there. At present it is difficult to see how the class containing this code would even load, and it certainly won't give the correct answer, unless a version of Service.class was present when the class was loaded, in which case your code will give the methods of that version, not the newly compiled version.

You need to get rid of all references to Service.class or indeed Service from your entire source code, and load Service with Class.forName() after compilation. Do a clean build to ensure no Service.class file is present in your deployment.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • `Method[] declaredMethods = Class.forName("codeGenerator.Service").getDeclaredMethods();`If I use it this way, I still can't get right output. The fact is the class wasn't compiled. – leo May 11 '16 at 02:17
  • @leo So see [here](http://stackoverflow.com/questions/7989135/is-it-possible-to-programmatically-compile-java-source-code-in-memory-only). – user207421 May 11 '16 at 06:11
0
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();
}

Finally I successfully compiled the target Service.java in above way. Thank you all.

leo
  • 583
  • 2
  • 7
  • 20