Skip to content

Commit f4b0c0c

Browse files
wangwang
authored andcommitted
fix parent class enhance issue
1 parent 9e80a4c commit f4b0c0c

6 files changed

Lines changed: 146 additions & 2 deletions

File tree

apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/ClassEnhancePluginDefine.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
package org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance;
2020

2121
import net.bytebuddy.description.method.MethodDescription;
22+
import net.bytebuddy.description.modifier.Visibility;
2223
import net.bytebuddy.description.type.TypeDescription;
2324
import net.bytebuddy.dynamic.DynamicType;
2425
import net.bytebuddy.implementation.FieldAccessor;
@@ -102,6 +103,9 @@ protected DynamicType.Builder<?> enhanceInstance(TypeDescription typeDescription
102103
newClassBuilder = newClassBuilder.defineField(
103104
CONTEXT_ATTR_NAME, Object.class, ACC_PRIVATE | ACC_VOLATILE)
104105
.implement(EnhancedInstance.class)
106+
.defineMethod("getSkyWalkingDynamicField", Object.class, Visibility.PUBLIC)
107+
.intercept(FieldAccessor.ofField(CONTEXT_ATTR_NAME))
108+
.defineMethod("setSkyWalkingDynamicField", void.class, Visibility.PUBLIC).withParameters(Object.class)
105109
.intercept(FieldAccessor.ofField(CONTEXT_ATTR_NAME));
106110
context.extendObjectCompleted();
107111
}

apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/v2/ClassEnhancePluginDefineV2.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.v2;
1919

