I'm currently developing a custom ORM framework and utilising ASM to dynamically generate sub classes at runtime. The generation process seems to complete OK, however when I try to instantiate the resulting class I'm getting a "NoClassDefFoundError".
The error seems to pertain to the Super class rather then the actual subclass. Here is an excerpt from the subclass generation method:
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); } The "loadProxyClass" method called above is a helper method that basically instantiates and calls a custom ClassLoader in order to load the dynamically created class:
/**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)); } The ProxyClassLoader simply extends ClassLoader and overrides the "findClass" method in order to load the Dynamically Generated class bytes:
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); } } The error I get is: Exception in thread "main" java.lang.NoClassDefFoundError: DummyEntity (wrong name: DummyEntityProxy)
Where the DummyEntity is the super class I pass into the generateProxyClass method and the DummyEntityProxy is the class I'm attempting to generate. I'm stumped, any help would be greatly appreciated.