/** * {@inheritDoc} */ @Override public IProxyClassInfo createProxyClass(IProxyBuildPlan plan) { String internalName = AsmUtil.getAsmInternalName(plan.getProxyClassName()); Type proxyType = Type.getObjectType(internalName); String[] interfaces = getInternalNames(plan.getImplementedInterfaces()); String superClass = Type.getInternalName(plan.getSuperClass()); // generate a new class for the proxy with the defined interfaces and superclass ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); cw.visit(V1_5, ACC_PUBLIC, internalName, null, superClass, interfaces); // create the subject field cw.visitField(ACC_PUBLIC, SUBJECT_FIELD, IInstrumenterConstant.OBJECT_TYPE.getDescriptor(), null, null).visitEnd(); // create the fields for the delegation-target methods // The result map maps the proxied methods to their generated field's names Map<IMethodBuildPlan, String> methodFields = generateDelegationMethodTargetFields(plan, cw); generateConstructor(plan, proxyType, cw); // create the proxied methods for (Entry<IMethodBuildPlan, String> entry : methodFields.entrySet()) { createDelegationMethod(proxyType, entry.getKey(), entry.getValue(), cw); } cw.visitEnd(); byte[] bytecode = cw.toByteArray(); Class<?> cl = loadClass(bytecode, plan.getProxyClassName(), plan.getTargetClassLoader()); // inject the method fields injectDelegationTargetFields(plan, methodFields, cl); return new ASMProxyClassInfo(cl); }
@Test public void testProxyInvalidPlanHandling() { // classloader does not contain the required depdendencies Object proxyA = linker.createProxy(CorrectProxySubject.class, new CorrectProxySubject(), this.getClass().getClassLoader()); Object proxyB = linker.createProxy(CorrectProxySubject.class, new CorrectProxySubject(), this.getClass().getClassLoader()); verify(proxyBuilder, times(0)).createProxyClass(any(IProxyBuildPlan.class)); assertThat(proxyA, equalTo(null)); assertThat(proxyB, equalTo(null)); }
paramTypes.addAll(plan.getConstructorParameterTypes()); Method constructor = new Method(IInstrumenterConstant.CONSTRUCTOR_INTERNAL_NAME, Type.VOID_TYPE, getTypes(paramTypes)); Method superConstructor = new Method(IInstrumenterConstant.CONSTRUCTOR_INTERNAL_NAME, Type.VOID_TYPE, getTypes(plan.getConstructorParameterTypes())); GeneratorAdapter mg = new GeneratorAdapter(ACC_PUBLIC, constructor, null, getTypes(plan.getConstructorExceptions()), cw);
Method invokeMethod = new Method("invoke", IInstrumenterConstant.OBJECT_TYPE, invokeMethodArgs); Method meth = new Method(plan.getMethodName(), Type.getType(plan.getReturnType()), getTypes(plan.getParameterTypes())); GeneratorAdapter mg = new GeneratorAdapter(ACC_PUBLIC, meth, null, new Type[] {}, cv);
@Test public void testProxyGenerationErrorHandling() { doReturn(null).when(proxyBuilder).createProxyClass(any(IProxyBuildPlan.class)); Object proxyA = linker.createProxy(CorrectProxySubject.class, new CorrectProxySubject(), fakeRootLoader); Object proxyB = linker.createProxy(CorrectProxySubject.class, new CorrectProxySubject(), fakeRootLoader); verify(proxyBuilder, times(1)).createProxyClass(any(IProxyBuildPlan.class)); assertThat(proxyA, equalTo(null)); assertThat(proxyB, equalTo(null)); }
@Test public void testProxyParentClassLoaderCaching() { linker.createProxy(CorrectProxySubject.class, new CorrectProxySubject(), fakeRootLoader); linker.createProxy(CorrectProxySubject.class, new CorrectProxySubject(), new ClassLoader(fakeRootLoader) { }); verify(proxyBuilder, times(1)).createProxyClass(any(IProxyBuildPlan.class)); }
@BeforeMethod public void initProxy() throws InvalidProxyDescriptionException { subject = new CorrectProxySubject(); ClassLoader cl = new RenamingClassLoader(this.getClass().getClassLoader(), "moved.", ClassToProxy.class, InterfaceToProxy.class); IProxyBuildPlan plan = ProxyBuildPlanImpl.create(CorrectProxySubject.class, "proxy_" + counter.getAndIncrement(), cl); proxy = builder.createProxyClass(plan).createProxy(subject); }
@Test public void testProxyCaching() { linker.createProxy(CorrectProxySubject.class, new CorrectProxySubject(), fakeRootLoader); linker.createProxy(CorrectProxySubject.class, new CorrectProxySubject(), fakeRootLoader); verify(proxyBuilder, times(1)).createProxyClass(any(IProxyBuildPlan.class)); }