2020
import net.bytebuddy.description.method.MethodDescription;
21+
import net.bytebuddy.description.modifier.Visibility;
2122
import net.bytebuddy.description.type.TypeDescription;
2223
import net.bytebuddy.dynamic.DynamicType;
2324
import net.bytebuddy.implementation.FieldAccessor;
@@ -135,6 +136,9 @@ protected DynamicType.Builder<?> enhanceInstance(TypeDescription typeDescription
135136
newClassBuilder = newClassBuilder.defineField(
136137
CONTEXT_ATTR_NAME, Object.class, ACC_PRIVATE | ACC_VOLATILE)
137138
.implement(EnhancedInstance.class)
139+
.defineMethod("getSkyWalkingDynamicField", Object.class, Visibility.PUBLIC)
140+
.intercept(FieldAccessor.ofField(CONTEXT_ATTR_NAME))
141+
.defineMethod("setSkyWalkingDynamicField", void.class, Visibility.PUBLIC).withParameters(Object.class)
138142
.intercept(FieldAccessor.ofField(CONTEXT_ATTR_NAME));
139143
context.extendObjectCompleted();
140144
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
19+
package org.apache.skywalking.apm.agent.bytebuddy.biz;
20+
21+
public class ChildBar extends ParentBar {
22+
23+
public String sayHelloChild() {
24+
return "Joe";
25+
}
26+
27+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
19+
package org.apache.skywalking.apm.agent.bytebuddy.biz;
20+
21+
public class ParentBar {
22+
23+
public String sayHelloParent() {
24+
return "Joe";
25+
}
26+
}

apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/AbstractInterceptTest.java

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import net.bytebuddy.agent.builder.SWAgentBuilderDefault;
2525
import net.bytebuddy.agent.builder.SWDescriptionStrategy;
2626
import net.bytebuddy.agent.builder.SWNativeMethodStrategy;
27+
import net.bytebuddy.description.modifier.Visibility;
2728
import net.bytebuddy.implementation.FieldAccessor;
2829
import net.bytebuddy.implementation.MethodDelegation;
2930
import net.bytebuddy.implementation.SWImplementationContextFactory;
@@ -38,6 +39,7 @@
3839
import org.apache.skywalking.apm.agent.bytebuddy.SWAuxiliaryTypeNamingStrategy;
3940
import org.apache.skywalking.apm.agent.bytebuddy.SWClassFileLocator;
4041
import org.apache.skywalking.apm.agent.bytebuddy.biz.BizFoo;
42+
import org.apache.skywalking.apm.agent.bytebuddy.biz.ChildBar;
4143
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
4244
import org.junit.Assert;
4345
import org.junit.BeforeClass;
@@ -63,6 +65,8 @@ public class AbstractInterceptTest {
6365
public static final String BIZ_FOO_CLASS_NAME = "org.apache.skywalking.apm.agent.bytebuddy.biz.BizFoo";
6466
public static final String PROJECT_SERVICE_CLASS_NAME = "org.apache.skywalking.apm.agent.bytebuddy.biz.ProjectService";
6567
public static final String DOC_SERVICE_CLASS_NAME = "org.apache.skywalking.apm.agent.bytebuddy.biz.DocService";
68+
public static final String PARENT_BAR_CLASS_NAME = "org.apache.skywalking.apm.agent.bytebuddy.biz.ParentBar";
69+
public static final String CHILD_BAR_CLASS_NAME = "org.apache.skywalking.apm.agent.bytebuddy.biz.ChildBar";
6670
public static final String SAY_HELLO_METHOD = "sayHello";
6771
public static final int BASE_INT_VALUE = 100;
6872
public static final String CONSTRUCTOR_INTERCEPTOR_CLASS = "constructorInterceptorClass";
@@ -85,6 +89,20 @@ protected void failed(Throwable e, Description description) {
8589
}
8690
};
8791

92+
protected static void callBar(int round) {
93+
Log.info("-------------");
94+
Log.info("callChildBar: " + round);
95+
// load target class
96+
String strResultChild = new ChildBar().sayHelloChild();
97+
Log.info("result: " + strResultChild);
98+
99+
String strResultParent = new ChildBar().sayHelloParent();
100+
Log.info("result: " + strResultParent);
101+
102+
Assert.assertEquals("String value is unexpected", "John", strResultChild);
103+
Assert.assertEquals("String value is unexpected", "John", strResultParent);
104+
}
105+
88106
protected static void callBizFoo(int round) {
89107
Log.info("-------------");
90108
Log.info("callBizFoo: " + round);
@@ -115,7 +133,7 @@ protected static void checkConstructorInterceptor(String className, int round) {
115133

116134
protected static void checkInterface(Class testClass, Class interfaceCls) {
117135
Assert.assertTrue("Check interface failure, the test class: " + testClass + " does not implement the expected interface: " + interfaceCls,
118-
EnhancedInstance.class.isAssignableFrom(BizFoo.class));
136+
EnhancedInstance.class.isAssignableFrom(testClass));
119137
}
120138

121139
protected static void checkErrors() {
@@ -195,6 +213,9 @@ protected void installInterface(String className) {
195213
builder = builder.defineField(
196214
CONTEXT_ATTR_NAME, Object.class, ACC_PRIVATE | ACC_VOLATILE)
197215
.implement(EnhancedInstance.class)
216+
.defineMethod("getSkyWalkingDynamicField", Object.class, Visibility.PUBLIC)
217+
.intercept(FieldAccessor.ofField(CONTEXT_ATTR_NAME))
218+
.defineMethod("setSkyWalkingDynamicField", void.class, Visibility.PUBLIC).withParameters(Object.class)
198219
.intercept(FieldAccessor.ofField(CONTEXT_ATTR_NAME));
199220
}
200221
return builder;
@@ -223,7 +244,7 @@ protected void installTraceClassTransformer(String msg) {
223244
ClassFileTransformer classFileTransformer = new ClassFileTransformer() {
224245
@Override
225246
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
226-
if (className.endsWith("BizFoo") || className.endsWith("ProjectService") || className.endsWith("DocService")) {
247+
if (className.endsWith("BizFoo") || className.endsWith("ProjectService") || className.endsWith("DocService") || className.endsWith("ChildBar") || className.endsWith("ParentBar")) {
227248
Log.error(msg + className);
228249
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
229250
ClassReader cr = new ClassReader(classfileBuffer);
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
19+
package org.apache.skywalking.apm.agent.bytebuddy.cases;
20+
21+
import net.bytebuddy.agent.ByteBuddyAgent;
22+
import org.apache.skywalking.apm.agent.bytebuddy.biz.ChildBar;
23+
import org.apache.skywalking.apm.agent.bytebuddy.biz.ParentBar;
24+
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
25+
import org.junit.Test;
26+
27+
import java.lang.instrument.Instrumentation;
28+
29+
public class ReTransform4Test extends AbstractReTransformTest {
30+
31+
@Test
32+
public void testInterceptConstructor() throws Exception {
33+
Instrumentation instrumentation = ByteBuddyAgent.install();
34+
35+
// install transformer
36+
installMethodInterceptor(PARENT_BAR_CLASS_NAME, "sayHelloParent", 1);
37+
installMethodInterceptor(CHILD_BAR_CLASS_NAME, "sayHelloChild", 1);
38+
// implement EnhancedInstance
39+
installInterface(PARENT_BAR_CLASS_NAME);
40+
installInterface(CHILD_BAR_CLASS_NAME);
41+
42+
// call target class
43+
callBar(1);
44+
45+
// check interceptors
46+
checkInterface(ParentBar.class, EnhancedInstance.class);
47+
checkInterface(ChildBar.class, EnhancedInstance.class);
48+
checkErrors();
49+
50+
installTraceClassTransformer("Trace class: ");
51+
52+
// do retransform
53+
reTransform(instrumentation, ChildBar.class);
54+
55+
// check interceptors
56+
checkInterface(ParentBar.class, EnhancedInstance.class);
57+
checkInterface(ChildBar.class, EnhancedInstance.class);
58+
checkErrors();
59+
}
60+
61+
}
62+

0 commit comments

Comments
 (0)