0

我得到了以下从教程中复制的代码:

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.CompilerTest 的 java.lang.Class.getMethod(Class.java:1622) 处的 com.tom.labs.Main.test()。主要(CompilerTest.java:38)

有人可以帮帮我吗?更新:

我打印出 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) throws java.lang.InterruptedException, public final void java.lang.Object.wait() throws 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()]

很奇怪,里面没有方法测试。

4

2 回答 2

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!\");" +
                " } " +
                "}";

没有命名空间。您应该为其添加一个包关键字,或者更改

Class<?> clazz = loader.loadClass("com.tom.labs.Main");

Class<?> clazz = loader.loadClass("Main");
于 2012-06-29T08:49:50.417 回答
0

首先,您应该将包名称添加到您的类名中。

除了包名,请检查生成的类是否放在你的类路径中。这可以通过在调用编译任务时添加类输出文件夹选项来完成:

CompilationTask task = compiler.getTask(null, fileManager, null, Arrays.asList("-d", ""), null, fileObjects);

有一个很棒但轻量级的库可以在一次调用中完成您的工作,并完全在内存中编译源代码和加载类,请访问:

在使用 JavaCompiler 从另一个应用程序中编译类文件之后,我该如何运行它?

于 2013-01-22T03:16:42.250 回答