代码之家  ›  专栏  ›  技术社区  ›  Amir Afghani

为什么Java类加载器找不到我的接口?

  •  2
  • Amir Afghani  · 技术社区  · 14 年前

    在下面的代码中,我使用 sun.tools.javac.Main . 我将使用反射创建这个类的新实例。问题是,我想避免使用反射来调用为此类定义的方法,所以我创建了一个ProxyInvoker,它引用了我在项目中定义的接口。为了让类加载器看到这一点,我将类路径添加到类加载器的可执行接口。在“编译”步骤中,我仍然得到一个错误,该错误表示找不到我的接口。

    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileWriter;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.net.URLClassLoader;
    
    public class MyClassGenerator {
    
        static final String generatedClassName = "TestHello_" + System.currentTimeMillis();
        static final String javaFileName = generatedClassName + ".java";
    
        static URLClassLoader classLoader;
    
        public static void main(final String args[])
                throws MalformedURLException {
            final ProxyInvoker proxy = new ProxyInvoker();
            generateClass();
            loadExecutableInterface();
            if (compileClass()) {
                System.out.println("Running " + generatedClassName + ":\n\n");
                final Executable ex = createExecutable();
                ex.execute();
            }
            else {
                System.out.println(javaFileName + " is bad.");
            }
        }
    
        public static void loadExecutableInterface()
                throws MalformedURLException {
    
            final File file = new File("."); // <-- the directory where the generated java class is defined
            final File file2 = new File("src"); // <-- the directory where interface Executable is defined
    
            try {
                classLoader = URLClassLoader.newInstance(new URL[] { file.toURI().toURL(), file2.toURI().toURL() });
                try {
                    classLoader.loadClass("Executable");
                }
                catch (final ClassNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            catch (final MalformedURLException e) {
                e.printStackTrace();
            }
            System.out.println(file.toURI().toURL());
            System.out.println(file2.toURI().toURL());
    
        }
    
        public static void generateClass() {
            try {
                final FileWriter aWriter = new FileWriter(javaFileName, true);
                aWriter.write("public class " + generatedClassName + " implements Executable {");
                aWriter.write("\n");
                aWriter.write("\n");
                aWriter.write("    public void invoke() {");
                aWriter.write("        System.out.println(\"Hello World!\");");
                aWriter.write("    }");
                aWriter.write("\n");
                aWriter.write("}");
                aWriter.flush();
                aWriter.close();
            }
            catch (final Exception e) {
                e.printStackTrace();
            }
        }
    
        public static boolean compileClass() {
            final String[] source = { new String(javaFileName) };
            final ByteArrayOutputStream baos = new ByteArrayOutputStream();
            new sun.tools.javac.Main(baos, source[0]).compile(source);
            System.out.print(baos.toString());
            return (baos.toString().indexOf("error") == -1);
        }
    
        public static Executable createExecutable() {
    
            Executable instance = null;
    
            try {
                final Class<?> genClass = Class.forName(generatedClassName, true, classLoader);
                instance = (Executable) genClass.newInstance();
            }
            catch (final Exception e) {
                e.printStackTrace();
            }
    
            return instance;
    
        }
    }
    
    class ProxyInvoker {
    
        Executable myExecutable;
    
        public void runIt() {
    
            final Executable myExecutable;
    
        }
    
    }
    
    1 回复  |  直到 14 年前
        1
  •  6
  •   Neeme Praks Tim Pote    14 年前

    以下是您的代码的工作版本:

    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileWriter;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.net.URLClassLoader;
    
    public class MyClassGenerator {
    
        static final String generatedClassName = "TestHello_" + System.currentTimeMillis();
        static final String javaFileName = generatedClassName + ".java";
    
        static URLClassLoader classLoader;
    
        public static void main(final String args[])
                throws MalformedURLException {
            generateClass();
            loadExecutableInterface();
            if (compileClass()) {
                System.out.println("Running " + generatedClassName + ":\n\n");
                final Executable ex = createExecutable();
                ex.execute();
            }
            else {
                System.out.println(javaFileName + " is bad.");
            }
        }
    
        public static void loadExecutableInterface()
                throws MalformedURLException {
    
            final File file = new File("."); // <-- the directory where the generated java class is defined
    
            try {
                classLoader = URLClassLoader.newInstance(new URL[] { file.toURI().toURL() }, Executable.class.getClassLoader());
                try {
                    classLoader.loadClass("Executable");
                }
                catch (final ClassNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            catch (final MalformedURLException e) {
                e.printStackTrace();
            }
            System.out.println(file.toURI().toURL());
    
        }
    
        public static void generateClass() {
            try {
                final FileWriter aWriter = new FileWriter(javaFileName, true);
                aWriter.write("public class " + generatedClassName + " implements Executable {");
                aWriter.write("\n");
                aWriter.write("\n");
                aWriter.write("    public void execute() {");
                aWriter.write("        System.out.println(\"Hello World!\");");
                aWriter.write("    }");
                aWriter.write("\n");
                aWriter.write("}");
                aWriter.flush();
                aWriter.close();
            }
            catch (final Exception e) {
                e.printStackTrace();
            }
        }
    
        public static boolean compileClass() {
            final String[] source = { "-classpath", "target/classes", javaFileName };
            final ByteArrayOutputStream baos = new ByteArrayOutputStream();
            new sun.tools.javac.Main(baos, source[0]).compile(source);
            System.out.print(baos.toString());
            return (baos.toString().indexOf("error") == -1);
        }
    
        public static Executable createExecutable() {
    
            Executable instance = null;
    
            try {
                final Class<?> genClass = Class.forName(generatedClassName, true, classLoader);
                instance = (Executable) genClass.newInstance();
            }
            catch (final Exception e) {
                e.printStackTrace();
            }
    
            return instance;
    
        }
    
    }
    

    这个 主要变化 :classloader和编译部分出错。