В настоящее время я разрабатываю пользовательскую структуру ORM и использую ASM для динамического создания подклассов во время выполнения. Процесс генерации, похоже, завершен ОК, однако, когда я пытаюсь создать экземпляр полученного класса, я получаю «NoClassDefFoundError».Динамическое создание подкласса во время выполнения
Ошибка, похоже, относится к классу Super, а не к фактическому подклассу. Вот выдержка из метода генерации подкласса:
private Class generateProxyClass(Class anEntitySuperClass,
List<Field> fieldsToIntercept) throws ClassNotFoundException{
String entitySuperClassName = this.convertToInternalName(anEntitySuperClass.getName());
//String entityProxySubClassName = "com/flux/dynamic/".concat(anEntitySuperClass.getSimpleName()).concat("Proxy");
String entityProxySubClassName = anEntitySuperClass.getSimpleName().concat("Proxy");
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
cw.visit(V1_6,ACC_PUBLIC+ACC_SUPER,entityProxySubClassName,null,entitySuperClassName,null);
cw.visitSource(entityProxySubClassName.concat(".java"),null);
//create constructor
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC,"<init>","()V",null,null);
mv.visitCode();
//have our consturctor initailise its super class.
mv.visitVarInsn(ALOAD,0);
mv.visitMethodInsn(INVOKESPECIAL,entitySuperClassName,"<init>","()V");
mv.visitInsn(RETURN);
mv.visitMaxs(0,0);
mv.visitEnd();
this.generateAndAppendProxyAccessorMethods(anEntitySuperClass,fieldsToIntercept, cw);
cw.visitEnd();
//at this point our class should be fully generated an include all required fields. next we
//convert the class to a byte array and pass it in to our helper method to load an
//actual class from the byte array.
return this.loadProxyClass(cw.toByteArray(),entityProxySubClassName);
}
Метод «loadProxyClass» назвал выше вспомогательный метод, который в основном конкретизирует и вызывает пользовательский ClassLoader для того, чтобы загрузить динамически созданный класс:
/**loads the generated proxy class from the provided bytes. */
private Class loadProxyClass(byte[] aGeneratedProxyClass,String proxyClassName) throws ClassNotFoundException{
return new ProxyClassLoader(Thread.currentThread().getContextClassLoader(),aGeneratedProxyClass)
.loadClass(this.convertToExternalName(proxyClassName));
}
ProxyClassLoader просто расширяет ClassLoader и переопределяет метод «findClass» для того, чтобы загрузить динамически генерируемый класс байт:
public class ProxyClassLoader extends ClassLoader {
private byte[] rawClassBytes;
public ProxyClassLoader(ClassLoader parentClassLoader,byte[] classBytes){
super(parentClassLoader);
this.rawClassBytes = classBytes;
}
@Override
public Class findClass(String name) {
return defineClass(name,this.rawClassBytes, 0,this.rawClassBytes.length);
}
}
Ошибки я получаю: Exception in thread "main" java.lang.NoClassDefFoundError: DummyEntity (wrong name: DummyEntityProxy)
DummyEntity
Где это супер класс я прохожу в метод generateProxyClass
и DummyEntityProxy
класс я пытаюсь создать. Я в тупик, любая помощь будет очень признательна.
Только для дальнейших ссылок: с Java 8 сообщения об ошибках верификатора стали более читаемыми. –