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

しかし、うまくいきません。取得エラー: スレッド「メイン」の例外 java.lang.NoSuchMethodException: com.tom.labs.CompilerTest.メイン (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()、パブリック最終ネイティブ void java.lang.Object.notify()、パブリック最終ネイティブ 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);

たった 1 回の呼び出しで作業を実行し、ソースをコンパイルしてクラスを完全にメモリにロードできる、素晴らしく軽量なライブラリがあります。ぜひアクセスしてください。

JavaCompiler を使用して別のアプリケーション内からクラス ファイルをコンパイルした後、それを実行するにはどうすればよいですか?

于 2013-01-22T03:16:42.250 に答える