diff --git a/src/com/esotericsoftware/reflectasm/ConstructorAccess.java b/src/com/esotericsoftware/reflectasm/ConstructorAccess.java index eafbab1..6364462 100644 --- a/src/com/esotericsoftware/reflectasm/ConstructorAccess.java +++ b/src/com/esotericsoftware/reflectasm/ConstructorAccess.java @@ -49,55 +49,59 @@ public abstract class ConstructorAccess { String accessClassName = className + "ConstructorAccess"; if (accessClassName.startsWith("java.")) accessClassName = "reflectasm." + accessClassName; Class accessClass; - + AccessClassLoader loader = AccessClassLoader.get(type); - synchronized (loader) { - try { - accessClass = loader.loadClass(accessClassName); - } catch (ClassNotFoundException ignored) { - String accessClassNameInternal = accessClassName.replace('.', '/'); - String classNameInternal = className.replace('.', '/'); - String enclosingClassNameInternal; - Constructor constructor = null; - int modifiers = 0; - if (!isNonStaticMemberClass) { - enclosingClassNameInternal = null; - try { - constructor = type.getDeclaredConstructor((Class[])null); - modifiers = constructor.getModifiers(); - } catch (Exception ex) { - throw new RuntimeException("Class cannot be created (missing no-arg constructor): " + type.getName(), ex); - } - if (Modifier.isPrivate(modifiers)) { - throw new RuntimeException("Class cannot be created (the no-arg constructor is private): " + type.getName()); - } - } else { - enclosingClassNameInternal = enclosingType.getName().replace('.', '/'); - try { - constructor = type.getDeclaredConstructor(enclosingType); // Inner classes should have this. - modifiers = constructor.getModifiers(); - } catch (Exception ex) { - throw new RuntimeException("Non-static member class cannot be created (missing enclosing class constructor): " - + type.getName(), ex); - } - if (Modifier.isPrivate(modifiers)) { - throw new RuntimeException( - "Non-static member class cannot be created (the enclosing class constructor is private): " + type.getName()); + try { + accessClass = loader.loadClass(accessClassName); + } catch (ClassNotFoundException ignored) { + synchronized (loader) { + try { + accessClass = loader.loadClass(accessClassName); + } catch (ClassNotFoundException ignored2) { + String accessClassNameInternal = accessClassName.replace('.', '/'); + String classNameInternal = className.replace('.', '/'); + String enclosingClassNameInternal; + Constructor constructor = null; + int modifiers = 0; + if (!isNonStaticMemberClass) { + enclosingClassNameInternal = null; + try { + constructor = type.getDeclaredConstructor((Class[])null); + modifiers = constructor.getModifiers(); + } catch (Exception ex) { + throw new RuntimeException("Class cannot be created (missing no-arg constructor): " + type.getName(), ex); + } + if (Modifier.isPrivate(modifiers)) { + throw new RuntimeException("Class cannot be created (the no-arg constructor is private): " + type.getName()); + } + } else { + enclosingClassNameInternal = enclosingType.getName().replace('.', '/'); + try { + constructor = type.getDeclaredConstructor(enclosingType); // Inner classes should have this. + modifiers = constructor.getModifiers(); + } catch (Exception ex) { + throw new RuntimeException("Non-static member class cannot be created (missing enclosing class constructor): " + + type.getName(), ex); + } + if (Modifier.isPrivate(modifiers)) { + throw new RuntimeException( + "Non-static member class cannot be created (the enclosing class constructor is private): " + type.getName()); + } } + String superclassNameInternal = Modifier.isPublic(modifiers) ? + "com/esotericsoftware/reflectasm/PublicConstructorAccess" : + "com/esotericsoftware/reflectasm/ConstructorAccess"; + + ClassWriter cw = new ClassWriter(0); + cw.visit(V1_1, ACC_PUBLIC + ACC_SUPER, accessClassNameInternal, null, superclassNameInternal, null); + + insertConstructor(cw, superclassNameInternal); + insertNewInstance(cw, classNameInternal); + insertNewInstanceInner(cw, classNameInternal, enclosingClassNameInternal); + + cw.visitEnd(); + accessClass = loader.defineClass(accessClassName, cw.toByteArray()); } - String superclassNameInternal = Modifier.isPublic(modifiers) ? - "com/esotericsoftware/reflectasm/PublicConstructorAccess" : - "com/esotericsoftware/reflectasm/ConstructorAccess"; - - ClassWriter cw = new ClassWriter(0); - cw.visit(V1_1, ACC_PUBLIC + ACC_SUPER, accessClassNameInternal, null, superclassNameInternal, null); - - insertConstructor(cw, superclassNameInternal); - insertNewInstance(cw, classNameInternal); - insertNewInstanceInner(cw, classNameInternal, enclosingClassNameInternal); - - cw.visitEnd(); - accessClass = loader.defineClass(accessClassName, cw.toByteArray()); } } ConstructorAccess access; diff --git a/src/com/esotericsoftware/reflectasm/FieldAccess.java b/src/com/esotericsoftware/reflectasm/FieldAccess.java index 075ba9a..50f97e6 100644 --- a/src/com/esotericsoftware/reflectasm/FieldAccess.java +++ b/src/com/esotericsoftware/reflectasm/FieldAccess.java @@ -121,38 +121,42 @@ public abstract class FieldAccess { Class accessClass = null; AccessClassLoader loader = AccessClassLoader.get(type); - synchronized (loader) { - try { - accessClass = loader.loadClass(accessClassName); - } catch (ClassNotFoundException ignored) { - String accessClassNameInternal = accessClassName.replace('.', '/'); - String classNameInternal = className.replace('.', '/'); - - ClassWriter cw = new ClassWriter(0); - cw.visit(V1_1, ACC_PUBLIC + ACC_SUPER, accessClassNameInternal, null, "com/esotericsoftware/reflectasm/FieldAccess", - null); - insertConstructor(cw); - insertGetObject(cw, classNameInternal, fields); - insertSetObject(cw, classNameInternal, fields); - insertGetPrimitive(cw, classNameInternal, fields, Type.BOOLEAN_TYPE); - insertSetPrimitive(cw, classNameInternal, fields, Type.BOOLEAN_TYPE); - insertGetPrimitive(cw, classNameInternal, fields, Type.BYTE_TYPE); - insertSetPrimitive(cw, classNameInternal, fields, Type.BYTE_TYPE); - insertGetPrimitive(cw, classNameInternal, fields, Type.SHORT_TYPE); - insertSetPrimitive(cw, classNameInternal, fields, Type.SHORT_TYPE); - insertGetPrimitive(cw, classNameInternal, fields, Type.INT_TYPE); - insertSetPrimitive(cw, classNameInternal, fields, Type.INT_TYPE); - insertGetPrimitive(cw, classNameInternal, fields, Type.LONG_TYPE); - insertSetPrimitive(cw, classNameInternal, fields, Type.LONG_TYPE); - insertGetPrimitive(cw, classNameInternal, fields, Type.DOUBLE_TYPE); - insertSetPrimitive(cw, classNameInternal, fields, Type.DOUBLE_TYPE); - insertGetPrimitive(cw, classNameInternal, fields, Type.FLOAT_TYPE); - insertSetPrimitive(cw, classNameInternal, fields, Type.FLOAT_TYPE); - insertGetPrimitive(cw, classNameInternal, fields, Type.CHAR_TYPE); - insertSetPrimitive(cw, classNameInternal, fields, Type.CHAR_TYPE); - insertGetString(cw, classNameInternal, fields); - cw.visitEnd(); - accessClass = loader.defineClass(accessClassName, cw.toByteArray()); + try { + accessClass = loader.loadClass(accessClassName); + } catch (ClassNotFoundException ignored) { + synchronized (loader) { + try { + accessClass = loader.loadClass(accessClassName); + } catch (ClassNotFoundException ignored2) { + String accessClassNameInternal = accessClassName.replace('.', '/'); + String classNameInternal = className.replace('.', '/'); + + ClassWriter cw = new ClassWriter(0); + cw.visit(V1_1, ACC_PUBLIC + ACC_SUPER, accessClassNameInternal, null, "com/esotericsoftware/reflectasm/FieldAccess", + null); + insertConstructor(cw); + insertGetObject(cw, classNameInternal, fields); + insertSetObject(cw, classNameInternal, fields); + insertGetPrimitive(cw, classNameInternal, fields, Type.BOOLEAN_TYPE); + insertSetPrimitive(cw, classNameInternal, fields, Type.BOOLEAN_TYPE); + insertGetPrimitive(cw, classNameInternal, fields, Type.BYTE_TYPE); + insertSetPrimitive(cw, classNameInternal, fields, Type.BYTE_TYPE); + insertGetPrimitive(cw, classNameInternal, fields, Type.SHORT_TYPE); + insertSetPrimitive(cw, classNameInternal, fields, Type.SHORT_TYPE); + insertGetPrimitive(cw, classNameInternal, fields, Type.INT_TYPE); + insertSetPrimitive(cw, classNameInternal, fields, Type.INT_TYPE); + insertGetPrimitive(cw, classNameInternal, fields, Type.LONG_TYPE); + insertSetPrimitive(cw, classNameInternal, fields, Type.LONG_TYPE); + insertGetPrimitive(cw, classNameInternal, fields, Type.DOUBLE_TYPE); + insertSetPrimitive(cw, classNameInternal, fields, Type.DOUBLE_TYPE); + insertGetPrimitive(cw, classNameInternal, fields, Type.FLOAT_TYPE); + insertSetPrimitive(cw, classNameInternal, fields, Type.FLOAT_TYPE); + insertGetPrimitive(cw, classNameInternal, fields, Type.CHAR_TYPE); + insertSetPrimitive(cw, classNameInternal, fields, Type.CHAR_TYPE); + insertGetString(cw, classNameInternal, fields); + cw.visitEnd(); + accessClass = loader.defineClass(accessClassName, cw.toByteArray()); + } } } try { diff --git a/src/com/esotericsoftware/reflectasm/MethodAccess.java b/src/com/esotericsoftware/reflectasm/MethodAccess.java index 983439f..fb40c20 100644 --- a/src/com/esotericsoftware/reflectasm/MethodAccess.java +++ b/src/com/esotericsoftware/reflectasm/MethodAccess.java @@ -107,169 +107,173 @@ public abstract class MethodAccess { Class accessClass; AccessClassLoader loader = AccessClassLoader.get(type); - synchronized (loader) { - try { - accessClass = loader.loadClass(accessClassName); - } catch (ClassNotFoundException ignored) { - String accessClassNameInternal = accessClassName.replace('.', '/'); - String classNameInternal = className.replace('.', '/'); - - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); - MethodVisitor mv; - cw.visit(V1_1, ACC_PUBLIC + ACC_SUPER, accessClassNameInternal, null, "com/esotericsoftware/reflectasm/MethodAccess", - null); - { - mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); - mv.visitCode(); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "com/esotericsoftware/reflectasm/MethodAccess", "", "()V"); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - { - mv = cw.visitMethod(ACC_PUBLIC + ACC_VARARGS, "invoke", - "(Ljava/lang/Object;I[Ljava/lang/Object;)Ljava/lang/Object;", null, null); - mv.visitCode(); - - if (!methods.isEmpty()) { - mv.visitVarInsn(ALOAD, 1); - mv.visitTypeInsn(CHECKCAST, classNameInternal); - mv.visitVarInsn(ASTORE, 4); - - mv.visitVarInsn(ILOAD, 2); - Label[] labels = new Label[n]; - for (int i = 0; i < n; i++) - labels[i] = new Label(); - Label defaultLabel = new Label(); - mv.visitTableSwitchInsn(0, labels.length - 1, defaultLabel, labels); - - StringBuilder buffer = new StringBuilder(128); - for (int i = 0; i < n; i++) { - mv.visitLabel(labels[i]); - if (i == 0) - mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] {classNameInternal}, 0, null); - else - mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); - mv.visitVarInsn(ALOAD, 4); - - buffer.setLength(0); - buffer.append('('); - - Class[] paramTypes = parameterTypes[i]; - Class returnType = returnTypes[i]; - for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) { - mv.visitVarInsn(ALOAD, 3); - mv.visitIntInsn(BIPUSH, paramIndex); - mv.visitInsn(AALOAD); - Type paramType = Type.getType(paramTypes[paramIndex]); - switch (paramType.getSort()) { + try { + accessClass = loader.loadClass(accessClassName); + } catch (ClassNotFoundException ignored) { + synchronized (loader) { + try { + accessClass = loader.loadClass(accessClassName); + } catch (ClassNotFoundException ignored2) { + String accessClassNameInternal = accessClassName.replace('.', '/'); + String classNameInternal = className.replace('.', '/'); + + ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); + MethodVisitor mv; + cw.visit(V1_1, ACC_PUBLIC + ACC_SUPER, accessClassNameInternal, null, "com/esotericsoftware/reflectasm/MethodAccess", + null); + { + mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); + mv.visitCode(); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESPECIAL, "com/esotericsoftware/reflectasm/MethodAccess", "", "()V"); + mv.visitInsn(RETURN); + mv.visitMaxs(0, 0); + mv.visitEnd(); + } + { + mv = cw.visitMethod(ACC_PUBLIC + ACC_VARARGS, "invoke", + "(Ljava/lang/Object;I[Ljava/lang/Object;)Ljava/lang/Object;", null, null); + mv.visitCode(); + + if (!methods.isEmpty()) { + mv.visitVarInsn(ALOAD, 1); + mv.visitTypeInsn(CHECKCAST, classNameInternal); + mv.visitVarInsn(ASTORE, 4); + + mv.visitVarInsn(ILOAD, 2); + Label[] labels = new Label[n]; + for (int i = 0; i < n; i++) + labels[i] = new Label(); + Label defaultLabel = new Label(); + mv.visitTableSwitchInsn(0, labels.length - 1, defaultLabel, labels); + + StringBuilder buffer = new StringBuilder(128); + for (int i = 0; i < n; i++) { + mv.visitLabel(labels[i]); + if (i == 0) + mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] {classNameInternal}, 0, null); + else + mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 4); + + buffer.setLength(0); + buffer.append('('); + + Class[] paramTypes = parameterTypes[i]; + Class returnType = returnTypes[i]; + for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) { + mv.visitVarInsn(ALOAD, 3); + mv.visitIntInsn(BIPUSH, paramIndex); + mv.visitInsn(AALOAD); + Type paramType = Type.getType(paramTypes[paramIndex]); + switch (paramType.getSort()) { + case Type.BOOLEAN: + mv.visitTypeInsn(CHECKCAST, "java/lang/Boolean"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z"); + break; + case Type.BYTE: + mv.visitTypeInsn(CHECKCAST, "java/lang/Byte"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B"); + break; + case Type.CHAR: + mv.visitTypeInsn(CHECKCAST, "java/lang/Character"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C"); + break; + case Type.SHORT: + mv.visitTypeInsn(CHECKCAST, "java/lang/Short"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S"); + break; + case Type.INT: + mv.visitTypeInsn(CHECKCAST, "java/lang/Integer"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I"); + break; + case Type.FLOAT: + mv.visitTypeInsn(CHECKCAST, "java/lang/Float"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F"); + break; + case Type.LONG: + mv.visitTypeInsn(CHECKCAST, "java/lang/Long"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J"); + break; + case Type.DOUBLE: + mv.visitTypeInsn(CHECKCAST, "java/lang/Double"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D"); + break; + case Type.ARRAY: + mv.visitTypeInsn(CHECKCAST, paramType.getDescriptor()); + break; + case Type.OBJECT: + mv.visitTypeInsn(CHECKCAST, paramType.getInternalName()); + break; + } + buffer.append(paramType.getDescriptor()); + } + + buffer.append(')'); + buffer.append(Type.getDescriptor(returnType)); + int invoke; + if (isInterface) + invoke = INVOKEINTERFACE; + else if (Modifier.isStatic(methods.get(i).getModifiers())) + invoke = INVOKESTATIC; + else + invoke = INVOKEVIRTUAL; + mv.visitMethodInsn(invoke, classNameInternal, methodNames[i], buffer.toString()); + + switch (Type.getType(returnType).getSort()) { + case Type.VOID: + mv.visitInsn(ACONST_NULL); + break; case Type.BOOLEAN: - mv.visitTypeInsn(CHECKCAST, "java/lang/Boolean"); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z"); + mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;"); break; case Type.BYTE: - mv.visitTypeInsn(CHECKCAST, "java/lang/Byte"); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B"); + mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;"); break; case Type.CHAR: - mv.visitTypeInsn(CHECKCAST, "java/lang/Character"); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C"); + mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;"); break; case Type.SHORT: - mv.visitTypeInsn(CHECKCAST, "java/lang/Short"); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S"); + mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;"); break; case Type.INT: - mv.visitTypeInsn(CHECKCAST, "java/lang/Integer"); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I"); + mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;"); break; case Type.FLOAT: - mv.visitTypeInsn(CHECKCAST, "java/lang/Float"); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F"); + mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;"); break; case Type.LONG: - mv.visitTypeInsn(CHECKCAST, "java/lang/Long"); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J"); + mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;"); break; case Type.DOUBLE: - mv.visitTypeInsn(CHECKCAST, "java/lang/Double"); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D"); - break; - case Type.ARRAY: - mv.visitTypeInsn(CHECKCAST, paramType.getDescriptor()); - break; - case Type.OBJECT: - mv.visitTypeInsn(CHECKCAST, paramType.getInternalName()); + mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;"); break; } - buffer.append(paramType.getDescriptor()); + + mv.visitInsn(ARETURN); } - - buffer.append(')'); - buffer.append(Type.getDescriptor(returnType)); - int invoke; - if (isInterface) - invoke = INVOKEINTERFACE; - else if (Modifier.isStatic(methods.get(i).getModifiers())) - invoke = INVOKESTATIC; - else - invoke = INVOKEVIRTUAL; - mv.visitMethodInsn(invoke, classNameInternal, methodNames[i], buffer.toString()); - - switch (Type.getType(returnType).getSort()) { - case Type.VOID: - mv.visitInsn(ACONST_NULL); - break; - case Type.BOOLEAN: - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;"); - break; - case Type.BYTE: - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;"); - break; - case Type.CHAR: - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;"); - break; - case Type.SHORT: - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;"); - break; - case Type.INT: - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;"); - break; - case Type.FLOAT: - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;"); - break; - case Type.LONG: - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;"); - break; - case Type.DOUBLE: - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;"); - break; - } - - mv.visitInsn(ARETURN); + + mv.visitLabel(defaultLabel); + mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); } - - mv.visitLabel(defaultLabel); - mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); + mv.visitTypeInsn(NEW, "java/lang/IllegalArgumentException"); + mv.visitInsn(DUP); + mv.visitTypeInsn(NEW, "java/lang/StringBuilder"); + mv.visitInsn(DUP); + mv.visitLdcInsn("Method not found: "); + mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "", "(Ljava/lang/String;)V"); + mv.visitVarInsn(ILOAD, 2); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(I)Ljava/lang/StringBuilder;"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;"); + mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalArgumentException", "", "(Ljava/lang/String;)V"); + mv.visitInsn(ATHROW); + mv.visitMaxs(0, 0); + mv.visitEnd(); } - mv.visitTypeInsn(NEW, "java/lang/IllegalArgumentException"); - mv.visitInsn(DUP); - mv.visitTypeInsn(NEW, "java/lang/StringBuilder"); - mv.visitInsn(DUP); - mv.visitLdcInsn("Method not found: "); - mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "", "(Ljava/lang/String;)V"); - mv.visitVarInsn(ILOAD, 2); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(I)Ljava/lang/StringBuilder;"); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;"); - mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalArgumentException", "", "(Ljava/lang/String;)V"); - mv.visitInsn(ATHROW); - mv.visitMaxs(0, 0); - mv.visitEnd(); + cw.visitEnd(); + byte[] data = cw.toByteArray(); + accessClass = loader.defineClass(accessClassName, data); } - cw.visitEnd(); - byte[] data = cw.toByteArray(); - accessClass = loader.defineClass(accessClassName, data); } } try {