我有一个程序,我编译有人在文本框中写入的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);
}
}
className
为TEMPCLASS$InnerClass
,数据为表示类文件的字节。这适用于外部类。
答案 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();
以前,我使用的是一些旧文档,这些文档只会使整个过程变得复杂。