在运行时加载ASM生成的类

时间:2015-07-05 00:15:16

标签: java java-bytecode-asm

我通过ASM编写了一些字节码(生成的类实现了一些已知的接口)。

我对其他类也有一些依赖。

现在我想将字节数组挂钩到某个类中。

如何从字节数组加载类?

现在我得到NoClassDefFoundError:IllegalName:core / selecter / ObjectSelector / codegen / testClass.class

我使用此代码加载类:

@SuppressWarnings("unchecked")
private static <T> SelectorAccess<T> createNewOrNull(byte[] bytesOfClass, String name) {
    try {
        return (SelectorAccess<T>) new ClassLoader() {
            public Class<?> defineClass(byte[] bytes) {
                return super.defineClass(name.concat(".class"), bytes, 0, bytes.length);
            }
        }.defineClass(bytesOfClass).newInstance();
    } catch (InstantiationException | IllegalAccessException e) {
        e.printStackTrace();
        return null;
    }
}

我认为这是因为我的ClassLoader不知道我的类的依赖关系?

我该如何避免这个问题?

1 个答案:

答案 0 :(得分:2)

嗯,异常指向它:“IllegalName:core / selecter / ObjectSelector / codegen / testClass.class”。这不是ClassLoader.defineClass预期的合法类名:

  

参数:

     

name - 类的预期binary name,如果不知道则为null

...

  

二进制名称

     

ClassLoader中作为String参数提供的任何类名必须是 The Java™Language Specification 定义的二进制名称。

     

有效类名的示例包括:

"java.lang.String"
"javax.swing.JSpinner$DefaultEditor"
"java.security.KeyStore$Builder$FileBuilder$1"
"java.net.URLClassLoader$3$1"

你得到的图片,该方法需要一个没有.class后缀的点分隔名称。即如果您的类的类文件内部名称确实为core/selecter/ObjectSelector/codegen/testClass,则defineClass的正确名称将为core.selecter.ObjectSelector.codegen.testClass

但请注意,提及可以简单地将null传递给name参数......