我从教程中获得了以下代码:
package com.tom.labs;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
public class CompilerTest {
/**
* @param args
*/
public static void main(String[] args) throws Exception {
String source = "public class Main { " +
" public static void main(String[] args) {" +
" System.out.println(\"Hello World!\");" +
" }" +
" public static void test() { " +
" System.out.println(\"Hello World!\");" +
" } " +
"}";
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
StringSourceJavaObject sourceObject = new CompilerTest.StringSourceJavaObject("Main", source);
Iterable fileObjects = Arrays.asList(sourceObject);
CompilationTask task = compiler.getTask(null, fileManager, null, null, null, fileObjects);
boolean result = task.call();
if (result) {
ClassLoader loader = CompilerTest.class.getClassLoader();
Class<?> clazz = loader.loadClass("com.tom.labs.Main");
Method method = clazz.getMethod("test", new Class<?>[] {});
method.invoke(null, new Object[] {});
}
}
static class StringSourceJavaObject extends SimpleJavaFileObject {
private String content = null;
public StringSourceJavaObject(String name, String content) throws URISyntaxException {
super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE);
this.content = content;
}
public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
return content;
}
}
}
然而,它不起作用。得到错误: 线程“main”中的异常java.lang.NoSuchMethodException:com.tom.labs.Main.test() at java.lang.Class.getMethod(Class.java:1622) 在com.tom.labs.CompilerTest.main(CompilerTest.java:38)
有人可以帮帮我吗? Updte:
我打印出了getMethods的输出: [public static void com.tom.labs.Main.main(java.lang.String []),public final void java.lang.Object.wait(long,int)throws java.lang.InterruptedException,public final native void java .lang.Object.wait(long)抛出java.lang.InterruptedException,public final void java.lang.Object.wait()抛出java.lang.InterruptedException,public boolean java.lang.Object.equals(java.lang.Object ),public java.lang.String java.lang.Object.toString(),public native int java.lang.Object.hashCode(),public final native java.lang.Class java.lang.Object.getClass(),public final native void java.lang.Object.notify(),public final native void java.lang.Object.notifyAll()]
这很奇怪,方法测试不在那里。
答案 0 :(得分:1)
你的'来源'
String source = "public class Main { " +
" public static void main(String[] args) {" +
" System.out.println(\"Hello World!\");" +
" }" +
" public static void test() { " +
" System.out.println(\"Hello World!\");" +
" } " +
"}";
没有命名空间。您应该向其添加package关键字,或者更改
Class<?> clazz = loader.loadClass("com.tom.labs.Main");
到
Class<?> clazz = loader.loadClass("Main");
答案 1 :(得分:0)
首先,您应该将包名添加到您的班级名称。
除了包名,请查看天气生成的课程,如同课程路径一样。这可以通过在调用编译任务时添加类输出文件夹选项来完成:
CompilationTask task = compiler.getTask(null,fileManager,null,Arrays.asList(“ - d”,“”),null,fileObjects);
有一个很棒但很轻的库可以在一次调用中完成你的工作,并且完全在内存中编译源码和加载类,请访问: