From 695460bdb307dfe6fcbfea5a982590cc3bbe1bb1 Mon Sep 17 00:00:00 2001 From: Megrez Lu Date: Wed, 21 May 2025 19:02:35 +0800 Subject: [PATCH 1/9] add test cases --- .../apm/agent/bytebuddy/biz/ChildBar.java | 7 +++ .../apm/agent/bytebuddy/biz/ParentBar.java | 7 +++ .../cases/AbstractInterceptTest.java | 24 ++++++-- .../bytebuddy/cases/ReTransform4Test.java | 61 +++++++++++++++++++ 4 files changed, 95 insertions(+), 4 deletions(-) create mode 100644 apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/ChildBar.java create mode 100644 apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/ParentBar.java create mode 100644 apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/ReTransform4Test.java diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/ChildBar.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/ChildBar.java new file mode 100644 index 0000000000..91f3cd3ef1 --- /dev/null +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/ChildBar.java @@ -0,0 +1,7 @@ +package org.apache.skywalking.apm.agent.bytebuddy.biz; + +public class ChildBar extends ParentBar { + public String sayHelloChild() { + return "Joe"; + } +} diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/ParentBar.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/ParentBar.java new file mode 100644 index 0000000000..d3bc44dfe1 --- /dev/null +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/ParentBar.java @@ -0,0 +1,7 @@ +package org.apache.skywalking.apm.agent.bytebuddy.biz; + +public class ParentBar { + public String sayHelloParent() { + return "Joe"; + } +} diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/AbstractInterceptTest.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/AbstractInterceptTest.java index ba9cf4d372..9093d8c98a 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/AbstractInterceptTest.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/AbstractInterceptTest.java @@ -38,6 +38,7 @@ import org.apache.skywalking.apm.agent.bytebuddy.SWAuxiliaryTypeNamingStrategy; import org.apache.skywalking.apm.agent.bytebuddy.SWClassFileLocator; import org.apache.skywalking.apm.agent.bytebuddy.biz.BizFoo; +import org.apache.skywalking.apm.agent.bytebuddy.biz.ChildBar; import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; import org.junit.Assert; import org.junit.BeforeClass; @@ -63,6 +64,8 @@ public class AbstractInterceptTest { public static final String BIZ_FOO_CLASS_NAME = "org.apache.skywalking.apm.agent.bytebuddy.biz.BizFoo"; public static final String PROJECT_SERVICE_CLASS_NAME = "org.apache.skywalking.apm.agent.bytebuddy.biz.ProjectService"; public static final String DOC_SERVICE_CLASS_NAME = "org.apache.skywalking.apm.agent.bytebuddy.biz.DocService"; + public static final String PARENT_BAR_CLASS_NAME = "org.apache.skywalking.apm.agent.bytebuddy.biz.ParentBar"; + public static final String CHILD_BAR_CLASS_NAME = "org.apache.skywalking.apm.agent.bytebuddy.biz.ChildBar"; public static final String SAY_HELLO_METHOD = "sayHello"; public static final int BASE_INT_VALUE = 100; public static final String CONSTRUCTOR_INTERCEPTOR_CLASS = "constructorInterceptorClass"; @@ -85,6 +88,20 @@ protected void failed(Throwable e, Description description) { } }; + protected static void callBar(int round) { + Log.info("-------------"); + Log.info("callChildBar: " + round); + // load target class + String strResultChild = new ChildBar().sayHelloChild(); + Log.info("result: " + strResultChild); + + String strResultParent = new ChildBar().sayHelloParent(); + Log.info("result: " + strResultParent); + + Assert.assertEquals("String value is unexpected", "John", strResultChild); + Assert.assertEquals("String value is unexpected", "John", strResultParent); + } + protected static void callBizFoo(int round) { Log.info("-------------"); Log.info("callBizFoo: " + round); @@ -115,7 +132,7 @@ protected static void checkConstructorInterceptor(String className, int round) { protected static void checkInterface(Class testClass, Class interfaceCls) { Assert.assertTrue("Check interface failure, the test class: " + testClass + " does not implement the expected interface: " + interfaceCls, - EnhancedInstance.class.isAssignableFrom(BizFoo.class)); + EnhancedInstance.class.isAssignableFrom(testClass)); } protected static void checkErrors() { @@ -139,8 +156,7 @@ protected void installMethodInterceptorWithMethodDelegation(String className, St return builder .method(ElementMatchers.nameContainsIgnoreCase(methodName)) .intercept(MethodDelegation.withDefaultConfiguration() - .to(new InstMethodsInter(interceptorClassName, classLoader), fieldName)) - ; + .to(new InstMethodsInter(interceptorClassName, classLoader), fieldName)); } ) .with(getListener(interceptorClassName)) @@ -223,7 +239,7 @@ protected void installTraceClassTransformer(String msg) { ClassFileTransformer classFileTransformer = new ClassFileTransformer() { @Override public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { - if (className.endsWith("BizFoo") || className.endsWith("ProjectService") || className.endsWith("DocService")) { + if (className.endsWith("BizFoo") || className.endsWith("ProjectService") || className.endsWith("DocService") || className.endsWith("ChildBar") || className.endsWith("ParentBar")) { Log.error(msg + className); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ClassReader cr = new ClassReader(classfileBuffer); diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/ReTransform4Test.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/ReTransform4Test.java new file mode 100644 index 0000000000..7570e2c94e --- /dev/null +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/ReTransform4Test.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.agent.bytebuddy.cases; + +import net.bytebuddy.agent.ByteBuddyAgent; +import org.apache.skywalking.apm.agent.bytebuddy.biz.ChildBar; +import org.apache.skywalking.apm.agent.bytebuddy.biz.ParentBar; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.junit.Test; + +import java.lang.instrument.Instrumentation; + +public class ReTransform4Test extends AbstractReTransformTest { + + @Test + public void testEnhancedInstanceForMultiShotRetransform() throws Exception { + Instrumentation instrumentation = ByteBuddyAgent.install(); + + // install transformer + installMethodInterceptor(PARENT_BAR_CLASS_NAME, "sayHelloParent", 1); + installMethodInterceptor(CHILD_BAR_CLASS_NAME, "sayHelloChild", 1); + // implement EnhancedInstance + installInterface(PARENT_BAR_CLASS_NAME); + installInterface(CHILD_BAR_CLASS_NAME); + + callBar(1); + + // check interceptors + checkInterface(ParentBar.class, EnhancedInstance.class); + checkInterface(ChildBar.class, EnhancedInstance.class); + checkErrors(); + + installTraceClassTransformer("Trace class: "); + + // do retransform + reTransform(instrumentation, ChildBar.class); + + // check interceptors + checkInterface(ParentBar.class, EnhancedInstance.class); + checkInterface(ChildBar.class, EnhancedInstance.class); + checkErrors(); + } + +} + From 067ef99b2cd640e625efcedf077c4d06cd8e38b3 Mon Sep 17 00:00:00 2001 From: Megrez Lu Date: Thu, 22 May 2025 09:50:02 +0800 Subject: [PATCH 2/9] fix issue by wrapping it into SWTypeDescriptionWrapper --- .../agent/builder/SWDescriptionStrategy.java | 11 ++++++++++- pom.xml | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWDescriptionStrategy.java b/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWDescriptionStrategy.java index 62e8a0606c..c88353ca42 100644 --- a/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWDescriptionStrategy.java +++ b/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWDescriptionStrategy.java @@ -145,6 +145,8 @@ static class SWTypeDescriptionWrapper extends TypeDescription.AbstractBase imple private TypeDescription delegate; + private Generic superClass; + public SWTypeDescriptionWrapper(TypeDescription delegate, String nameTrait, ClassLoader classLoader, String typeName) { this.delegate = delegate; this.nameTrait = nameTrait; @@ -325,7 +327,14 @@ public AnnotationList getDeclaredAnnotations() { @Override public Generic getSuperClass() { - return delegate.getSuperClass(); + if (this.superClass == null) { + Generic delegateSuperClass = delegate.getSuperClass(); + if (delegateSuperClass == null) { + return delegateSuperClass; + } + this.superClass = new SWTypeDescriptionWrapper(delegateSuperClass.asErasure(), this.nameTrait, this.classLoader, delegateSuperClass.getTypeName()).asGenericType(); + } + return this.superClass; } @Override diff --git a/pom.xml b/pom.xml index 1e546b07f4..42adb97927 100755 --- a/pom.xml +++ b/pom.xml @@ -86,7 +86,7 @@ 1.18.30 - 1.14.9 + 1.17.5 1.68.1 4.1.115.Final 2.8.9 From cb1bd25fe5c81915dd75c917257c64d141262b73 Mon Sep 17 00:00:00 2001 From: Megrez Lu Date: Thu, 22 May 2025 09:56:09 +0800 Subject: [PATCH 3/9] revert byte-buddy version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 42adb97927..1e546b07f4 100755 --- a/pom.xml +++ b/pom.xml @@ -86,7 +86,7 @@ 1.18.30 - 1.17.5 + 1.14.9 1.68.1 4.1.115.Final 2.8.9 From fffd7a4abd24ed5a0d8ba5d677a25e126578bffe Mon Sep 17 00:00:00 2001 From: Megrez Lu Date: Thu, 22 May 2025 10:00:51 +0800 Subject: [PATCH 4/9] fix license --- .../apm/agent/bytebuddy/biz/ChildBar.java | 18 ++++++++++++++++++ .../apm/agent/bytebuddy/biz/ParentBar.java | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/ChildBar.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/ChildBar.java index 91f3cd3ef1..ce19ee5e49 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/ChildBar.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/ChildBar.java @@ -1,3 +1,21 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + package org.apache.skywalking.apm.agent.bytebuddy.biz; public class ChildBar extends ParentBar { diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/ParentBar.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/ParentBar.java index d3bc44dfe1..6638ba47bc 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/ParentBar.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/ParentBar.java @@ -1,3 +1,21 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + package org.apache.skywalking.apm.agent.bytebuddy.biz; public class ParentBar { From d241ed4bbce2c8f375411fba0fcdf7fd5b49dc6e Mon Sep 17 00:00:00 2001 From: Megrez Lu Date: Thu, 22 May 2025 11:52:19 +0800 Subject: [PATCH 5/9] fix classloader --- .../java/net/bytebuddy/agent/builder/SWDescriptionStrategy.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWDescriptionStrategy.java b/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWDescriptionStrategy.java index c88353ca42..2e6196afb6 100644 --- a/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWDescriptionStrategy.java +++ b/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWDescriptionStrategy.java @@ -332,7 +332,7 @@ public Generic getSuperClass() { if (delegateSuperClass == null) { return delegateSuperClass; } - this.superClass = new SWTypeDescriptionWrapper(delegateSuperClass.asErasure(), this.nameTrait, this.classLoader, delegateSuperClass.getTypeName()).asGenericType(); + this.superClass = new SWTypeDescriptionWrapper(delegateSuperClass.asErasure(), this.nameTrait, delegateSuperClass.getClass().getClassLoader(), delegateSuperClass.getTypeName()).asGenericType(); } return this.superClass; } From 072e89885c35c6775b8a66629b2c26fe29e47571 Mon Sep 17 00:00:00 2001 From: Megrez Lu Date: Thu, 22 May 2025 15:05:27 +0800 Subject: [PATCH 6/9] fix className --- .../net/bytebuddy/agent/builder/SWDescriptionStrategy.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWDescriptionStrategy.java b/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWDescriptionStrategy.java index 2e6196afb6..55ef0b2aaa 100644 --- a/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWDescriptionStrategy.java +++ b/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWDescriptionStrategy.java @@ -330,9 +330,9 @@ public Generic getSuperClass() { if (this.superClass == null) { Generic delegateSuperClass = delegate.getSuperClass(); if (delegateSuperClass == null) { - return delegateSuperClass; + return null; } - this.superClass = new SWTypeDescriptionWrapper(delegateSuperClass.asErasure(), this.nameTrait, delegateSuperClass.getClass().getClassLoader(), delegateSuperClass.getTypeName()).asGenericType(); + this.superClass = new SWTypeDescriptionWrapper(delegateSuperClass.asErasure(), this.nameTrait, delegateSuperClass.getClass().getClassLoader(), delegateSuperClass.getClass().getName()).asGenericType(); } return this.superClass; } From 69d8fb8326492c3992f332adcd2cb988a13a65fc Mon Sep 17 00:00:00 2001 From: Megrez Lu Date: Thu, 22 May 2025 17:28:52 +0800 Subject: [PATCH 7/9] add a wrapper --- .../agent/builder/SWDescriptionStrategy.java | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWDescriptionStrategy.java b/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWDescriptionStrategy.java index 55ef0b2aaa..84d614e328 100644 --- a/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWDescriptionStrategy.java +++ b/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWDescriptionStrategy.java @@ -332,7 +332,10 @@ public Generic getSuperClass() { if (delegateSuperClass == null) { return null; } - this.superClass = new SWTypeDescriptionWrapper(delegateSuperClass.asErasure(), this.nameTrait, delegateSuperClass.getClass().getClassLoader(), delegateSuperClass.getClass().getName()).asGenericType(); + this.superClass = new ForLoadedSuperClassWrapper( + this.delegate.getClass(), + new SWTypeDescriptionWrapper(delegateSuperClass.asErasure(), this.nameTrait, delegateSuperClass.getClass().getClassLoader(), delegateSuperClass.getClass().getName()) + ); } return this.superClass; } @@ -363,6 +366,30 @@ public int getModifiers() { } } + static class ForLoadedSuperClassWrapper extends TypeDescription.Generic.LazyProjection.ForLoadedSuperClass { + private final TypeDescription delegation; + + /** + * Creates a new lazy projection of a type's super class. + * + * @param type The type of which the super class is represented. + */ + protected ForLoadedSuperClassWrapper(Class type, TypeDescription delegation) { + super(type); + this.delegation = delegation; + } + + @Override + protected TypeDescription.Generic resolve() { + return this.delegation.asGenericType(); + } + + @Override + public TypeDescription asErasure() { + return this.delegation; + } + } + static class TypeCache { private String typeName; private Set methodCodes; From 8c244fdd294495c0e68f5d7fcaceae823d7426a0 Mon Sep 17 00:00:00 2001 From: Megrez Lu Date: Thu, 22 May 2025 18:27:07 +0800 Subject: [PATCH 8/9] remove class access --- .../net/bytebuddy/agent/builder/SWDescriptionStrategy.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWDescriptionStrategy.java b/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWDescriptionStrategy.java index 84d614e328..a17cdfc568 100644 --- a/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWDescriptionStrategy.java +++ b/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWDescriptionStrategy.java @@ -333,8 +333,8 @@ public Generic getSuperClass() { return null; } this.superClass = new ForLoadedSuperClassWrapper( - this.delegate.getClass(), - new SWTypeDescriptionWrapper(delegateSuperClass.asErasure(), this.nameTrait, delegateSuperClass.getClass().getClassLoader(), delegateSuperClass.getClass().getName()) + null, + new SWTypeDescriptionWrapper(delegateSuperClass.asErasure(), this.nameTrait, null, delegateSuperClass.asErasure().getName()) ); } return this.superClass; From c99c5930c2973f8f86017c8436cff88d7781a8ae Mon Sep 17 00:00:00 2001 From: Megrez Lu Date: Thu, 22 May 2025 19:00:09 +0800 Subject: [PATCH 9/9] override getDeclaredAnnotations --- .../agent/builder/SWDescriptionStrategy.java | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWDescriptionStrategy.java b/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWDescriptionStrategy.java index a17cdfc568..754ea9f12b 100644 --- a/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWDescriptionStrategy.java +++ b/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWDescriptionStrategy.java @@ -333,8 +333,8 @@ public Generic getSuperClass() { return null; } this.superClass = new ForLoadedSuperClassWrapper( - null, - new SWTypeDescriptionWrapper(delegateSuperClass.asErasure(), this.nameTrait, null, delegateSuperClass.asErasure().getName()) + new SWTypeDescriptionWrapper(delegateSuperClass.asErasure(), this.nameTrait, null, delegateSuperClass.asErasure().getName()), + delegateSuperClass ); } return this.superClass; @@ -368,15 +368,12 @@ public int getModifiers() { static class ForLoadedSuperClassWrapper extends TypeDescription.Generic.LazyProjection.ForLoadedSuperClass { private final TypeDescription delegation; + private final TypeDescription.Generic superGeneric; - /** - * Creates a new lazy projection of a type's super class. - * - * @param type The type of which the super class is represented. - */ - protected ForLoadedSuperClassWrapper(Class type, TypeDescription delegation) { - super(type); + protected ForLoadedSuperClassWrapper(TypeDescription delegation, TypeDescription.Generic superGeneric) { + super(null); // HACK: a trick here since type is not used anywhere in the wrapper this.delegation = delegation; + this.superGeneric = superGeneric; } @Override @@ -388,6 +385,11 @@ protected TypeDescription.Generic resolve() { public TypeDescription asErasure() { return this.delegation; } + + @Override + public AnnotationList getDeclaredAnnotations() { + return superGeneric.getDeclaredAnnotations(); + } } static class TypeCache {