【问题标题】:Loading inner classes at runtime在运行时加载内部类
【发布时间】:2011-09-12 22:04:52
【问题描述】:

我有一个程序,我在其中编译某人在文本框中编写的 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,数据是表示类文件的字节。这适用于外部类。

【问题讨论】:

  • 愚蠢的观点,但你已经把“它编译为TEMP1110$InnerClass.java”。这是一个错误类型,还是它需要是 .class 并且文件名错误的问题?
  • 如果内部类不是静态的,你不需要先加载外部类吗?见这里:stackoverflow.com/questions/2868337/…

标签: java runtime inner-classes classloader


【解决方案1】:

我想'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 );

【讨论】:

  • 感谢您的建议,我将对此进行调查并尽快报告。
【解决方案2】:

API spec 看来,当您发送给defineClass 的名称与字节表示的类的二进制名称不匹配时,似乎会抛出NoClassDefFoundError

您可以尝试将 null 传递给内部类的 className

【讨论】:

    【解决方案3】:

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

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

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

    【讨论】:

      猜你喜欢
      • 2012-04-11
      • 2013-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-08
      • 2013-03-13
      相关资源
      最近更新 更多