IntrabandProxyUtil { protected static Class<?> generateStubClass( ClassLoader classLoader, Class<?> clazz, String skeletonId) { String internalName = Type.getInternalName(clazz); ClassNode classNode = ASMUtil.loadAndRename( clazz, internalName.concat(STUB_POSTFIX)); classNode.access &= ~(Opcodes.ACC_ABSTRACT | Opcodes.ACC_INTERFACE); classNode.access |= Opcodes.ACC_PUBLIC; if (clazz.isInterface()) { List<String> interfaces = classNode.interfaces; interfaces.clear(); interfaces.add(internalName); } List<MethodNode> methodNodes = classNode.methods; MethodNode defaultInitMethodNode = ASMUtil.removeMethodNode( methodNodes, "<init>", Type.VOID_TYPE); ASMUtil.removeMethodNodes(methodNodes, "<init>"); ASMUtil.removeMethodNodes(methodNodes, Opcodes.ACC_ABSTRACT); ASMUtil.removeMethodNodes(methodNodes, _annotationDescriptors); ClassNode templateClassNode = ASMUtil.loadAndRename( TemplateStub.class, classNode.name); List<FieldNode> templateFieldNodes = templateClassNode.fields; FieldNode idFieldNode = ASMUtil.findFieldNode( templateFieldNodes, "_id"); idFieldNode.access |= Opcodes.ACC_FINAL; FieldNode intrabandFieldNode = ASMUtil.findFieldNode( templateFieldNodes, "_intraband"); intrabandFieldNode.access |= Opcodes.ACC_FINAL; FieldNode registrationReferenceFieldNode = ASMUtil.findFieldNode( templateFieldNodes, "_registrationReference"); registrationReferenceFieldNode.access |= Opcodes.ACC_FINAL; ASMUtil.addFieldNodes(classNode.fields, templateFieldNodes); List<MethodNode> templateMethodNodes = templateClassNode.methods; MethodNode templateInitMethodNode = ASMUtil.findMethodNode( templateMethodNodes, "<init>", Type.VOID_TYPE, _STRING_TYPE, _REGISTRATION_REFERENCE_TYPE, _EXCEPTION_HANDLER_TYPE); if (defaultInitMethodNode != null) { ASMUtil.mergeMethods( templateInitMethodNode, defaultInitMethodNode, templateInitMethodNode); } MethodNode defaultClinitMethodNode = ASMUtil.removeMethodNode( methodNodes, "<clinit>", Type.VOID_TYPE); if (defaultClinitMethodNode != null) { MethodNode templateClinitMethodNode = ASMUtil.findMethodNode( templateMethodNodes, "<clinit>", Type.VOID_TYPE); ASMUtil.mergeMethods( templateClinitMethodNode, defaultClinitMethodNode, templateClinitMethodNode); } methodNodes.addAll(templateMethodNodes); Type stubType = Type.getType(classNode.name); MethodsBag methodsBag = extractMethods(clazz); for (Method idMethod : methodsBag.idMethods) { MethodNodeGenerator methodNodeGenerator = new MethodNodeGenerator( idMethod); methodNodeGenerator.loadThis(); methodNodeGenerator.getField(stubType, "_id", _STRING_TYPE); methodNodeGenerator.returnValue(); methodNodeGenerator.endMethod(); methodNodes.add(methodNodeGenerator.getMethodNode()); } List<Method> proxyMethods = methodsBag.proxyMethods; for (int i = 0; i < proxyMethods.size(); i++) { methodNodes.add( createProxyMethodNode( proxyMethods.get(i), i, skeletonId, stubType)); } for (Method emptyMethod : methodsBag.emptyMethods) { MethodNodeGenerator methodNodeGenerator = new MethodNodeGenerator( emptyMethod); ASMUtil.addDefaultReturnInsns( methodNodeGenerator, Type.getType(emptyMethod.getReturnType())); methodNodeGenerator.endMethod(); methodNodes.add(methodNodeGenerator.getMethodNode()); } rewriteGetProxyMethodSignaturesMethodNode( classNode, methodsBag.proxyMethodSignatures); return toClass(classNode, classLoader); }  static String[] getProxyMethodSignatures(Class<?> clazz); static Class<?> getStubClass(Class<?> clazz, String skeletonId); static Class<?> getStubClass(
		ClassLoader classLoader, Class<?> clazz, String skeletonId); static T newStubInstance(
		Class<? extends T> stubClass, String id,
		RegistrationReference registrationReference,
		ExceptionHandler exceptionHandler); static final String SKELETON_POSTFIX; static final String STUB_POSTFIX; }
