在运行时加载内部类

时间:2011-08-02 19:10:24

标签: java runtime inner-classes classloader

我有一个程序,我编译有人在文本框中写入的java代码,然后运行它。 他们输入完整的源代码,类和所有

我将他们写的类保存到随机的java源文件中,然后通过类加载器编译并加载该类。这非常有效。

我有一个新问题,即子类的问题。我给外层一个唯一的名称,并加载该类。

实施例

TEMP1110.java -> TEMP1110.class等 对于内部类,它编译为TEMP1110$InnerClass.class 我尝试通过我的类加载器加载这个类,但是当外部类调用它时:new InnerClass().method();

它给了我这个:java.lang.NoClassDefFoundError: TEMP1110$InnerClass

是否有一些怪癖或我做错了什么?

我的类加载器:

private static class JClassLoader extends ClassLoader {
    public Class buildClass(final byte[] data, final String className) {
        return (Class) defineClass(className, data, 0, data.length);
    }
}

classNameTEMPCLASS$InnerClass,数据为表示类文件的字节。这适用于外部类。

3 个答案:

答案 0 :(得分:0)

我认为'new InnerClass()'使用普通的类加载和类路径搜索来查找类。由于生成的.class文件不在类路径上,因此无法找到。

尝试动态操作类路径以添加.class文件所在的文件夹:

String currentPath = System.getProperty("java.library.path");
System.setProperty( "java.library.path", current + ":/path/to/my/classfiles" );

// this forces JVM to reload "java.library.path" property
Field fieldSysPath = ClassLoader.class.getDeclaredField( "sys_paths" );
fieldSysPath.setAccessible( true );
fieldSysPath.set( null, null );

答案 1 :(得分:0)

API spec开始,当发送给defineClass的名称与由bytes表示的类的二进制名称不匹配时,看起来会抛出NoClassDefFoundError

您可以尝试为内部类className传递null。

答案 2 :(得分:0)

我的最终解决方案,我是界面:

ClassLoader cl = new URLClassLoader(new URL[] {new File("TEMP/").toURI().toURL()});
Class classd = cl.loadClass(className);
return (I) classd.newInstance();

以前,我使用的是一些旧文档,这些文档只会使整个过程变得复杂。