@NewEnv(type = NewEnv.Type.CLASSLOADER) @Test public void testGenerateStubClassFunction() throws Exception { String skeletonId = "skeletonId"; Class<?> stubClass = IntrabandProxyUtil.generateStubClass( _classLoader, TestGenerateStubFunction1.class, skeletonId); Constructor<?> constructor = stubClass.getConstructor( String.class, RegistrationReference.class, ExceptionHandler.class); String testId = "testId"; AutoReplyMockIntraband autoReplyMockIntraband = new AutoReplyMockIntraband(skeletonId, testId); RegistrationReference registrationReference = new MockRegistrationReference(autoReplyMockIntraband); Object stubObject = null; try (CaptureHandler captureHandler = JDKLoggerTestUtil.configureJDKLogger( stubClass.getName(), Level.INFO)) { List<LogRecord> logRecords = captureHandler.getLogRecords(); stubObject = constructor.newInstance( testId, registrationReference, WarnLogExceptionHandler.INSTANCE); Assert.assertEquals(2, logRecords.size()); LogRecord logRecord = logRecords.get(0); Assert.assertEquals( stubClass.getName() + " in <clinit>", logRecord.getMessage()); logRecord = logRecords.get(1); Assert.assertEquals( stubClass.getName() + " in <init>", logRecord.getMessage()); } Assert.assertSame( registrationReference, ReflectionTestUtil.getFieldValue( stubObject, "_registrationReference")); Assert.assertSame( WarnLogExceptionHandler.INSTANCE, ReflectionTestUtil.getFieldValue(stubObject, "_exceptionHandler")); Assert.assertSame( autoReplyMockIntraband, ReflectionTestUtil.getFieldValue(stubObject, "_intraband")); stubClass = IntrabandProxyUtil.generateStubClass( _classLoader, TestGenerateStubFunction2.class, skeletonId); constructor = stubClass.getConstructor( String.class, RegistrationReference.class, ExceptionHandler.class); stubObject = constructor.newInstance( testId, registrationReference, WarnLogExceptionHandler.INSTANCE); for (Method idMethod : _getIdMethods(TestGenerateStubFunction2.class)) { Assert.assertEquals( testId, ReflectionTestUtil.invoke( stubObject, idMethod.getName(), new Class<?>[0])); } List<Method> proxyMethods = _getProxyMethods( TestGenerateStubFunction2.class); for (int i = 0; i < proxyMethods.size(); i++) { Method proxyMethod = proxyMethods.get(i); Class<?>[] parameterTypes = proxyMethod.getParameterTypes(); Object[] args = new Object[parameterTypes.length]; for (int j = 0; j < args.length; j++) { args[j] = _sampleValueMap.get(parameterTypes[j]); } autoReplyMockIntraband.setInvocation(proxyMethod, i); Object object = ReflectionTestUtil.invoke( stubObject, proxyMethod.getName(), proxyMethod.getParameterTypes(), args); Assert.assertEquals( _sampleValueMap.get(proxyMethod.getReturnType()), object); } for (Method emptyMethod : _getEmptyMethods(TestGenerateStubFunction2.class)) { Assert.assertEquals( _defaultValueMap.get(emptyMethod.getReturnType()), ReflectionTestUtil.invoke( stubObject, emptyMethod.getName(), new Class<?>[0])); } List<Method> copiedMethods = _getCopiedMethods( TestGenerateStubFunction2.class); Collections.sort(copiedMethods, new Comparator<Method>() { @Override public int compare(Method method1, Method method2) { String name1 = method1.getName(); String name2 = method2.getName(); return name1.compareTo(name2); } }); try (CaptureHandler captureHandler = JDKLoggerTestUtil.configureJDKLogger( stubClass.getName(), Level.INFO)) { List<LogRecord> logRecords = captureHandler.getLogRecords(); for (Method copiedMethod : copiedMethods) { ReflectionTestUtil.invoke( stubObject, copiedMethod.getName(), new Class<?>[0]); LogRecord logRecord = logRecords.get(logRecords.size() - 1); Assert.assertEquals( copiedMethod.getName(), logRecord.getMessage()); } } }