From 0554e12c5a02dd26b827bc190359e025a2a0a425 Mon Sep 17 00:00:00 2001 From: Gong Dewei Date: Fri, 23 Jun 2023 16:38:59 +0800 Subject: [PATCH 01/24] Add bytebuddy-patch to support retransform classes with other agents --- .../enhance/ClassEnhancePluginDefine.java | 27 +- .../enhance/DelegateNamingResolver.java | 55 ++++ .../v2/ClassEnhancePluginDefineV2.java | 29 +- .../MethodInheritanceAnnotationMatcher.java | 5 + .../plugin/match/ProtectiveShieldMatcher.java | 5 + apm-sniffer/apm-agent/pom.xml | 5 + .../skywalking/apm/agent/SkyWalkingAgent.java | 42 ++- apm-sniffer/bytebuddy-patch/pom.xml | 90 +++++++ .../agent/builder/SWAgentBuilderDefault.java | 88 +++++++ .../agent/builder/SWNativeMethodStrategy.java | 44 ++++ .../SWImplementationContextFactory.java | 59 +++++ .../agent/bytebuddy/SWAsmVisitorWrapper.java | 120 +++++++++ .../SWAuxiliaryTypeNamingStrategy.java | 41 +++ .../agent/bytebuddy/SWClassFileLocator.java | 178 +++++++++++++ .../SWExtractionClassFileTransformer.java | 76 ++++++ .../bytebuddy/SWMethodNameTransformer.java | 47 ++++ .../agent/bytebuddy/ConstructorAdvice.java | 33 +++ .../apm/agent/bytebuddy/ConstructorInter.java | 54 ++++ .../apm/agent/bytebuddy/EnhanceHelper.java | 76 ++++++ .../apm/agent/bytebuddy/InstMethodAdvice.java | 42 +++ .../apm/agent/bytebuddy/InstMethodsInter.java | 63 +++++ .../skywalking/apm/agent/bytebuddy/Log.java | 42 +++ .../apm/agent/bytebuddy/biz/BizFoo.java | 44 ++++ .../apm/agent/bytebuddy/biz/DocDO.java | 43 +++ .../apm/agent/bytebuddy/biz/DocService.java | 39 +++ .../apm/agent/bytebuddy/biz/ProjectDO.java | 45 ++++ .../agent/bytebuddy/biz/ProjectService.java | 39 +++ .../case1/AbstractInterceptTest.java | 247 ++++++++++++++++++ .../case1/AbstractRetransformTest.java | 56 ++++ .../agent/bytebuddy/case1/InterceptTest1.java | 47 ++++ .../agent/bytebuddy/case1/InterceptTest2.java | 50 ++++ .../agent/bytebuddy/case1/InterceptTest3.java | 52 ++++ .../agent/bytebuddy/case1/InterceptTest4.java | 55 ++++ .../agent/bytebuddy/case1/InterceptTest5.java | 52 ++++ .../agent/bytebuddy/case1/InterceptTest6.java | 53 ++++ .../case1/MultipleInterceptorTest.java | 106 ++++++++ .../bytebuddy/case1/RetransformTest1.java | 80 ++++++ .../bytebuddy/case1/RetransformTest2.java | 87 ++++++ apm-sniffer/pom.xml | 1 + pom.xml | 11 +- 40 files changed, 2296 insertions(+), 32 deletions(-) create mode 100644 apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java create mode 100644 apm-sniffer/bytebuddy-patch/pom.xml create mode 100644 apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWAgentBuilderDefault.java create mode 100644 apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWNativeMethodStrategy.java create mode 100644 apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/implementation/SWImplementationContextFactory.java create mode 100644 apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWAsmVisitorWrapper.java create mode 100644 apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWAuxiliaryTypeNamingStrategy.java create mode 100644 apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWClassFileLocator.java create mode 100644 apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWExtractionClassFileTransformer.java create mode 100644 apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWMethodNameTransformer.java create mode 100644 apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/ConstructorAdvice.java create mode 100644 apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/ConstructorInter.java create mode 100644 apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/EnhanceHelper.java create mode 100644 apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/InstMethodAdvice.java create mode 100644 apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/InstMethodsInter.java create mode 100644 apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/Log.java create mode 100644 apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/BizFoo.java create mode 100644 apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/DocDO.java create mode 100644 apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/DocService.java create mode 100644 apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/ProjectDO.java create mode 100644 apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/ProjectService.java create mode 100644 apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/AbstractInterceptTest.java create mode 100644 apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/AbstractRetransformTest.java create mode 100644 apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest1.java create mode 100644 apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest2.java create mode 100644 apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest3.java create mode 100644 apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest4.java create mode 100644 apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest5.java create mode 100644 apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest6.java create mode 100644 apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/MultipleInterceptorTest.java create mode 100644 apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/RetransformTest1.java create mode 100644 apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/RetransformTest2.java diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/ClassEnhancePluginDefine.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/ClassEnhancePluginDefine.java index 3c545d80f0..8f4ca771a0 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/ClassEnhancePluginDefine.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/ClassEnhancePluginDefine.java @@ -55,6 +55,9 @@ */ public abstract class ClassEnhancePluginDefine extends AbstractClassEnhancePluginDefine { private static final ILog LOGGER = LogManager.getLogger(ClassEnhancePluginDefine.class); + private ConstructorInterceptPoint[] constructorInterceptPoints; + private InstanceMethodsInterceptPoint[] instanceMethodsInterceptPoints; + private StaticMethodsInterceptPoint[] staticMethodsInterceptPoints; /** * Enhance a class to intercept constructors and class instance methods. @@ -67,8 +70,12 @@ public abstract class ClassEnhancePluginDefine extends AbstractClassEnhancePlugi protected DynamicType.Builder enhanceInstance(TypeDescription typeDescription, DynamicType.Builder newClassBuilder, ClassLoader classLoader, EnhanceContext context) throws PluginException { - ConstructorInterceptPoint[] constructorInterceptPoints = getConstructorsInterceptPoints(); - InstanceMethodsInterceptPoint[] instanceMethodsInterceptPoints = getInstanceMethodsInterceptPoints(); + if (constructorInterceptPoints == null) { + constructorInterceptPoints = getConstructorsInterceptPoints(); + } + if (instanceMethodsInterceptPoints == null) { + instanceMethodsInterceptPoints = getInstanceMethodsInterceptPoints(); + } String enhanceOriginClassName = typeDescription.getTypeName(); boolean existedConstructorInterceptPoint = false; if (constructorInterceptPoints != null && constructorInterceptPoints.length > 0) { @@ -78,6 +85,7 @@ protected DynamicType.Builder enhanceInstance(TypeDescription typeDescription if (instanceMethodsInterceptPoints != null && instanceMethodsInterceptPoints.length > 0) { existedMethodsInterceptPoints = true; } + DelegateNamingResolver delegateNamingResolver = DelegateNamingResolver.get(typeDescription.getTypeName(), this); /** * nothing need to be enhanced in class instance, maybe need enhance static methods. @@ -121,7 +129,7 @@ protected DynamicType.Builder enhanceInstance(TypeDescription typeDescription newClassBuilder = newClassBuilder.constructor(constructorInterceptPoint.getConstructorMatcher()) .intercept(SuperMethodCall.INSTANCE.andThen(MethodDelegation.withDefaultConfiguration() .to(new ConstructorInter(constructorInterceptPoint - .getConstructorInterceptor(), classLoader)))); + .getConstructorInterceptor(), classLoader), delegateNamingResolver.resolve(constructorInterceptPoint)))); } } } @@ -149,7 +157,7 @@ protected DynamicType.Builder enhanceInstance(TypeDescription typeDescription newClassBuilder = newClassBuilder.method(junction) .intercept(MethodDelegation.withDefaultConfiguration() .withBinders(Morph.Binder.install(OverrideCallable.class)) - .to(new InstMethodsInterWithOverrideArgs(interceptor, classLoader))); + .to(new InstMethodsInterWithOverrideArgs(interceptor, classLoader), delegateNamingResolver.resolve(instanceMethodsInterceptPoint))); } } else { if (isBootstrapInstrumentation()) { @@ -159,7 +167,7 @@ protected DynamicType.Builder enhanceInstance(TypeDescription typeDescription } else { newClassBuilder = newClassBuilder.method(junction) .intercept(MethodDelegation.withDefaultConfiguration() - .to(new InstMethodsInter(interceptor, classLoader))); + .to(new InstMethodsInter(interceptor, classLoader), delegateNamingResolver.resolve(instanceMethodsInterceptPoint))); } } } @@ -178,11 +186,14 @@ protected DynamicType.Builder enhanceInstance(TypeDescription typeDescription @Override protected DynamicType.Builder enhanceClass(TypeDescription typeDescription, DynamicType.Builder newClassBuilder, ClassLoader classLoader) throws PluginException { - StaticMethodsInterceptPoint[] staticMethodsInterceptPoints = getStaticMethodsInterceptPoints(); String enhanceOriginClassName = typeDescription.getTypeName(); + if (staticMethodsInterceptPoints == null) { + staticMethodsInterceptPoints = getStaticMethodsInterceptPoints(); + } if (staticMethodsInterceptPoints == null || staticMethodsInterceptPoints.length == 0) { return newClassBuilder; } + DelegateNamingResolver delegateNamingResolver = DelegateNamingResolver.get(typeDescription.getTypeName(), this); for (StaticMethodsInterceptPoint staticMethodsInterceptPoint : staticMethodsInterceptPoints) { String interceptor = staticMethodsInterceptPoint.getMethodsInterceptor(); @@ -200,7 +211,7 @@ protected DynamicType.Builder enhanceClass(TypeDescription typeDescription, D newClassBuilder = newClassBuilder.method(isStatic().and(staticMethodsInterceptPoint.getMethodsMatcher())) .intercept(MethodDelegation.withDefaultConfiguration() .withBinders(Morph.Binder.install(OverrideCallable.class)) - .to(new StaticMethodsInterWithOverrideArgs(interceptor))); + .to(new StaticMethodsInterWithOverrideArgs(interceptor), delegateNamingResolver.resolve(staticMethodsInterceptPoint))); } } else { if (isBootstrapInstrumentation()) { @@ -210,7 +221,7 @@ protected DynamicType.Builder enhanceClass(TypeDescription typeDescription, D } else { newClassBuilder = newClassBuilder.method(isStatic().and(staticMethodsInterceptPoint.getMethodsMatcher())) .intercept(MethodDelegation.withDefaultConfiguration() - .to(new StaticMethodsInter(interceptor))); + .to(new StaticMethodsInter(interceptor), delegateNamingResolver.resolve(staticMethodsInterceptPoint))); } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java new file mode 100644 index 0000000000..35fc9dece3 --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java @@ -0,0 +1,55 @@ +/* + * 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.core.plugin.interceptor.enhance; + +import net.bytebuddy.utility.RandomString; +import org.apache.skywalking.apm.agent.core.plugin.AbstractClassEnhancePluginDefine; + +import java.util.Objects; + +/** + * Generate fixed delegate field name for MethodDelegation + */ +public class DelegateNamingResolver { + private static final String PREFIX = "delegate$"; + private static String NAME_TRAIT = "sw$"; + private final String className; + private final int identifier; + private final String fieldNamePrefix; + + public static void setNameTrait(String nameTrait) { + DelegateNamingResolver.NAME_TRAIT = nameTrait; + } + + public DelegateNamingResolver(String className, int identifier) { + this.className = className; + this.identifier = identifier; + this.fieldNamePrefix = NAME_TRAIT + PREFIX + RandomString.hashOf(className.hashCode()) + "$" + RandomString.hashOf(identifier) + "$"; + } + + public String resolve(Object interceptPoint) { + Objects.requireNonNull(interceptPoint, "interceptPoint cannot be null"); + return fieldNamePrefix + RandomString.hashOf(interceptPoint.hashCode()); + } + + public static DelegateNamingResolver get(String className, AbstractClassEnhancePluginDefine pluginDefine) { + return new DelegateNamingResolver(className, pluginDefine.hashCode()); + } + +} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/v2/ClassEnhancePluginDefineV2.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/v2/ClassEnhancePluginDefineV2.java index 733d32f184..bbae79d0a5 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/v2/ClassEnhancePluginDefineV2.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/v2/ClassEnhancePluginDefineV2.java @@ -35,6 +35,7 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; import org.apache.skywalking.apm.agent.core.plugin.interceptor.StaticMethodsInterceptPoint; import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ConstructorInter; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.DelegateNamingResolver; import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.OverrideCallable; import org.apache.skywalking.apm.agent.core.plugin.interceptor.v2.ConstructorInterceptV2Point; @@ -56,15 +57,22 @@ */ public abstract class ClassEnhancePluginDefineV2 extends AbstractClassEnhancePluginDefine { + private ConstructorInterceptPoint[] constructorInterceptPoints; + private InstanceMethodsInterceptV2Point[] instanceMethodsInterceptV2Points; + private StaticMethodsInterceptV2Point[] staticMethodsInterceptV2Points; + @Override protected DynamicType.Builder enhanceClass(TypeDescription typeDescription, DynamicType.Builder newClassBuilder, ClassLoader classLoader) throws PluginException { - StaticMethodsInterceptV2Point[] staticMethodsInterceptV2Points = getStaticMethodsInterceptV2Points(); String enhanceOriginClassName = typeDescription.getTypeName(); + if (staticMethodsInterceptV2Points == null) { + staticMethodsInterceptV2Points = getStaticMethodsInterceptV2Points(); + } if (staticMethodsInterceptV2Points == null || staticMethodsInterceptV2Points.length == 0) { return newClassBuilder; } + DelegateNamingResolver delegateNamingResolver = DelegateNamingResolver.get(typeDescription.getTypeName(), this); for (StaticMethodsInterceptV2Point staticMethodsInterceptV2Point : staticMethodsInterceptV2Points) { String interceptor = staticMethodsInterceptV2Point.getMethodsInterceptorV2(); @@ -85,7 +93,7 @@ protected DynamicType.Builder enhanceClass(TypeDescription typeDescription, isStatic().and(staticMethodsInterceptV2Point.getMethodsMatcher())) .intercept(MethodDelegation.withDefaultConfiguration() .withBinders(Morph.Binder.install(OverrideCallable.class)) - .to(new StaticMethodsInterV2WithOverrideArgs(interceptor))); + .to(new StaticMethodsInterV2WithOverrideArgs(interceptor), delegateNamingResolver.resolve(staticMethodsInterceptV2Point))); } } else { if (isBootstrapInstrumentation()) { @@ -97,7 +105,7 @@ protected DynamicType.Builder enhanceClass(TypeDescription typeDescription, newClassBuilder = newClassBuilder.method( isStatic().and(staticMethodsInterceptV2Point.getMethodsMatcher())) .intercept(MethodDelegation.withDefaultConfiguration() - .to(new StaticMethodsInterV2(interceptor))); + .to(new StaticMethodsInterV2(interceptor), delegateNamingResolver.resolve(staticMethodsInterceptV2Point))); } } @@ -110,9 +118,14 @@ protected DynamicType.Builder enhanceClass(TypeDescription typeDescription, protected DynamicType.Builder enhanceInstance(TypeDescription typeDescription, DynamicType.Builder newClassBuilder, ClassLoader classLoader, EnhanceContext context) throws PluginException { - ConstructorInterceptPoint[] constructorInterceptPoints = getConstructorsInterceptPoints(); - InstanceMethodsInterceptV2Point[] instanceMethodsInterceptV2Points = getInstanceMethodsInterceptV2Points(); + if (constructorInterceptPoints == null) { + constructorInterceptPoints = getConstructorsInterceptPoints(); + } + if (instanceMethodsInterceptV2Points == null) { + instanceMethodsInterceptV2Points = getInstanceMethodsInterceptV2Points(); + } String enhanceOriginClassName = typeDescription.getTypeName(); + DelegateNamingResolver fieldNamingResolver = DelegateNamingResolver.get(typeDescription.getTypeName(), this); boolean existedConstructorInterceptPoint = false; if (constructorInterceptPoints != null && constructorInterceptPoints.length > 0) { @@ -149,7 +162,7 @@ protected DynamicType.Builder enhanceInstance(TypeDescription typeDescription newClassBuilder = newClassBuilder.constructor(constructorInterceptPoint.getConstructorMatcher()) .intercept(SuperMethodCall.INSTANCE.andThen(MethodDelegation.withDefaultConfiguration() .to(new ConstructorInter(constructorInterceptPoint - .getConstructorInterceptor(), classLoader)))); + .getConstructorInterceptor(), classLoader), fieldNamingResolver.resolve(constructorInterceptPoint)))); } } } @@ -176,7 +189,7 @@ protected DynamicType.Builder enhanceInstance(TypeDescription typeDescription newClassBuilder = newClassBuilder.method(junction) .intercept(MethodDelegation.withDefaultConfiguration() .withBinders(Morph.Binder.install(OverrideCallable.class)) - .to(new InstMethodsInterV2WithOverrideArgs(interceptor, classLoader))); + .to(new InstMethodsInterV2WithOverrideArgs(interceptor, classLoader), fieldNamingResolver.resolve(instanceMethodsInterceptV2Point))); } } else { if (isBootstrapInstrumentation()) { @@ -186,7 +199,7 @@ protected DynamicType.Builder enhanceInstance(TypeDescription typeDescription } else { newClassBuilder = newClassBuilder.method(junction) .intercept(MethodDelegation.withDefaultConfiguration() - .to(new InstMethodsInterV2(interceptor, classLoader))); + .to(new InstMethodsInterV2(interceptor, classLoader), fieldNamingResolver.resolve(instanceMethodsInterceptV2Point))); } } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/match/MethodInheritanceAnnotationMatcher.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/match/MethodInheritanceAnnotationMatcher.java index 21511c1b23..a61740e98e 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/match/MethodInheritanceAnnotationMatcher.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/match/MethodInheritanceAnnotationMatcher.java @@ -97,4 +97,9 @@ public static ElementMatcher.Junction byMethodIn ElementMatcher matcher) { return new MethodInheritanceAnnotationMatcher(new CollectionItemMatcher<>(annotationType(matcher))); } + + @Override + public String toString() { + return "MethodInheritanceAnnotationMatcher(" + matcher + ')'; + } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/match/ProtectiveShieldMatcher.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/match/ProtectiveShieldMatcher.java index 96c0d7bbec..75e6dc86f8 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/match/ProtectiveShieldMatcher.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/match/ProtectiveShieldMatcher.java @@ -52,4 +52,9 @@ public boolean matches(T target) { return false; } } + + @Override + public String toString() { + return "ProtectiveShieldMatcher(" + matcher + ')'; + } } diff --git a/apm-sniffer/apm-agent/pom.xml b/apm-sniffer/apm-agent/pom.xml index e70018f03f..15b1e32024 100644 --- a/apm-sniffer/apm-agent/pom.xml +++ b/apm-sniffer/apm-agent/pom.xml @@ -47,6 +47,11 @@ apm-agent-core ${project.version} + + org.apache.skywalking + bytebuddy-patch + ${project.version} + diff --git a/apm-sniffer/apm-agent/src/main/java/org/apache/skywalking/apm/agent/SkyWalkingAgent.java b/apm-sniffer/apm-agent/src/main/java/org/apache/skywalking/apm/agent/SkyWalkingAgent.java index dd0a072164..7e518bb231 100644 --- a/apm-sniffer/apm-agent/src/main/java/org/apache/skywalking/apm/agent/SkyWalkingAgent.java +++ b/apm-sniffer/apm-agent/src/main/java/org/apache/skywalking/apm/agent/SkyWalkingAgent.java @@ -25,10 +25,14 @@ import java.util.Map; import net.bytebuddy.ByteBuddy; import net.bytebuddy.agent.builder.AgentBuilder; +import net.bytebuddy.agent.builder.SWAgentBuilderDefault; +import net.bytebuddy.agent.builder.SWNativeMethodStrategy; import net.bytebuddy.description.NamedElement; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.dynamic.DynamicType; import net.bytebuddy.dynamic.scaffold.TypeValidation; +import org.apache.skywalking.apm.agent.bytebuddy.SWAuxiliaryTypeNamingStrategy; +import net.bytebuddy.implementation.SWImplementationContextFactory; import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.matcher.ElementMatchers; import net.bytebuddy.utility.JavaModule; @@ -46,7 +50,7 @@ import org.apache.skywalking.apm.agent.core.plugin.PluginException; import org.apache.skywalking.apm.agent.core.plugin.PluginFinder; import org.apache.skywalking.apm.agent.core.plugin.bootstrap.BootstrapInstrumentBoost; -import org.apache.skywalking.apm.agent.core.plugin.bytebuddy.CacheableTransformerDecorator; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.DelegateNamingResolver; import org.apache.skywalking.apm.agent.core.plugin.jdk9module.JDK9ModuleExporter; import static net.bytebuddy.matcher.ElementMatchers.nameContains; @@ -69,7 +73,7 @@ public static void premain(String agentArgs, Instrumentation instrumentation) th } catch (Exception e) { // try to resolve a new logger, and use the new logger to write the error log here LogManager.getLogger(SkyWalkingAgent.class) - .error(e, "SkyWalking agent initialized failure. Shutting down."); + .error(e, "SkyWalking agent initialized failure. Shutting down."); return; } finally { // refresh logger again after initialization finishes @@ -91,9 +95,11 @@ public static void premain(String agentArgs, Instrumentation instrumentation) th return; } - final ByteBuddy byteBuddy = new ByteBuddy().with(TypeValidation.of(Config.Agent.IS_OPEN_DEBUGGING_CLASS)); + LOGGER.info("Skywalking agent begin to install transformer ..."); + String nameTrait = getNameTrait(); + DelegateNamingResolver.setNameTrait(nameTrait); - AgentBuilder agentBuilder = new AgentBuilder.Default(byteBuddy).ignore( + AgentBuilder agentBuilder = newAgentBuilder(instrumentation, nameTrait).ignore( nameStartsWith("net.bytebuddy.") .or(nameStartsWith("org.slf4j.")) .or(nameStartsWith("org.groovy.")) @@ -119,15 +125,6 @@ public static void premain(String agentArgs, Instrumentation instrumentation) th return; } - if (Config.Agent.IS_CACHE_ENHANCED_CLASS) { - try { - agentBuilder = agentBuilder.with(new CacheableTransformerDecorator(Config.Agent.CLASS_CACHE_MODE)); - LOGGER.info("SkyWalking agent class cache [{}] activated.", Config.Agent.CLASS_CACHE_MODE); - } catch (Exception e) { - LOGGER.error(e, "SkyWalking agent can't active class cache."); - } - } - agentBuilder.type(pluginFinder.buildMatch()) .transform(new Transformer(pluginFinder)) .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION) @@ -137,6 +134,8 @@ public static void premain(String agentArgs, Instrumentation instrumentation) th PluginFinder.pluginInitCompleted(); + LOGGER.info("Skywalking agent transformer has installed."); + try { ServiceManager.INSTANCE.boot(); } catch (Exception e) { @@ -147,6 +146,23 @@ public static void premain(String agentArgs, Instrumentation instrumentation) th .addShutdownHook(new Thread(ServiceManager.INSTANCE::shutdown, "skywalking service shutdown thread")); } + private static AgentBuilder newAgentBuilder(Instrumentation instrumentation, String nameTrait) { + final ByteBuddy byteBuddy = new ByteBuddy() + .with(TypeValidation.of(Config.Agent.IS_OPEN_DEBUGGING_CLASS)) + .with(new SWAuxiliaryTypeNamingStrategy(nameTrait)) + .with(new SWImplementationContextFactory(nameTrait)); + + SWNativeMethodStrategy nativeMethodStrategy = new SWNativeMethodStrategy(nameTrait); + + AgentBuilder agentBuilder = new SWAgentBuilderDefault(byteBuddy, nativeMethodStrategy) + .with(AgentBuilder.DescriptionStrategy.Default.POOL_FIRST); + return agentBuilder; + } + + private static String getNameTrait() { + return "sw$"; + } + private static class Transformer implements AgentBuilder.Transformer { private PluginFinder pluginFinder; diff --git a/apm-sniffer/bytebuddy-patch/pom.xml b/apm-sniffer/bytebuddy-patch/pom.xml new file mode 100644 index 0000000000..76ea2effb0 --- /dev/null +++ b/apm-sniffer/bytebuddy-patch/pom.xml @@ -0,0 +1,90 @@ + + + + + + org.apache.skywalking + java-agent-sniffer + 8.17.0-SNAPSHOT + + 4.0.0 + + bytebuddy-patch + + + 8 + 8 + + + + + org.apache.skywalking + apm-agent-core + ${project.version} + + + net.bytebuddy + byte-buddy + + + + org.projectlombok + lombok + 1.18.20 + provided + + + + junit + junit + test + + + org.ow2.asm + asm + 5.0.3 + test + + + org.ow2.asm + asm-util + 5.0.3 + test + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + **/*Test*.java + + + **/Abstract*.java + + + + + + \ No newline at end of file diff --git a/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWAgentBuilderDefault.java b/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWAgentBuilderDefault.java new file mode 100644 index 0000000000..388bc49ce0 --- /dev/null +++ b/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWAgentBuilderDefault.java @@ -0,0 +1,88 @@ +/* + * 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 net.bytebuddy.agent.builder; + +import net.bytebuddy.ByteBuddy; +import net.bytebuddy.NamingStrategy; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.dynamic.ClassFileLocator; +import net.bytebuddy.matcher.ElementMatchers; + +import java.util.Collections; +import java.util.List; + +import static net.bytebuddy.matcher.ElementMatchers.any; +import static net.bytebuddy.matcher.ElementMatchers.isBootstrapClassLoader; +import static net.bytebuddy.matcher.ElementMatchers.isExtensionClassLoader; +import static net.bytebuddy.matcher.ElementMatchers.isSynthetic; +import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith; +import static net.bytebuddy.matcher.ElementMatchers.not; + +/** + * A custom AgentBuilder.Default for changing NativeMethodStrategy + */ +public class SWAgentBuilderDefault extends AgentBuilder.Default { + + /** + * The default circularity lock that assures that no agent created by any agent builder within this + * class loader causes a class loading circularity. + */ + private static final CircularityLock DEFAULT_LOCK = new CircularityLock.Default(); + + public SWAgentBuilderDefault(NativeMethodStrategy nativeMethodStrategy) { + this(new ByteBuddy(), nativeMethodStrategy); + } + + public SWAgentBuilderDefault(ByteBuddy byteBuddy, NativeMethodStrategy nativeMethodStrategy) { + this(byteBuddy, + Listener.NoOp.INSTANCE, + DEFAULT_LOCK, + PoolStrategy.Default.FAST, + TypeStrategy.Default.REBASE, + LocationStrategy.ForClassLoader.STRONG, + ClassFileLocator.NoOp.INSTANCE, + nativeMethodStrategy, + WarmupStrategy.NoOp.INSTANCE, + TransformerDecorator.NoOp.INSTANCE, + new InitializationStrategy.SelfInjection.Split(), + RedefinitionStrategy.DISABLED, + RedefinitionStrategy.DiscoveryStrategy.SinglePass.INSTANCE, + RedefinitionStrategy.BatchAllocator.ForTotal.INSTANCE, + RedefinitionStrategy.Listener.NoOp.INSTANCE, + RedefinitionStrategy.ResubmissionStrategy.Disabled.INSTANCE, + InjectionStrategy.UsingReflection.INSTANCE, + LambdaInstrumentationStrategy.DISABLED, + DescriptionStrategy.Default.HYBRID, + FallbackStrategy.ByThrowableType.ofOptionalTypes(), + ClassFileBufferStrategy.Default.RETAINING, + InstallationListener.NoOp.INSTANCE, + new RawMatcher.Disjunction( + new RawMatcher.ForElementMatchers(any(), isBootstrapClassLoader().or(isExtensionClassLoader())), + new RawMatcher.ForElementMatchers(nameStartsWith("net.bytebuddy.") + .and(not(ElementMatchers.nameStartsWith(NamingStrategy.BYTE_BUDDY_RENAME_PACKAGE + "."))) + .or(nameStartsWith("sun.reflect.").or(nameStartsWith("jdk.internal.reflect."))) + .or(isSynthetic()))), + Collections.emptyList()); + } + + protected SWAgentBuilderDefault(ByteBuddy byteBuddy, Listener listener, CircularityLock circularityLock, PoolStrategy poolStrategy, TypeStrategy typeStrategy, LocationStrategy locationStrategy, ClassFileLocator classFileLocator, NativeMethodStrategy nativeMethodStrategy, WarmupStrategy warmupStrategy, TransformerDecorator transformerDecorator, InitializationStrategy initializationStrategy, RedefinitionStrategy redefinitionStrategy, RedefinitionStrategy.DiscoveryStrategy redefinitionDiscoveryStrategy, RedefinitionStrategy.BatchAllocator redefinitionBatchAllocator, RedefinitionStrategy.Listener redefinitionListener, RedefinitionStrategy.ResubmissionStrategy redefinitionResubmissionStrategy, InjectionStrategy injectionStrategy, LambdaInstrumentationStrategy lambdaInstrumentationStrategy, DescriptionStrategy descriptionStrategy, FallbackStrategy fallbackStrategy, ClassFileBufferStrategy classFileBufferStrategy, InstallationListener installationListener, RawMatcher ignoreMatcher, List transformations) { + super(byteBuddy, listener, circularityLock, poolStrategy, typeStrategy, locationStrategy, classFileLocator, nativeMethodStrategy, warmupStrategy, transformerDecorator, initializationStrategy, redefinitionStrategy, redefinitionDiscoveryStrategy, redefinitionBatchAllocator, redefinitionListener, redefinitionResubmissionStrategy, injectionStrategy, lambdaInstrumentationStrategy, descriptionStrategy, fallbackStrategy, classFileBufferStrategy, installationListener, ignoreMatcher, transformations); + } + +} diff --git a/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWNativeMethodStrategy.java b/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWNativeMethodStrategy.java new file mode 100644 index 0000000000..eccbe0fc41 --- /dev/null +++ b/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWNativeMethodStrategy.java @@ -0,0 +1,44 @@ +/* + * 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 net.bytebuddy.agent.builder; + +import net.bytebuddy.dynamic.scaffold.inline.MethodNameTransformer; +import org.apache.skywalking.apm.agent.bytebuddy.SWMethodNameTransformer; + +import java.lang.instrument.ClassFileTransformer; +import java.lang.instrument.Instrumentation; + +public class SWNativeMethodStrategy implements AgentBuilder.Default.NativeMethodStrategy { + private static final String DEFAULT_PREFIX = "origin$"; + + private String prefix; + + public SWNativeMethodStrategy(String nameTrait) { + this.prefix = nameTrait + DEFAULT_PREFIX; + } + + @Override + public MethodNameTransformer resolve() { + return new SWMethodNameTransformer(prefix); + } + + @Override + public void apply(Instrumentation instrumentation, ClassFileTransformer classFileTransformer) { + } +} \ No newline at end of file diff --git a/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/implementation/SWImplementationContextFactory.java b/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/implementation/SWImplementationContextFactory.java new file mode 100644 index 0000000000..f1aac5cb6e --- /dev/null +++ b/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/implementation/SWImplementationContextFactory.java @@ -0,0 +1,59 @@ +/* + * 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 net.bytebuddy.implementation; + +import net.bytebuddy.ClassFileVersion; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.dynamic.scaffold.TypeInitializer; +import net.bytebuddy.implementation.auxiliary.AuxiliaryType; +import net.bytebuddy.utility.RandomString; + +/** + * Support custom suffix name trait, using in cache value field name, field getter/setter delegation, accessor method and so on. + */ +public class SWImplementationContextFactory implements Implementation.Context.Factory { + + private String suffixNameTrait; + + public SWImplementationContextFactory(String suffixNameTrait) { + this.suffixNameTrait = suffixNameTrait; + } + + @Override + public Implementation.Context.ExtractableView make(TypeDescription instrumentedType, + AuxiliaryType.NamingStrategy auxiliaryTypeNamingStrategy, + TypeInitializer typeInitializer, + ClassFileVersion classFileVersion, + ClassFileVersion auxiliaryClassFileVersion) { + return this.make(instrumentedType, auxiliaryTypeNamingStrategy, typeInitializer, classFileVersion, + auxiliaryClassFileVersion, Implementation.Context.FrameGeneration.GENERATE); + } + + @Override + public Implementation.Context.ExtractableView make(TypeDescription instrumentedType, + AuxiliaryType.NamingStrategy auxiliaryTypeNamingStrategy, + TypeInitializer typeInitializer, + ClassFileVersion classFileVersion, + ClassFileVersion auxiliaryClassFileVersion, + Implementation.Context.FrameGeneration frameGeneration) { + return new Implementation.Context.Default(instrumentedType, classFileVersion, auxiliaryTypeNamingStrategy, + typeInitializer, auxiliaryClassFileVersion, frameGeneration, + suffixNameTrait + RandomString.hashOf(instrumentedType.getName().hashCode())); + } +} diff --git a/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWAsmVisitorWrapper.java b/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWAsmVisitorWrapper.java new file mode 100644 index 0000000000..4aeddd8cdb --- /dev/null +++ b/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWAsmVisitorWrapper.java @@ -0,0 +1,120 @@ +/* + * 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; + +import net.bytebuddy.asm.AsmVisitorWrapper; +import net.bytebuddy.description.field.FieldDescription; +import net.bytebuddy.description.field.FieldList; +import net.bytebuddy.description.method.MethodList; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.implementation.Implementation; +import net.bytebuddy.jar.asm.ClassVisitor; +import net.bytebuddy.jar.asm.FieldVisitor; +import net.bytebuddy.jar.asm.MethodVisitor; +import net.bytebuddy.jar.asm.Opcodes; +import net.bytebuddy.pool.TypePool; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Remove duplicated fields of instrumentedType + */ +public class SWAsmVisitorWrapper implements AsmVisitorWrapper { + + private String nameTrait = "$"; + + public SWAsmVisitorWrapper() { + } + + @Override + public int mergeWriter(int flags) { + return flags; + } + + @Override + public int mergeReader(int flags) { + return flags; + } + + @Override + public ClassVisitor wrap(TypeDescription instrumentedType, ClassVisitor classVisitor, Implementation.Context implementationContext, + TypePool typePool, FieldList fields, MethodList methods, + int writerFlags, int readerFlags) { + if (classVisitor instanceof RemoveDuplicatedElementsVisitor) { + return classVisitor; + } + return new RemoveDuplicatedElementsVisitor(Opcodes.ASM8, classVisitor); + } + + class RemoveDuplicatedElementsVisitor extends ClassVisitor { + + private Map> fieldCache = new ConcurrentHashMap<>(); + private Map>> methodCache = new ConcurrentHashMap<>(); + private String className; + + public RemoveDuplicatedElementsVisitor(int api, ClassVisitor classVisitor) { + super(api, classVisitor); + } + + @Override + public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { + super.visit(version, access, name, signature, superName, interfaces); + this.className = name; + } + + @Override + public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) { + if (name.contains(nameTrait)) { + Map fieldData = getFieldData(className); + String prevDescriptor = fieldData.get(name); + if (prevDescriptor != null && prevDescriptor.equals(descriptor)) { + // ignore duplicated field of class + return null; + } + fieldData.put(name, descriptor); + } + return super.visitField(access, name, descriptor, signature, value); + } + + @Override + public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { + if (name.equals("") || name.contains(nameTrait)) { + Map> methodData = getMethodData(className); + List descriptorList = methodData.computeIfAbsent(name, k -> new ArrayList<>()); + if (descriptorList.contains(descriptor)) { + // ignore duplicated method of class + return null; + } + descriptorList.add(descriptor); + } + return super.visitMethod(access, name, descriptor, signature, exceptions); + } + + private Map getFieldData(String className) { + return fieldCache.computeIfAbsent(className, k -> new ConcurrentHashMap<>()); + } + + private Map> getMethodData(String className) { + return methodCache.computeIfAbsent(className, k -> new ConcurrentHashMap<>()); + } + } +} diff --git a/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWAuxiliaryTypeNamingStrategy.java b/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWAuxiliaryTypeNamingStrategy.java new file mode 100644 index 0000000000..ac2b802eb4 --- /dev/null +++ b/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWAuxiliaryTypeNamingStrategy.java @@ -0,0 +1,41 @@ +/* + * 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; + +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.implementation.auxiliary.AuxiliaryType; +import net.bytebuddy.utility.RandomString; + +/** + * Generate predicated auxiliary type name for delegate method + */ +public class SWAuxiliaryTypeNamingStrategy implements AuxiliaryType.NamingStrategy { + private static final String DEFAULT_SUFFIX = "auxiliary$"; + private String suffix; + + public SWAuxiliaryTypeNamingStrategy(String nameTrait) { + this.suffix = nameTrait + DEFAULT_SUFFIX; + } + + @Override + public String name(TypeDescription instrumentedType, AuxiliaryType auxiliaryType) { + return instrumentedType.getName() + "$" + suffix + RandomString.hashOf(auxiliaryType.hashCode()); + } + +} diff --git a/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWClassFileLocator.java b/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWClassFileLocator.java new file mode 100644 index 0000000000..22bc502255 --- /dev/null +++ b/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWClassFileLocator.java @@ -0,0 +1,178 @@ +/* + * 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; + +import net.bytebuddy.dynamic.ClassFileLocator; +import org.apache.skywalking.apm.agent.core.logging.api.ILog; +import org.apache.skywalking.apm.agent.core.logging.api.LogManager; + +import java.io.IOException; +import java.lang.instrument.Instrumentation; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.TimeUnit; + +/** + * Resolve auxiliary type + */ +public class SWClassFileLocator implements ClassFileLocator { + private static ILog LOGGER = LogManager.getLogger(SWClassFileLocator.class); + + private final ForInstrumentation.ClassLoadingDelegate classLoadingDelegate; + private Instrumentation instrumentation; + private ClassLoader classLoader; + private String[] typeNameTraits = {"auxiliary$", "ByteBuddy$", "sw$"}; + private BlockingQueue queue = new LinkedBlockingDeque<>(); + private Thread thread; + private int timeoutSeconds = 2; + private volatile boolean closed; + + public SWClassFileLocator(Instrumentation instrumentation, ClassLoader classLoader, String[] typeNameTraits) { + this(instrumentation, classLoader); + this.typeNameTraits = typeNameTraits; + } + + public SWClassFileLocator(Instrumentation instrumentation, ClassLoader classLoader) { + this.instrumentation = instrumentation; + this.classLoader = classLoader; + classLoadingDelegate = ForInstrumentation.ClassLoadingDelegate.ForDelegatingClassLoader.of(classLoader); + + // Use thread instead of ExecutorService here, avoiding conflicts with apm-jdk-threadpool-plugin + thread = new Thread(() -> { + while (!closed) { + try { + ResolutionFutureTask task = queue.poll(5, TimeUnit.SECONDS); + if (task != null) { + try { + Resolution resolution = getResolution(task.getClassName()); + task.getFuture().complete(resolution); + } catch (Throwable e) { + task.getFuture().completeExceptionally(e); + } + } + } catch (InterruptedException e) { + // ignore interrupted error + } catch (Throwable e) { + LOGGER.error(e, "Resolve bytecode of class failure"); + } + } + }, "SWClassFileLocator"); + thread.setDaemon(true); + thread.start(); + } + + @Override + public Resolution locate(String name) throws IOException { + if (!match(name)) { + return new Resolution.Illegal(name); + } + if (closed) { + throw new IOException("resolve class failure: closed"); + } + // get class binary representation in a clean thread, avoiding nest calling transformer! + ResolutionFutureTask futureTask = new ResolutionFutureTask(name); + queue.offer(futureTask); + try { + return futureTask.getFuture().get(timeoutSeconds, TimeUnit.SECONDS); + } catch (Exception e) { + throw new IOException("resolve class failure: " + name, e); + } + } + + private boolean match(String name) { + boolean matched = false; + for (String typeNameTrait : typeNameTraits) { + if (name.contains(typeNameTrait)) { + matched = true; + break; + } + } + return matched; + } + + private Resolution getResolution(String name) throws Exception { + SWExtractionClassFileTransformer classFileTransformer = new SWExtractionClassFileTransformer(name); + try { + instrumentation.addTransformer(classFileTransformer, true); + Class aClass = locateClass(name); + if (aClass == null) { + return new Resolution.Illegal(name); + } + instrumentation.retransformClasses(new Class[]{aClass}); + } finally { + instrumentation.removeTransformer(classFileTransformer); + } + + return classFileTransformer.getBinaryRepresentation() != null ? + new Resolution.Explicit(classFileTransformer.getBinaryRepresentation()) : + new Resolution.Illegal(name); + } + + private Class locateClass(String className) { + // find class in classloader + try { + return classLoadingDelegate.locate(className); + } catch (ClassNotFoundException e) { + } + + // find class in instrumentation + Class[] allLoadedClasses = instrumentation.getAllLoadedClasses(); + for (int i = 0; i < allLoadedClasses.length; i++) { + Class aClass = allLoadedClasses[i]; + if (className.equals(aClass.getName())) { + return aClass; + } + } + return null; + } + + @Override + public void close() throws IOException { + closed = true; + queue.clear(); + thread.interrupt(); + } + + public int getTimeoutSeconds() { + return timeoutSeconds; + } + + public void setTimeoutSeconds(int timeoutSeconds) { + this.timeoutSeconds = timeoutSeconds; + } + + private class ResolutionFutureTask { + private CompletableFuture future; + private String className; + + public ResolutionFutureTask(String className) { + this.className = className; + future = new CompletableFuture<>(); + } + + public CompletableFuture getFuture() { + return future; + } + + public String getClassName() { + return className; + } + } +} diff --git a/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWExtractionClassFileTransformer.java b/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWExtractionClassFileTransformer.java new file mode 100644 index 0000000000..7466be2ebc --- /dev/null +++ b/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWExtractionClassFileTransformer.java @@ -0,0 +1,76 @@ +/* + * 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; + +import java.lang.instrument.ClassFileTransformer; +import java.security.ProtectionDomain; + +public class SWExtractionClassFileTransformer implements ClassFileTransformer { + + /** + * An indicator that an attempted class file transformation did not alter the handed class file. + */ + private static final byte[] DO_NOT_TRANSFORM = null; + +// /** +// * The class loader that is expected to have loaded the looked-up a class. +// */ +// private final ClassLoader classLoader; + + /** + * The name of the type to look up. + */ + private final String typeName; + + /** + * The binary representation of the looked-up class. + */ + private volatile byte[] binaryRepresentation; + + /** + * Creates a class file transformer for the purpose of extraction. + * + * @param typeName The name of the type to look up. + */ + public SWExtractionClassFileTransformer(String typeName) { + this.typeName = typeName; + } + + @Override + public byte[] transform(ClassLoader classLoader, + String internalName, + Class redefinedType, + ProtectionDomain protectionDomain, + byte[] binaryRepresentation) { + if (internalName != null && typeName.equals(internalName.replace('/', '.'))) { + this.binaryRepresentation = binaryRepresentation.clone(); + } + return DO_NOT_TRANSFORM; + } + + /** + * Returns the binary representation of the class file that was looked up. The returned array must never be modified. + * + * @return The binary representation of the class file or {@code null} if no such class file could + * be located. + */ + public byte[] getBinaryRepresentation() { + return binaryRepresentation; + } +} \ No newline at end of file diff --git a/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWMethodNameTransformer.java b/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWMethodNameTransformer.java new file mode 100644 index 0000000000..47441b6f4e --- /dev/null +++ b/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWMethodNameTransformer.java @@ -0,0 +1,47 @@ +/* + * 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; + +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.dynamic.scaffold.inline.MethodNameTransformer; +import net.bytebuddy.utility.RandomString; + +/** + * Generate fixed origin method name with method description hash code + */ +public class SWMethodNameTransformer implements MethodNameTransformer { + + private static final String DEFAULT_PREFIX = "original$"; + + private String prefix; + + public SWMethodNameTransformer() { + this(DEFAULT_PREFIX); + } + + public SWMethodNameTransformer(String prefix) { + this.prefix = prefix; + } + + @Override + public String transform(MethodDescription methodDescription) { + return prefix + methodDescription.getInternalName() + "$" + RandomString.hashOf(methodDescription.toString().hashCode()); + } + +} diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/ConstructorAdvice.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/ConstructorAdvice.java new file mode 100644 index 0000000000..43a36aba44 --- /dev/null +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/ConstructorAdvice.java @@ -0,0 +1,33 @@ +/* + * 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; + +import net.bytebuddy.asm.Advice; + +import java.lang.reflect.Constructor; +import java.util.Arrays; + +public class ConstructorAdvice { + + @Advice.OnMethodExit(inline = false) + public static void onExit(@Advice.Origin Constructor constructor, + @Advice.AllArguments Object[] args) throws Exception { + Log.info(String.format("ConstructorAdvice: constructor: %s, args: %s", constructor, Arrays.asList(args))); + } +} \ No newline at end of file diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/ConstructorInter.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/ConstructorInter.java new file mode 100644 index 0000000000..2c10f74cd7 --- /dev/null +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/ConstructorInter.java @@ -0,0 +1,54 @@ +/* + * 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; + +import net.bytebuddy.implementation.bind.annotation.AllArguments; +import net.bytebuddy.implementation.bind.annotation.RuntimeType; +import net.bytebuddy.implementation.bind.annotation.This; + +import java.util.Arrays; + +/** + * The actual byte-buddy's interceptor to intercept constructor methods. In this class, it provides a bridge between + * byte-buddy and sky-walking plugin. + */ +public class ConstructorInter { + private String interceptorClassName; + private ClassLoader classLoader; + + /** + * @param interceptorClassName class full name. + */ + public ConstructorInter(String interceptorClassName, ClassLoader classLoader) { + this.interceptorClassName = interceptorClassName; + this.classLoader = classLoader; + } + + /** + * Intercept the target constructor. + * + * @param obj target class instance. + * @param allArguments all constructor arguments + */ + @RuntimeType + public void intercept(@This Object obj, @AllArguments Object[] allArguments) { + EnhanceHelper.addInterceptor(interceptorClassName); + Log.info(String.format("ConstructorInterceptorClass: %s, target: %s, args: %s", interceptorClassName, obj, Arrays.asList(allArguments))); + } +} \ No newline at end of file diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/EnhanceHelper.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/EnhanceHelper.java new file mode 100644 index 0000000000..2b05697258 --- /dev/null +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/EnhanceHelper.java @@ -0,0 +1,76 @@ +/* + * 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; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class EnhanceHelper { + + private static List INTERCEPTORS = new ArrayList<>(); + private static List> ERRORS = new ArrayList<>(); + + public static void onError(String message, Throwable error) { + ERRORS.add(new MapEntry(message, error)); + } + + public static void addInterceptor(String interceptor) { + INTERCEPTORS.add(interceptor); + } + + public static List getInterceptors() { + return INTERCEPTORS; + } + + public static List> getErrors() { + return ERRORS; + } + + public static void clear() { + ERRORS.clear(); + INTERCEPTORS.clear(); + } + + private static class MapEntry implements Map.Entry { + private T key; + private P value; + + public MapEntry(T key, P value) { + this.key = key; + this.value = value; + } + + @Override + public T getKey() { + return key; + } + + @Override + public P getValue() { + return value; + } + + @Override + public P setValue(P value) { + this.value = value; + return value; + } + } +} diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/InstMethodAdvice.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/InstMethodAdvice.java new file mode 100644 index 0000000000..1307e520ca --- /dev/null +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/InstMethodAdvice.java @@ -0,0 +1,42 @@ +/* + * 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; + +import net.bytebuddy.asm.Advice; + +import java.lang.reflect.Method; +import java.util.Arrays; + +public class InstMethodAdvice { + + @Advice.OnMethodEnter(inline = false) + public static void onEnter(@Advice.This Object target, + @Advice.Origin Method method, + @Advice.AllArguments Object[] args) throws Exception { + Log.info(String.format("InstMethodAdvice.onEnter: constructor: %s, args: %s", method, Arrays.asList(args))); + } + + @Advice.OnMethodExit(inline = false) + public static void onExit(@Advice.This Object target, + @Advice.Origin Method method, + @Advice.AllArguments Object[] args) throws Exception { + Log.info(String.format("InstMethodAdvice.onExit: constructor: %s, args: %s", method, Arrays.asList(args))); + } + +} \ No newline at end of file diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/InstMethodsInter.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/InstMethodsInter.java new file mode 100644 index 0000000000..96ee856dc7 --- /dev/null +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/InstMethodsInter.java @@ -0,0 +1,63 @@ +/* + * 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; + +import net.bytebuddy.implementation.bind.annotation.AllArguments; +import net.bytebuddy.implementation.bind.annotation.Origin; +import net.bytebuddy.implementation.bind.annotation.RuntimeType; +import net.bytebuddy.implementation.bind.annotation.SuperCall; +import net.bytebuddy.implementation.bind.annotation.This; + +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.concurrent.Callable; + +public class InstMethodsInter { + private String interceptorClassName; + private ClassLoader classLoader; + + public InstMethodsInter(String interceptorClassName, ClassLoader classLoader) { + this.interceptorClassName = interceptorClassName; + this.classLoader = classLoader; + } + + @RuntimeType + public Object intercept(@This Object obj, @AllArguments Object[] allArguments, @SuperCall Callable zuper, + @Origin Method method) throws Throwable { + EnhanceHelper.addInterceptor(interceptorClassName); + + Object originResult = zuper.call(); + Object finalResult; + if (originResult instanceof String) { + String result = (String) originResult; + result = result.replaceAll("Joe", "John"); + finalResult = result; + } else if (originResult instanceof Integer) { + Integer result = (Integer) originResult; + finalResult = result + 1; + } else { + finalResult = originResult; + } + + Log.info(String.format("InstMethodInterceptorClass: %s, target: %s, args: %s, SuperCall: %s, method: %s, originResult: %s, finalResult: %s", + interceptorClassName, obj, Arrays.asList(allArguments), zuper, method, originResult, finalResult)); + return finalResult; + } + +} diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/Log.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/Log.java new file mode 100644 index 0000000000..0bae0273bc --- /dev/null +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/Log.java @@ -0,0 +1,42 @@ +/* + * 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; + +import java.io.PrintStream; + +public class Log { + private static PrintStream PRINT = System.out; + private static PrintStream ERROR_PRINT = System.err; + + public static void info(String msg) { + PRINT.println(msg); + } + + public static void info(int msg) { + PRINT.println(msg); + } + + public static void info(Object obj) { + PRINT.println(obj); + } + + public static void error(String msg) { + ERROR_PRINT.println(msg); + } +} diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/BizFoo.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/BizFoo.java new file mode 100644 index 0000000000..95aaaca1ee --- /dev/null +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/BizFoo.java @@ -0,0 +1,44 @@ +/* + * 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 BizFoo { + + private String name; + + public BizFoo() { + this("Tom"); + } + + public BizFoo(String name) { + this.name = name; + } + + public String sayHello(String someone) { + return "Hello to " + someone + " from " + name; + } + + public int sayHello(int uid) { + return uid; + } + + public String greeting(String man) { + return "Greet " + man; + } +} diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/DocDO.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/DocDO.java new file mode 100644 index 0000000000..d2929cec0b --- /dev/null +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/DocDO.java @@ -0,0 +1,43 @@ +/* + * 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; + +import lombok.Builder; + +@Builder +public class DocDO { + private int id; + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/DocService.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/DocService.java new file mode 100644 index 0000000000..2ceb9b31e4 --- /dev/null +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/DocService.java @@ -0,0 +1,39 @@ +/* + * 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; + +import java.util.ArrayList; +import java.util.List; + +public class DocService { + + private List cache = new ArrayList<>(); + + public void add(DocDO docDO) { + this.cache.add(docDO); + } + + public DocDO getById(int id) { + return cache.stream().filter(DocDO -> DocDO.getId() == id).findAny().orElse(null); + } + + public List list() { + return cache; + } +} diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/ProjectDO.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/ProjectDO.java new file mode 100644 index 0000000000..86e79fed4d --- /dev/null +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/ProjectDO.java @@ -0,0 +1,45 @@ +/* + * 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; + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class ProjectDO { + private int id; + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/ProjectService.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/ProjectService.java new file mode 100644 index 0000000000..eeece4afcb --- /dev/null +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/ProjectService.java @@ -0,0 +1,39 @@ +/* + * 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; + +import java.util.ArrayList; +import java.util.List; + +public class ProjectService { + + private List cache = new ArrayList<>(); + + public void add(ProjectDO projectDO) { + this.cache.add(projectDO); + } + + public ProjectDO getById(int id) { + return cache.stream().filter(projectDO -> projectDO.getId() == id).findAny().orElse(null); + } + + public List list() { + return cache; + } +} diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/AbstractInterceptTest.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/AbstractInterceptTest.java new file mode 100644 index 0000000000..1ceb750de4 --- /dev/null +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/AbstractInterceptTest.java @@ -0,0 +1,247 @@ +/* + * 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.case1; + +import net.bytebuddy.ByteBuddy; +import net.bytebuddy.agent.ByteBuddyAgent; +import net.bytebuddy.agent.builder.AgentBuilder; +import net.bytebuddy.agent.builder.SWAgentBuilderDefault; +import org.apache.skywalking.apm.agent.bytebuddy.SWAsmVisitorWrapper; +import net.bytebuddy.agent.builder.SWNativeMethodStrategy; +import net.bytebuddy.asm.Advice; +import net.bytebuddy.implementation.MethodDelegation; +import org.apache.skywalking.apm.agent.bytebuddy.SWAuxiliaryTypeNamingStrategy; +import net.bytebuddy.implementation.SWImplementationContextFactory; +import net.bytebuddy.implementation.SuperMethodCall; +import net.bytebuddy.matcher.ElementMatchers; +import net.bytebuddy.utility.JavaModule; +import org.apache.skywalking.apm.agent.bytebuddy.ConstructorAdvice; +import org.apache.skywalking.apm.agent.bytebuddy.ConstructorInter; +import org.apache.skywalking.apm.agent.bytebuddy.EnhanceHelper; +import org.apache.skywalking.apm.agent.bytebuddy.InstMethodAdvice; +import org.apache.skywalking.apm.agent.bytebuddy.InstMethodsInter; +import org.apache.skywalking.apm.agent.bytebuddy.Log; +import org.apache.skywalking.apm.agent.bytebuddy.SWClassFileLocator; +import org.apache.skywalking.apm.agent.bytebuddy.biz.BizFoo; +import org.junit.Assert; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.util.TraceClassVisitor; + +import java.io.ByteArrayOutputStream; +import java.io.PrintWriter; +import java.lang.instrument.ClassFileTransformer; +import java.lang.instrument.IllegalClassFormatException; +import java.security.ProtectionDomain; +import java.util.Arrays; +import java.util.List; + +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 SAY_HELLO_METHOD = "sayHello"; + public static final int BASE_INT_VALUE = 100; + public static final String CONSTRUCTOR_INTERCEPTOR_CLASS = "constructorInterceptorClass"; + public static final String METHOD_INTERCEPTOR_CLASS = "methodInterceptorClass"; + protected List nameTraits = Arrays.asList("sw2023", "sw2024"); + protected boolean deleteDuplicatedFields = false; + + protected static void callBizFoo(int round) { + Log.info("-------------"); + Log.info("callBizFoo: " + round); + // load target class + int intResult = new BizFoo().sayHello(BASE_INT_VALUE); + Log.info(intResult); + + String result = new BizFoo("Smith").sayHello("Joe"); + Log.info(result); + + Assert.assertEquals("Int value is unexpected", BASE_INT_VALUE + round, intResult); + Assert.assertEquals("String value is unexpected", "Hello to John from Smith", result); + } + + protected static void checkMethodInterceptor(String method, int round) { + List interceptors = EnhanceHelper.getInterceptors(); + String interceptorName = METHOD_INTERCEPTOR_CLASS + "$" + method + "$" + round; + Assert.assertTrue("Not found interceptor: " + interceptorName, interceptors.contains(interceptorName)); + Log.info("Found interceptor: " + interceptorName); + } + + protected static void checkConstructorInterceptor(int round) { + List interceptors = EnhanceHelper.getInterceptors(); + String interceptorName = CONSTRUCTOR_INTERCEPTOR_CLASS + "$" + round; + Assert.assertTrue("Not found interceptor: " + interceptorName, interceptors.contains(interceptorName)); + Log.info("Found interceptor: " + interceptorName); + } + + protected void installMethodInterceptor(String className, String methodName, int round) { + this.installMethodInterceptor1(className, methodName, round); +// this.installMethodInterceptor2(className, methodName, round); + } + + protected void installMethodInterceptor1(String className, String methodName, int round) { + String interceptorClassName = METHOD_INTERCEPTOR_CLASS + "$" + methodName + "$" + round; + String nameTrait = getNameTrait(round); + String fieldName = nameTrait + "_delegate$" + methodName + round; + + newAgentBuilder(nameTrait).type(ElementMatchers.named(className)) + .transform((builder, typeDescription, classLoader, module, protectionDomain) -> { + if (deleteDuplicatedFields) { + builder = builder.visit(new SWAsmVisitorWrapper()); + } + return builder + .method(ElementMatchers.nameContainsIgnoreCase(methodName)) + .intercept(MethodDelegation.withDefaultConfiguration() + .to(new InstMethodsInter(interceptorClassName, classLoader), fieldName)) + ; + } + ) + .with(new AgentBuilder.Listener.Adapter() { + @Override + public void onError(String typeName, ClassLoader classLoader, JavaModule module, boolean loaded, Throwable throwable) { + System.err.println(String.format("Transform Error: interceptorClassName: %s, typeName: %s, classLoader: %s, module: %s, loaded: %s", interceptorClassName, typeName, classLoader, module, loaded)); + throwable.printStackTrace(); + } + }) + .installOn(ByteBuddyAgent.install()); + } + + protected void installMethodInterceptor2(String className, String methodName, int round) { + String interceptorClassName = METHOD_INTERCEPTOR_CLASS + "$" + methodName + "$" + round; + String nameTrait = getNameTrait(round); + String fieldName = nameTrait + "_delegate$" + methodName + round; + + AgentBuilder agentBuilder = newAgentBuilder(nameTrait); + agentBuilder.type(ElementMatchers.named(className)) + .transform((builder, typeDescription, classLoader, module, protectionDomain) -> { + if (deleteDuplicatedFields) { + builder = builder.visit(new SWAsmVisitorWrapper()); + } + return builder + .method(ElementMatchers.nameContainsIgnoreCase(methodName)) + .intercept(Advice.to(InstMethodAdvice.class)); + } + ) + .with(new AgentBuilder.Listener.Adapter() { + @Override + public void onError(String typeName, ClassLoader classLoader, JavaModule module, boolean loaded, Throwable throwable) { + System.err.println(String.format("Transform Error: interceptorClassName: %s, typeName: %s, classLoader: %s, module: %s, loaded: %s", interceptorClassName, typeName, classLoader, module, loaded)); + throwable.printStackTrace(); + } + }) + .installOn(ByteBuddyAgent.install()); + } + + protected void installConstructorInterceptor(String className, int round) { + installConstructorInterceptor1(className, round); +// installConstructorInterceptor2(className, round); + } + + protected void installConstructorInterceptor1(String className, int round) { + String interceptorClassName = CONSTRUCTOR_INTERCEPTOR_CLASS + "$" + round; + String nameTrait = getNameTrait(round); + String fieldName = nameTrait + "_delegate$constructor" + round; + + AgentBuilder agentBuilder = newAgentBuilder(nameTrait); + agentBuilder.type(ElementMatchers.named(className)) + .transform((builder, typeDescription, classLoader, module, protectionDomain) -> { + if (deleteDuplicatedFields) { + builder = builder.visit(new SWAsmVisitorWrapper()); + } + return builder + .constructor(ElementMatchers.any()) + .intercept(SuperMethodCall.INSTANCE.andThen( + MethodDelegation.withDefaultConfiguration().to( + new ConstructorInter(interceptorClassName, classLoader), fieldName) + )); + } + ) + .with(new AgentBuilder.Listener.Adapter() { + @Override + public void onError(String typeName, ClassLoader classLoader, JavaModule module, boolean loaded, Throwable throwable) { + System.err.println(String.format("Transform Error: interceptorClass:%s, typeName: %s, classLoader: %s, module: %s, loaded: %s", interceptorClassName, typeName, classLoader, module, loaded)); + throwable.printStackTrace(); + } + }) + .installOn(ByteBuddyAgent.install()); + } + + protected void installConstructorInterceptor2(String className, int round) { + String interceptorClassName = CONSTRUCTOR_INTERCEPTOR_CLASS + "$" + round; + String nameTrait = getNameTrait(round); + String fieldName = nameTrait + "_delegate$constructor" + round; + + AgentBuilder agentBuilder = newAgentBuilder(nameTrait); + agentBuilder.type(ElementMatchers.named(className)) + .transform((builder, typeDescription, classLoader, module, protectionDomain) -> { + if (deleteDuplicatedFields) { + builder = builder.visit(new SWAsmVisitorWrapper()); + } + return builder + .constructor(ElementMatchers.any()) + .intercept(Advice.to(ConstructorAdvice.class)); + } + ) + .with(new AgentBuilder.Listener.Adapter() { + @Override + public void onError(String typeName, ClassLoader classLoader, JavaModule module, boolean loaded, Throwable throwable) { + System.err.println(String.format("Transform Error: interceptorClass:%s, typeName: %s, classLoader: %s, module: %s, loaded: %s", interceptorClassName, typeName, classLoader, module, loaded)); + throwable.printStackTrace(); + } + }) + .installOn(ByteBuddyAgent.install()); + } + + protected String getNameTrait(int round) { + return nameTraits.get(round - 1); + } + + protected AgentBuilder newAgentBuilder(String nameTrait) { + ByteBuddy byteBuddy = new ByteBuddy() + .with(new SWAuxiliaryTypeNamingStrategy(nameTrait)) + .with(new SWImplementationContextFactory(nameTrait)) + ; + + return new SWAgentBuilderDefault(byteBuddy, new SWNativeMethodStrategy(nameTrait)) + .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION) + .with(AgentBuilder.DescriptionStrategy.Default.POOL_FIRST) + .with(new SWClassFileLocator(ByteBuddyAgent.install(), getClassLoader())); + } + + private static ClassLoader getClassLoader() { + return AbstractInterceptTest.class.getClassLoader(); + } + + 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")) { + Log.error(msg + className); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + ClassReader cr = new ClassReader(classfileBuffer); + cr.accept(new TraceClassVisitor(new PrintWriter(outputStream)), ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES); + Log.error(outputStream.toString()); + } + return null; + } + }; + ByteBuddyAgent.install().addTransformer(classFileTransformer, true); + } +} diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/AbstractRetransformTest.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/AbstractRetransformTest.java new file mode 100644 index 0000000000..33d7ee5c03 --- /dev/null +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/AbstractRetransformTest.java @@ -0,0 +1,56 @@ +/* + * 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.case1; + +import org.apache.skywalking.apm.agent.bytebuddy.Log; + +import java.lang.instrument.ClassFileTransformer; +import java.lang.instrument.IllegalClassFormatException; +import java.lang.instrument.Instrumentation; +import java.lang.instrument.UnmodifiableClassException; +import java.security.ProtectionDomain; + +public class AbstractRetransformTest extends AbstractInterceptTest { + + protected static void reTransform(Instrumentation instrumentation, Class clazz) throws UnmodifiableClassException { + Log.info("-------------"); + Log.info("Begin to retransform class: " + clazz.getName() + " .."); + ClassFileTransformer transformer = new ClassFileTransformer() { + public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, + ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { + Log.info(String.format("transform: className=%s, classBeingRedefined=%s, classloader=%s, protectionDomain=%s, classfileBuffer=%d", + className, classBeingRedefined, loader, protectionDomain.getCodeSource(), classfileBuffer.length)); + return null; + } + }; + try { + instrumentation.addTransformer(transformer, true); + instrumentation.retransformClasses(clazz); + Log.info("Retransform class " + clazz.getName() + " successful."); + Log.info("-------------"); + } catch (Throwable e) { + Log.info("Retransform class " + clazz.getName() + " failure: " + e); + Log.info("-------------"); + throw e; + } finally { + instrumentation.removeTransformer(transformer); + } + } + +} diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest1.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest1.java new file mode 100644 index 0000000000..7e00b32887 --- /dev/null +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest1.java @@ -0,0 +1,47 @@ +/* + * 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.case1; + +import net.bytebuddy.agent.ByteBuddyAgent; +import org.junit.Test; + +import java.lang.instrument.UnmodifiableClassException; + +public class InterceptTest1 extends AbstractInterceptTest { + + @Test + public void test1() throws UnmodifiableClassException { + ByteBuddyAgent.install(); + + // install transformer + installMethodInterceptor(BIZ_FOO_CLASS_NAME, SAY_HELLO_METHOD, 1); + installConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); + + try { + callBizFoo(1); + } catch (Throwable e) { + e.printStackTrace(); + } finally { + // check interceptors + checkMethodInterceptor(SAY_HELLO_METHOD, 1); + checkConstructorInterceptor(1); + } + } +} + diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest2.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest2.java new file mode 100644 index 0000000000..6cb7204572 --- /dev/null +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest2.java @@ -0,0 +1,50 @@ +/* + * 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.case1; + +import net.bytebuddy.agent.ByteBuddyAgent; +import org.junit.Test; + +import java.lang.instrument.UnmodifiableClassException; + +public class InterceptTest2 extends AbstractInterceptTest { + + @Test + public void test2() throws UnmodifiableClassException { + ByteBuddyAgent.install(); + + // install transformer + installMethodInterceptor(BIZ_FOO_CLASS_NAME, SAY_HELLO_METHOD, 1); + installMethodInterceptor(BIZ_FOO_CLASS_NAME, SAY_HELLO_METHOD, 2); + installConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); + + // load target class + try { + callBizFoo(2); + } catch (Throwable e) { + e.printStackTrace(); + } finally { + // check interceptors + checkMethodInterceptor(SAY_HELLO_METHOD, 1); + checkMethodInterceptor(SAY_HELLO_METHOD, 2); + checkConstructorInterceptor(1); + } + } +} + diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest3.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest3.java new file mode 100644 index 0000000000..3f84bcb02c --- /dev/null +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest3.java @@ -0,0 +1,52 @@ +/* + * 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.case1; + +import net.bytebuddy.agent.ByteBuddyAgent; +import org.junit.Test; + +import java.lang.instrument.UnmodifiableClassException; + +public class InterceptTest3 extends AbstractInterceptTest { + + @Test + public void test3() throws UnmodifiableClassException { + ByteBuddyAgent.install(); + + // install transformer + installMethodInterceptor(BIZ_FOO_CLASS_NAME, SAY_HELLO_METHOD, 1); + installConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); + installMethodInterceptor(BIZ_FOO_CLASS_NAME, SAY_HELLO_METHOD, 2); + + // load target class + try { + callBizFoo(2); + } catch (Throwable e) { + e.printStackTrace(); + } finally { + // check interceptors + checkMethodInterceptor(SAY_HELLO_METHOD, 1); + checkConstructorInterceptor(1); + checkMethodInterceptor(SAY_HELLO_METHOD, 2); + } + + } + +} + diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest4.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest4.java new file mode 100644 index 0000000000..32afab95ab --- /dev/null +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest4.java @@ -0,0 +1,55 @@ +/* + * 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.case1; + +import net.bytebuddy.agent.ByteBuddyAgent; +import org.junit.Test; + +import java.lang.instrument.UnmodifiableClassException; + +public class InterceptTest4 extends AbstractInterceptTest { + + @Test + public void test4() throws UnmodifiableClassException { + ByteBuddyAgent.install(); + + // install transformer + installConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); + installMethodInterceptor(BIZ_FOO_CLASS_NAME, SAY_HELLO_METHOD, 1); + + // load target class + try { + callBizFoo(1); + } catch (Throwable e) { + e.printStackTrace(); + } finally { + // check interceptors + checkConstructorInterceptor(1); + checkMethodInterceptor(SAY_HELLO_METHOD, 1); + } + +// try { +// TimeUnit.DAYS.sleep(1); +// } catch (InterruptedException e) { +// } + + } + +} + diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest5.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest5.java new file mode 100644 index 0000000000..8b177c0d47 --- /dev/null +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest5.java @@ -0,0 +1,52 @@ +/* + * 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.case1; + +import net.bytebuddy.agent.ByteBuddyAgent; +import org.junit.Test; + +import java.lang.instrument.UnmodifiableClassException; + +public class InterceptTest5 extends AbstractInterceptTest { + + @Test + public void test5() throws UnmodifiableClassException { + ByteBuddyAgent.install(); + + // install transformer + installConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); + installMethodInterceptor(BIZ_FOO_CLASS_NAME, SAY_HELLO_METHOD, 1); + installConstructorInterceptor(BIZ_FOO_CLASS_NAME, 2); + installMethodInterceptor(BIZ_FOO_CLASS_NAME, SAY_HELLO_METHOD, 2); + + // load target class + try { + callBizFoo(2); + } catch (Throwable e) { + e.printStackTrace(); + } finally { + // check interceptors + checkConstructorInterceptor(1); + checkMethodInterceptor(SAY_HELLO_METHOD, 1); + checkConstructorInterceptor(2); + checkMethodInterceptor(SAY_HELLO_METHOD, 2); + } + } +} + diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest6.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest6.java new file mode 100644 index 0000000000..e02964821f --- /dev/null +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest6.java @@ -0,0 +1,53 @@ +/* + * 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.case1; + +import net.bytebuddy.agent.ByteBuddyAgent; +import org.junit.Test; + +import java.lang.instrument.UnmodifiableClassException; + +public class InterceptTest6 extends AbstractInterceptTest { + + @Test + public void test6() throws UnmodifiableClassException { + ByteBuddyAgent.install(); + + // install transformer + installMethodInterceptor(BIZ_FOO_CLASS_NAME, SAY_HELLO_METHOD, 1); + installConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); + installMethodInterceptor(BIZ_FOO_CLASS_NAME, SAY_HELLO_METHOD, 2); + installConstructorInterceptor(BIZ_FOO_CLASS_NAME, 2); + + // load target class + try { + callBizFoo(2); + } catch (Throwable e) { + e.printStackTrace(); + } finally { + // check interceptors + checkMethodInterceptor(SAY_HELLO_METHOD, 1); + checkConstructorInterceptor(1); + checkMethodInterceptor(SAY_HELLO_METHOD, 2); + checkConstructorInterceptor(2); + } + } + +} + diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/MultipleInterceptorTest.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/MultipleInterceptorTest.java new file mode 100644 index 0000000000..0add04f56b --- /dev/null +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/MultipleInterceptorTest.java @@ -0,0 +1,106 @@ +/* + * 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.case1; + +import net.bytebuddy.agent.ByteBuddyAgent; +import net.bytebuddy.agent.builder.AgentBuilder; +import org.apache.skywalking.apm.agent.bytebuddy.SWAsmVisitorWrapper; +import net.bytebuddy.implementation.MethodDelegation; +import net.bytebuddy.matcher.ElementMatchers; +import net.bytebuddy.utility.JavaModule; +import org.apache.skywalking.apm.agent.bytebuddy.InstMethodsInter; +import org.apache.skywalking.apm.agent.core.util.FileUtils; +import org.junit.Test; + +import java.io.File; + +public class MultipleInterceptorTest extends AbstractInterceptTest { + + String dumpFolder = "target/class-dump"; + + @Test + public void test1() { + String className = BIZ_FOO_CLASS_NAME; + String methodName = SAY_HELLO_METHOD; + String nameTrait = getNameTrait(1); + + enableClassDump(); + + //newAgentBuilder(nameTrait) + new AgentBuilder.Default() + .type(ElementMatchers.named(className)) + .transform((builder, typeDescription, classLoader, module, protectionDomain) -> { + int round = 1; + String interceptorClassName = METHOD_INTERCEPTOR_CLASS + "$" + methodName + "$" + round; + String fieldName = nameTrait + "_delegate$" + methodName + round; + + if (deleteDuplicatedFields) { + builder = builder.visit(new SWAsmVisitorWrapper()); + } + return builder + .method(ElementMatchers.nameContainsIgnoreCase(methodName)) + .intercept(MethodDelegation.withDefaultConfiguration() + .to(new InstMethodsInter(interceptorClassName, classLoader), fieldName)) + ; + } + ) + .type(ElementMatchers.nameContains(className)) + .transform((builder, typeDescription, classLoader, module, protectionDomain) -> { + int round = 2; + String interceptorClassName = METHOD_INTERCEPTOR_CLASS + "$" + methodName + "$" + round; + String fieldName = nameTrait + "_delegate$" + methodName + round; + + if (deleteDuplicatedFields) { + builder = builder.visit(new SWAsmVisitorWrapper()); + } + return builder + .method(ElementMatchers.nameContainsIgnoreCase(methodName)) + .intercept(MethodDelegation.withDefaultConfiguration() + .to(new InstMethodsInter(interceptorClassName, classLoader), fieldName)) + ; + } + ) + .with(new AgentBuilder.Listener.Adapter() { + @Override + public void onError(String typeName, ClassLoader classLoader, JavaModule module, boolean loaded, Throwable throwable) { + System.err.println(String.format("Transform Error: typeName: %s, classLoader: %s, module: %s, loaded: %s", typeName, classLoader, module, loaded)); + throwable.printStackTrace(); + } + }) + .installOn(ByteBuddyAgent.install()); + + try { + callBizFoo(1); + } catch (Throwable e) { + e.printStackTrace(); + } finally { + // check interceptors +// checkMethodInterceptor(SAY_HELLO_METHOD, 1); +// checkMethodInterceptor(SAY_HELLO_METHOD, 2); + //checkConstructorInterceptor(1); + } + } + + private void enableClassDump() { + System.setProperty("net.bytebuddy.dump", dumpFolder); + File dumpDir = new File(dumpFolder); + FileUtils.deleteDirectory(dumpDir); + dumpDir.mkdirs(); + } +} diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/RetransformTest1.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/RetransformTest1.java new file mode 100644 index 0000000000..4324883d14 --- /dev/null +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/RetransformTest1.java @@ -0,0 +1,80 @@ +/* + * 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.case1; + +import org.apache.skywalking.apm.agent.bytebuddy.Log; +import org.apache.skywalking.apm.agent.bytebuddy.biz.BizFoo; +import net.bytebuddy.agent.ByteBuddyAgent; +import org.apache.skywalking.apm.agent.bytebuddy.biz.ProjectDO; +import org.apache.skywalking.apm.agent.bytebuddy.biz.ProjectService; +import org.junit.Test; + +import java.lang.instrument.Instrumentation; +import java.lang.instrument.UnmodifiableClassException; + +public class RetransformTest1 extends AbstractRetransformTest { + + @Test + public void testInterceptConstructor() throws UnmodifiableClassException { + Instrumentation instrumentation = ByteBuddyAgent.install(); + + // install transformer + installMethodInterceptor(BIZ_FOO_CLASS_NAME, SAY_HELLO_METHOD, 1); + installConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); + // project service + installMethodInterceptor(PROJECT_SERVICE_CLASS_NAME, "add", 1); + installMethodInterceptor(PROJECT_SERVICE_CLASS_NAME, "get", 1); + installMethodInterceptor(PROJECT_SERVICE_CLASS_NAME, "list", 1); + installConstructorInterceptor(PROJECT_SERVICE_CLASS_NAME, 1); + + // call target class + try { + callBizFoo(1); + } catch (Throwable e) { + e.printStackTrace(); + } finally { + // check interceptors + checkMethodInterceptor(SAY_HELLO_METHOD, 1); + checkConstructorInterceptor(1); + } + + ProjectService projectService = new ProjectService(); + projectService.add(ProjectDO.builder() + .name("test") + .id(1) + .build()); + ProjectDO projectDO = projectService.getById(1); + Log.info(projectDO); + projectService.list(); + + // installTraceClassTransformer("Trace class: "); + + // do retransform + reTransform(instrumentation, BizFoo.class); + reTransform(instrumentation, ProjectService.class); + + // test again + callBizFoo(1); + + projectDO = projectService.getById(1); + Log.info(projectDO); + } + +} + diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/RetransformTest2.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/RetransformTest2.java new file mode 100644 index 0000000000..f07bba93a1 --- /dev/null +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/RetransformTest2.java @@ -0,0 +1,87 @@ +/* + * 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.case1; + +import net.bytebuddy.agent.ByteBuddyAgent; +import org.apache.skywalking.apm.agent.bytebuddy.Log; +import org.apache.skywalking.apm.agent.bytebuddy.biz.BizFoo; +import org.junit.Test; + +import java.lang.instrument.Instrumentation; +import java.lang.instrument.UnmodifiableClassException; + +import static org.apache.skywalking.apm.agent.bytebuddy.case1.AbstractRetransformTest.reTransform; + +public class RetransformTest2 extends AbstractInterceptTest { + + @Test + public void testInterceptConstructor() throws UnmodifiableClassException { + Instrumentation instrumentation = ByteBuddyAgent.install(); + + //this.deleteDuplicatedFields = true; + + // install transformer + installMethodInterceptor(BIZ_FOO_CLASS_NAME, SAY_HELLO_METHOD, 1); + installConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); + + // installTraceClassTransformer("Trace class 1: "); + + installConstructorInterceptor(BIZ_FOO_CLASS_NAME, 2); + installMethodInterceptor(BIZ_FOO_CLASS_NAME, SAY_HELLO_METHOD, 2); + installMethodInterceptor(BIZ_FOO_CLASS_NAME, "greeting", 2); + + // installTraceClassTransformer("Trace class 2: "); + + // call target class + try { + callBizFoo(2); + } catch (Throwable e) { + e.printStackTrace(); + } finally { + // check interceptors + Log.info("-------------"); + Log.info("Check interceptors .."); + checkConstructorInterceptor(1); + checkConstructorInterceptor(2); + checkMethodInterceptor(SAY_HELLO_METHOD, 1); + checkMethodInterceptor(SAY_HELLO_METHOD, 2); + } + + // do retransform + reTransform(instrumentation, BizFoo.class); +// reTransform(instrumentation, ProjectService.class); + + // test again + try { + callBizFoo(2); + } catch (Throwable e) { + e.printStackTrace(); + } finally { + // check interceptors + Log.info("-------------"); + Log.info("Check interceptors .."); + checkConstructorInterceptor(1); + checkConstructorInterceptor(2); + checkMethodInterceptor(SAY_HELLO_METHOD, 1); + checkMethodInterceptor(SAY_HELLO_METHOD, 2); + } + } + +} + diff --git a/apm-sniffer/pom.xml b/apm-sniffer/pom.xml index eb0c88aab7..f1057cfc17 100644 --- a/apm-sniffer/pom.xml +++ b/apm-sniffer/pom.xml @@ -37,6 +37,7 @@ bootstrap-plugins optional-plugins optional-reporter-plugins + bytebuddy-patch diff --git a/pom.xml b/pom.xml index baebc37938..d5badbbbcf 100755 --- a/pom.xml +++ b/pom.xml @@ -86,7 +86,7 @@ 1.18.20 - 1.12.19 + 1.14.4 1.50.0 4.1.86.Final 2.8.9 @@ -238,11 +238,15 @@ test + + net.bytebuddy + byte-buddy + ${bytebuddy.version} + net.bytebuddy byte-buddy-agent ${bytebuddy.version} - test org.objenesis @@ -419,7 +423,8 @@ org/apache/skywalking/oap/server/exporter/grpc/*.java, org/apache/skywalking/oap/server/configuration/service/*.java, **/jmh_generated/*_jmhType*.java, - **/jmh_generated/*_jmhTest.java + **/jmh_generated/*_jmhTest.java, + net/bytebuddy/** import.control=${maven.multiModuleProjectDirectory}/apm-checkstyle/importControl.xml From 7b66985b9e85bc43d84dd21c03812305ac7aa134 Mon Sep 17 00:00:00 2001 From: Gong Dewei Date: Fri, 23 Jun 2023 17:08:47 +0800 Subject: [PATCH 02/24] Remove class cache relative codes --- .../skywalking/apm/agent/core/conf/Config.java | 13 ------------- apm-sniffer/config/agent.config | 9 --------- .../service-agent/java-agent/configurations.md | 2 -- .../retransform-class-scenario/bin/startup.sh | 3 --- .../retransform-class-scenario/configuration.yml | 1 + .../configuration.yml | 4 +--- 6 files changed, 2 insertions(+), 30 deletions(-) diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java index 2ff91a6de4..6a694455eb 100755 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java @@ -110,19 +110,6 @@ public static class Agent { */ public static boolean IS_OPEN_DEBUGGING_CLASS = false; - /** - * If true, SkyWalking agent will cache all instrumented classes to memory or disk files (decided by class cache - * mode), allow other javaagent to enhance those classes that enhanced by SkyWalking agent. - */ - public static boolean IS_CACHE_ENHANCED_CLASS = false; - - /** - * The instrumented classes cache mode: MEMORY or FILE MEMORY: cache class bytes to memory, if instrumented - * classes is too many or too large, it may take up more memory FILE: cache class bytes in `/class-cache` - * folder, automatically clean up cached class files when the application exits - */ - public static ClassCacheMode CLASS_CACHE_MODE = ClassCacheMode.MEMORY; - /** * The identifier of the instance */ diff --git a/apm-sniffer/config/agent.config b/apm-sniffer/config/agent.config index 14bf708b83..dea03afe8e 100755 --- a/apm-sniffer/config/agent.config +++ b/apm-sniffer/config/agent.config @@ -46,15 +46,6 @@ agent.ignore_suffix=${SW_AGENT_IGNORE_SUFFIX:.jpg,.jpeg,.js,.css,.png,.bmp,.gif, # SkyWalking team may ask for these files in order to resolve compatible problem. agent.is_open_debugging_class=${SW_AGENT_OPEN_DEBUG:false} -# If true, SkyWalking agent will cache all instrumented classes files to memory or disk files (decided by class cache mode), -# allow other javaagent to enhance those classes that enhanced by SkyWalking agent. -agent.is_cache_enhanced_class=${SW_AGENT_CACHE_CLASS:false} - -# The instrumented classes cache mode: MEMORY or FILE -# MEMORY: cache class bytes to memory, if instrumented classes is too many or too large, it may take up more memory -# FILE: cache class bytes in `/class-cache` folder, automatically clean up cached class files when the application exits -agent.class_cache_mode=${SW_AGENT_CLASS_CACHE_MODE:MEMORY} - # Instance name is the identity of an instance, should be unique in the service. If empty, SkyWalking agent will # generate an 32-bit uuid. BY Default, SkyWalking uses UUID@hostname as the instance name. Max length is 50(UTF-8 char) agent.instance_name=${SW_AGENT_INSTANCE_NAME:} diff --git a/docs/en/setup/service-agent/java-agent/configurations.md b/docs/en/setup/service-agent/java-agent/configurations.md index b55dc4450f..3b3be04338 100644 --- a/docs/en/setup/service-agent/java-agent/configurations.md +++ b/docs/en/setup/service-agent/java-agent/configurations.md @@ -13,8 +13,6 @@ This is the properties list supported in `agent/config/agent.config`. | `agent.span_limit_per_segment` | The max number of spans in a single segment. Through this config item, SkyWalking keep your application memory cost estimated. | SW_AGENT_SPAN_LIMIT | 300 | | `agent.ignore_suffix` | If the operation name of the first span is included in this set, this segment should be ignored. | SW_AGENT_IGNORE_SUFFIX | Not set | | `agent.is_open_debugging_class` | If true, skywalking agent will save all instrumented classes files in `/debugging` folder. SkyWalking team may ask for these files in order to resolve compatible problem. | SW_AGENT_OPEN_DEBUG | Not set | -| `agent.is_cache_enhanced_class` | If true, SkyWalking agent will cache all instrumented classes files to memory or disk files (decided by class cache mode), allow another java agent to enhance those classes that enhanced by SkyWalking agent. To use some Java diagnostic tools (such as BTrace, Arthas) to diagnose applications or add a custom java agent to enhance classes, you need to enable this feature. | SW_AGENT_CACHE_CLASS | `false` | -| `agent.class_cache_mode` | The instrumented classes cache mode: `MEMORY` or `FILE`. `MEMORY`: cache class bytes to memory, if instrumented classes is too many or too large, it may take up more memory. `FILE`: cache class bytes in `/class-cache` folder, automatically clean up cached class files when the application exits. | SW_AGENT_CLASS_CACHE_MODE | `MEMORY` | | `agent.instance_name` | Instance name is the identity of an instance, should be unique in the service. If empty, SkyWalking agent will generate an 32-bit uuid. Default, use `UUID`@`hostname` as the instance name. Max length is 50(UTF-8 char) | SW_AGENT_INSTANCE_NAME | `""` | | `agent.instance_properties_json={"key":"value"}` | Add service instance custom properties in json format. | SW_INSTANCE_PROPERTIES_JSON | Not set | | `agent.cause_exception_depth` | How depth the agent goes, when log all cause exceptions. | SW_AGENT_CAUSE_EXCEPTION_DEPTH | `5` | diff --git a/test/plugin/scenarios/retransform-class-scenario/bin/startup.sh b/test/plugin/scenarios/retransform-class-scenario/bin/startup.sh index b94792e604..423bc894d4 100644 --- a/test/plugin/scenarios/retransform-class-scenario/bin/startup.sh +++ b/test/plugin/scenarios/retransform-class-scenario/bin/startup.sh @@ -18,7 +18,4 @@ home="$(cd "$(dirname $0)"; pwd)" -# enable class cache feature -export agent_opts="$agent_opts -Dskywalking.agent.is_cache_enhanced_class=true -Dskywalking.agent.class_cache_mode=MEMORY" - java -jar ${agent_opts} ${home}/../libs/retransform-class-scenario.jar & \ No newline at end of file diff --git a/test/plugin/scenarios/retransform-class-scenario/configuration.yml b/test/plugin/scenarios/retransform-class-scenario/configuration.yml index ee921e3eb1..b5ea7d85d1 100644 --- a/test/plugin/scenarios/retransform-class-scenario/configuration.yml +++ b/test/plugin/scenarios/retransform-class-scenario/configuration.yml @@ -20,3 +20,4 @@ healthCheck: http://localhost:8080/case/healthCheck startScript: ./bin/startup.sh environment: dependencies: +withPlugins: apm-*.jar diff --git a/test/plugin/scenarios/retransform-class-tomcat-scenario/configuration.yml b/test/plugin/scenarios/retransform-class-tomcat-scenario/configuration.yml index ff2ed8bcd6..1334673771 100644 --- a/test/plugin/scenarios/retransform-class-tomcat-scenario/configuration.yml +++ b/test/plugin/scenarios/retransform-class-tomcat-scenario/configuration.yml @@ -17,7 +17,5 @@ type: tomcat entryService: http://localhost:8080/retransform-class-tomcat-scenario/case/retransform-class healthCheck: http://localhost:8080/retransform-class-tomcat-scenario/case/healthCheck -environment: - - CATALINA_OPTS="-Dskywalking.agent.is_cache_enhanced_class=true -Dskywalking.agent.class_cache_mode=FILE" dependencies: -withPlugins: apm-spring-annotation-plugin-*.jar +withPlugins: apm-*.jar From 6528f3d1cf643bbf5e9bf5445d3d00a0f3c1498f Mon Sep 17 00:00:00 2001 From: Gong Dewei Date: Fri, 23 Jun 2023 17:12:36 +0800 Subject: [PATCH 03/24] Remove class cache relative codes 2 --- .../apm/agent/core/conf/Config.java | 1 - .../CacheableTransformerDecorator.java | 195 ------------------ .../core/plugin/bytebuddy/ClassCacheMode.java | 26 --- 3 files changed, 222 deletions(-) delete mode 100644 apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bytebuddy/CacheableTransformerDecorator.java delete mode 100644 apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bytebuddy/ClassCacheMode.java diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java index 6a694455eb..be7d54a4e4 100755 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java @@ -25,7 +25,6 @@ import org.apache.skywalking.apm.agent.core.logging.core.LogOutput; import org.apache.skywalking.apm.agent.core.logging.core.ResolverType; import org.apache.skywalking.apm.agent.core.logging.core.WriterFactory; -import org.apache.skywalking.apm.agent.core.plugin.bytebuddy.ClassCacheMode; import org.apache.skywalking.apm.util.Length; /** diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bytebuddy/CacheableTransformerDecorator.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bytebuddy/CacheableTransformerDecorator.java deleted file mode 100644 index 2b392512de..0000000000 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bytebuddy/CacheableTransformerDecorator.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * 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.core.plugin.bytebuddy; - -import net.bytebuddy.agent.builder.AgentBuilder; -import net.bytebuddy.agent.builder.ResettableClassFileTransformer; -import net.bytebuddy.utility.RandomString; -import org.apache.skywalking.apm.agent.core.boot.AgentPackageNotFoundException; -import org.apache.skywalking.apm.agent.core.boot.AgentPackagePath; -import org.apache.skywalking.apm.agent.core.logging.api.ILog; -import org.apache.skywalking.apm.agent.core.logging.api.LogManager; -import org.apache.skywalking.apm.agent.core.util.FileUtils; -import org.apache.skywalking.apm.agent.core.util.IOUtils; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.lang.instrument.IllegalClassFormatException; -import java.security.ProtectionDomain; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** - * Wrapper classFileTransformer of ByteBuddy, save the enhanced bytecode to memory cache or file cache, - * and automatically load the previously generated bytecode during the second retransform, - * to solve the problem that ByteBuddy generates auxiliary classes with different random names every time. - * Allow other javaagent to enhance those classes that enhanced by SkyWalking agent. - */ -public class CacheableTransformerDecorator implements AgentBuilder.TransformerDecorator { - - private static final ILog LOGGER = LogManager.getLogger(CacheableTransformerDecorator.class); - - private final ClassCacheMode cacheMode; - private ClassCacheResolver cacheResolver; - - public CacheableTransformerDecorator(ClassCacheMode cacheMode) throws IOException { - this.cacheMode = cacheMode; - initClassCache(); - } - - private void initClassCache() throws IOException { - if (this.cacheMode.equals(ClassCacheMode.FILE)) { - String cacheDirBase = null; - try { - cacheDirBase = AgentPackagePath.getPath() + "/class-cache"; - } catch (AgentPackageNotFoundException e) { - throw new IOException("Can't find the root path for creating /class-cache folder."); - } - File cacheDir = new File(cacheDirBase + "/class-cache-" + RandomString.make()); - if (!cacheDir.exists()) { - cacheDir.mkdirs(); - } - if (!cacheDir.exists()) { - throw new IOException("Create class cache dir failure"); - } - - cacheResolver = new FileCacheResolver(cacheDir); - } else { - cacheResolver = new MemoryCacheResolver(); - } - } - - @Override - public ResettableClassFileTransformer decorate(ResettableClassFileTransformer classFileTransformer) { - return new ResettableClassFileTransformer.WithDelegation(classFileTransformer) { - - @Override - public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { - // load from cache - byte[] classCache = cacheResolver.getClassCache(loader, className); - if (classCache != null) { - return classCache; - } - - //transform class - classfileBuffer = classFileTransformer.transform(loader, className, classBeingRedefined, protectionDomain, classfileBuffer); - - // save to cache - if (classfileBuffer != null) { - cacheResolver.putClassCache(loader, className, classfileBuffer); - } - - return classfileBuffer; - } - }; - } - - private static String getClassLoaderHash(ClassLoader loader) { - String classloader; - if (loader != null) { - classloader = Integer.toHexString(loader.hashCode()); - } else { - //classloader is null for BootstrapClassLoader - classloader = "00000000"; - } - return classloader; - } - - interface ClassCacheResolver { - - byte[] getClassCache(ClassLoader loader, String className); - - void putClassCache(ClassLoader loader, String className, byte[] classfileBuffer); - } - - static class MemoryCacheResolver implements ClassCacheResolver { - // classloaderHashcode@className -> class bytes - private Map classCacheMap = new ConcurrentHashMap(); - - @Override - public byte[] getClassCache(ClassLoader loader, String className) { - String cacheKey = getCacheKey(loader, className); - return classCacheMap.get(cacheKey); - } - - @Override - public void putClassCache(ClassLoader loader, String className, byte[] classfileBuffer) { - String cacheKey = getCacheKey(loader, className); - classCacheMap.put(cacheKey, classfileBuffer); - } - - private String getCacheKey(ClassLoader loader, String className) { - return getClassLoaderHash(loader) + "@" + className; - } - } - - static class FileCacheResolver implements ClassCacheResolver { - - private final File cacheDir; - - FileCacheResolver(File cacheDir) { - this.cacheDir = cacheDir; - - //clean cache dir on exit - FileUtils.deleteDirectoryOnExit(cacheDir); - } - - @Override - public byte[] getClassCache(ClassLoader loader, String className) { - // load from cache - File cacheFile = getCacheFile(loader, className); - if (cacheFile.exists()) { - FileInputStream fileInputStream = null; - try { - fileInputStream = new FileInputStream(cacheFile); - return IOUtils.toByteArray(fileInputStream); - } catch (IOException e) { - LOGGER.error("load class bytes from cache file failure", e); - } finally { - IOUtils.closeQuietly(fileInputStream); - } - } - return null; - } - - @Override - public void putClassCache(ClassLoader loader, String className, byte[] classfileBuffer) { - File cacheFile = getCacheFile(loader, className); - cacheFile.getParentFile().mkdirs(); - FileOutputStream output = null; - try { - output = new FileOutputStream(cacheFile); - IOUtils.copy(new ByteArrayInputStream(classfileBuffer), output); - } catch (IOException e) { - LOGGER.error("save class bytes to cache file failure", e); - } finally { - IOUtils.closeQuietly(output); - } - } - - private File getCacheFile(ClassLoader loader, String className) { - String filename = getClassLoaderHash(loader) + "/" + className.replace('.', '/') + ".class"; - return new File(cacheDir, filename); - } - - } -} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bytebuddy/ClassCacheMode.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bytebuddy/ClassCacheMode.java deleted file mode 100644 index c805c71826..0000000000 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bytebuddy/ClassCacheMode.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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.core.plugin.bytebuddy; - -/** - * ByteBuddy class cache mode - */ -public enum ClassCacheMode { - FILE, MEMORY -} From f57cf0f042741282c71b02e9d8d4e489e1e8aeab Mon Sep 17 00:00:00 2001 From: Gong Dewei Date: Fri, 23 Jun 2023 18:20:20 +0800 Subject: [PATCH 04/24] Compute hashcode of intercept point --- .../bytebuddy/AnnotationTypeNameMatch.java | 7 +++++ .../bytebuddy/ArgumentTypeNameMatch.java | 8 +++++ .../plugin/bytebuddy/ReturnTypeNameMatch.java | 7 +++++ .../enhance/ClassEnhancePluginDefine.java | 15 ++-------- .../enhance/DelegateNamingResolver.java | 30 ++++++++++++++++++- .../v2/ClassEnhancePluginDefineV2.java | 16 ++-------- 6 files changed, 57 insertions(+), 26 deletions(-) diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bytebuddy/AnnotationTypeNameMatch.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bytebuddy/AnnotationTypeNameMatch.java index fe13541e93..f5aa7aacc3 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bytebuddy/AnnotationTypeNameMatch.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bytebuddy/AnnotationTypeNameMatch.java @@ -55,6 +55,13 @@ public boolean matches(T target) { return target.getAnnotationType().asErasure().getName().equals(annotationTypeName); } + @Override + public String toString() { + return "AnnotationTypeNameMatch{" + + "annotationTypeName='" + annotationTypeName + '\'' + + '}'; + } + /** * The static method to create {@link AnnotationTypeNameMatch} This is a delegate method to follow byte-buddy {@link * ElementMatcher}'s code style. diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bytebuddy/ArgumentTypeNameMatch.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bytebuddy/ArgumentTypeNameMatch.java index 2dae176409..60ee56d490 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bytebuddy/ArgumentTypeNameMatch.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bytebuddy/ArgumentTypeNameMatch.java @@ -68,6 +68,14 @@ public boolean matches(MethodDescription target) { return false; } + @Override + public String toString() { + return "ArgumentTypeNameMatch{" + + "index=" + index + + ", argumentTypeName='" + argumentTypeName + '\'' + + '}'; + } + /** * The static method to create {@link ArgumentTypeNameMatch} This is a delegate method to follow byte-buddy {@link * ElementMatcher}'s code style. diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bytebuddy/ReturnTypeNameMatch.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bytebuddy/ReturnTypeNameMatch.java index 290542b777..238e06a81f 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bytebuddy/ReturnTypeNameMatch.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bytebuddy/ReturnTypeNameMatch.java @@ -53,6 +53,13 @@ public boolean matches(MethodDescription target) { return target.getReturnType().asErasure().getName().equals(returnTypeName); } + @Override + public String toString() { + return "ReturnTypeNameMatch{" + + "returnTypeName='" + returnTypeName + '\'' + + '}'; + } + /** * The static method to create {@link ReturnTypeNameMatch} This is a delegate method to follow byte-buddy {@link * ElementMatcher}'s code style. diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/ClassEnhancePluginDefine.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/ClassEnhancePluginDefine.java index 8f4ca771a0..af93e4593c 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/ClassEnhancePluginDefine.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/ClassEnhancePluginDefine.java @@ -55,9 +55,6 @@ */ public abstract class ClassEnhancePluginDefine extends AbstractClassEnhancePluginDefine { private static final ILog LOGGER = LogManager.getLogger(ClassEnhancePluginDefine.class); - private ConstructorInterceptPoint[] constructorInterceptPoints; - private InstanceMethodsInterceptPoint[] instanceMethodsInterceptPoints; - private StaticMethodsInterceptPoint[] staticMethodsInterceptPoints; /** * Enhance a class to intercept constructors and class instance methods. @@ -70,12 +67,8 @@ public abstract class ClassEnhancePluginDefine extends AbstractClassEnhancePlugi protected DynamicType.Builder enhanceInstance(TypeDescription typeDescription, DynamicType.Builder newClassBuilder, ClassLoader classLoader, EnhanceContext context) throws PluginException { - if (constructorInterceptPoints == null) { - constructorInterceptPoints = getConstructorsInterceptPoints(); - } - if (instanceMethodsInterceptPoints == null) { - instanceMethodsInterceptPoints = getInstanceMethodsInterceptPoints(); - } + ConstructorInterceptPoint[] constructorInterceptPoints = getConstructorsInterceptPoints(); + InstanceMethodsInterceptPoint[] instanceMethodsInterceptPoints = getInstanceMethodsInterceptPoints(); String enhanceOriginClassName = typeDescription.getTypeName(); boolean existedConstructorInterceptPoint = false; if (constructorInterceptPoints != null && constructorInterceptPoints.length > 0) { @@ -186,10 +179,8 @@ protected DynamicType.Builder enhanceInstance(TypeDescription typeDescription @Override protected DynamicType.Builder enhanceClass(TypeDescription typeDescription, DynamicType.Builder newClassBuilder, ClassLoader classLoader) throws PluginException { + StaticMethodsInterceptPoint[] staticMethodsInterceptPoints = getStaticMethodsInterceptPoints(); String enhanceOriginClassName = typeDescription.getTypeName(); - if (staticMethodsInterceptPoints == null) { - staticMethodsInterceptPoints = getStaticMethodsInterceptPoints(); - } if (staticMethodsInterceptPoints == null || staticMethodsInterceptPoints.length == 0) { return newClassBuilder; } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java index 35fc9dece3..a02cf303ac 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java @@ -20,6 +20,11 @@ import net.bytebuddy.utility.RandomString; import org.apache.skywalking.apm.agent.core.plugin.AbstractClassEnhancePluginDefine; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.StaticMethodsInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.v2.InstanceMethodsInterceptV2Point; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.v2.StaticMethodsInterceptV2Point; import java.util.Objects; @@ -40,12 +45,35 @@ public static void setNameTrait(String nameTrait) { public DelegateNamingResolver(String className, int identifier) { this.className = className; this.identifier = identifier; + // delegate field name pattern: $delegate$$$ + // something like: InstMethodsInter sw$delegate$td03673$sib0lj0$5n874b1; this.fieldNamePrefix = NAME_TRAIT + PREFIX + RandomString.hashOf(className.hashCode()) + "$" + RandomString.hashOf(identifier) + "$"; } public String resolve(Object interceptPoint) { Objects.requireNonNull(interceptPoint, "interceptPoint cannot be null"); - return fieldNamePrefix + RandomString.hashOf(interceptPoint.hashCode()); + return fieldNamePrefix + RandomString.hashOf(computeHashCode(interceptPoint)); + } + + private int computeHashCode(Object interceptPoint) { + String interceptPointClassName = interceptPoint.getClass().getName(); + if (interceptPoint instanceof ConstructorInterceptPoint) { + ConstructorInterceptPoint point = (ConstructorInterceptPoint) interceptPoint; + return Objects.hash(interceptPointClassName, point.getConstructorMatcher().toString(), point.getConstructorInterceptor()); + } else if (interceptPoint instanceof InstanceMethodsInterceptPoint) { + InstanceMethodsInterceptPoint point = (InstanceMethodsInterceptPoint) interceptPoint; + return Objects.hash(interceptPointClassName, point.getMethodsMatcher().toString(), point.getMethodsInterceptor(), point.isOverrideArgs()); + } else if (interceptPoint instanceof InstanceMethodsInterceptV2Point) { + InstanceMethodsInterceptV2Point point = (InstanceMethodsInterceptV2Point) interceptPoint; + return Objects.hash(interceptPointClassName, point.getMethodsMatcher().toString(), point.getMethodsInterceptorV2(), point.isOverrideArgs()); + } else if (interceptPoint instanceof StaticMethodsInterceptPoint) { + StaticMethodsInterceptPoint point = (StaticMethodsInterceptPoint) interceptPoint; + return Objects.hash(interceptPointClassName, point.getMethodsMatcher().toString(), point.getMethodsInterceptor(), point.isOverrideArgs()); + } else if (interceptPoint instanceof StaticMethodsInterceptV2Point) { + StaticMethodsInterceptV2Point point = (StaticMethodsInterceptV2Point) interceptPoint; + return Objects.hash(interceptPointClassName, point.getMethodsMatcher().toString(), point.getMethodsInterceptorV2(), point.isOverrideArgs()); + } + return interceptPoint.hashCode(); } public static DelegateNamingResolver get(String className, AbstractClassEnhancePluginDefine pluginDefine) { diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/v2/ClassEnhancePluginDefineV2.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/v2/ClassEnhancePluginDefineV2.java index bbae79d0a5..277699b3d1 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/v2/ClassEnhancePluginDefineV2.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/v2/ClassEnhancePluginDefineV2.java @@ -57,18 +57,12 @@ */ public abstract class ClassEnhancePluginDefineV2 extends AbstractClassEnhancePluginDefine { - private ConstructorInterceptPoint[] constructorInterceptPoints; - private InstanceMethodsInterceptV2Point[] instanceMethodsInterceptV2Points; - private StaticMethodsInterceptV2Point[] staticMethodsInterceptV2Points; - @Override protected DynamicType.Builder enhanceClass(TypeDescription typeDescription, DynamicType.Builder newClassBuilder, ClassLoader classLoader) throws PluginException { + StaticMethodsInterceptV2Point[] staticMethodsInterceptV2Points = getStaticMethodsInterceptV2Points(); String enhanceOriginClassName = typeDescription.getTypeName(); - if (staticMethodsInterceptV2Points == null) { - staticMethodsInterceptV2Points = getStaticMethodsInterceptV2Points(); - } if (staticMethodsInterceptV2Points == null || staticMethodsInterceptV2Points.length == 0) { return newClassBuilder; } @@ -118,12 +112,8 @@ protected DynamicType.Builder enhanceClass(TypeDescription typeDescription, protected DynamicType.Builder enhanceInstance(TypeDescription typeDescription, DynamicType.Builder newClassBuilder, ClassLoader classLoader, EnhanceContext context) throws PluginException { - if (constructorInterceptPoints == null) { - constructorInterceptPoints = getConstructorsInterceptPoints(); - } - if (instanceMethodsInterceptV2Points == null) { - instanceMethodsInterceptV2Points = getInstanceMethodsInterceptV2Points(); - } + ConstructorInterceptPoint[] constructorInterceptPoints = getConstructorsInterceptPoints(); + InstanceMethodsInterceptV2Point[] instanceMethodsInterceptV2Points = getInstanceMethodsInterceptV2Points(); String enhanceOriginClassName = typeDescription.getTypeName(); DelegateNamingResolver fieldNamingResolver = DelegateNamingResolver.get(typeDescription.getTypeName(), this); From 66b0e41b990d133d02b5f98d224b17113ae0c4bb Mon Sep 17 00:00:00 2001 From: Gong Dewei Date: Fri, 23 Jun 2023 18:39:46 +0800 Subject: [PATCH 05/24] polish test --- apm-sniffer/bytebuddy-patch/pom.xml | 21 ------- .../case1/AbstractInterceptTest.java | 59 +++++++------------ ...nterceptTest1.java => Intercept1Test.java} | 2 +- ...nterceptTest2.java => Intercept2Test.java} | 2 +- ...nterceptTest3.java => Intercept3Test.java} | 2 +- ...nterceptTest4.java => Intercept4Test.java} | 2 +- ...nterceptTest5.java => Intercept5Test.java} | 2 +- ...nterceptTest6.java => Intercept6Test.java} | 2 +- ...nsformTest1.java => Retransform1Test.java} | 2 +- ...nsformTest2.java => Retransform2Test.java} | 2 +- 10 files changed, 29 insertions(+), 67 deletions(-) rename apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/{InterceptTest1.java => Intercept1Test.java} (96%) rename apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/{InterceptTest2.java => Intercept2Test.java} (96%) rename apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/{InterceptTest3.java => Intercept3Test.java} (96%) rename apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/{InterceptTest4.java => Intercept4Test.java} (96%) rename apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/{InterceptTest5.java => Intercept5Test.java} (96%) rename apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/{InterceptTest6.java => Intercept6Test.java} (96%) rename apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/{RetransformTest1.java => Retransform1Test.java} (97%) rename apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/{RetransformTest2.java => Retransform2Test.java} (98%) diff --git a/apm-sniffer/bytebuddy-patch/pom.xml b/apm-sniffer/bytebuddy-patch/pom.xml index 76ea2effb0..9d3ef6dac8 100644 --- a/apm-sniffer/bytebuddy-patch/pom.xml +++ b/apm-sniffer/bytebuddy-patch/pom.xml @@ -29,11 +29,6 @@ bytebuddy-patch - - 8 - 8 - - org.apache.skywalking @@ -71,20 +66,4 @@ - - - - org.apache.maven.plugins - maven-surefire-plugin - - - **/*Test*.java - - - **/Abstract*.java - - - - - \ No newline at end of file diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/AbstractInterceptTest.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/AbstractInterceptTest.java index 1ceb750de4..5cbb7e9f01 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/AbstractInterceptTest.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/AbstractInterceptTest.java @@ -22,11 +22,9 @@ import net.bytebuddy.agent.ByteBuddyAgent; import net.bytebuddy.agent.builder.AgentBuilder; import net.bytebuddy.agent.builder.SWAgentBuilderDefault; -import org.apache.skywalking.apm.agent.bytebuddy.SWAsmVisitorWrapper; import net.bytebuddy.agent.builder.SWNativeMethodStrategy; import net.bytebuddy.asm.Advice; import net.bytebuddy.implementation.MethodDelegation; -import org.apache.skywalking.apm.agent.bytebuddy.SWAuxiliaryTypeNamingStrategy; import net.bytebuddy.implementation.SWImplementationContextFactory; import net.bytebuddy.implementation.SuperMethodCall; import net.bytebuddy.matcher.ElementMatchers; @@ -37,6 +35,8 @@ import org.apache.skywalking.apm.agent.bytebuddy.InstMethodAdvice; import org.apache.skywalking.apm.agent.bytebuddy.InstMethodsInter; import org.apache.skywalking.apm.agent.bytebuddy.Log; +import org.apache.skywalking.apm.agent.bytebuddy.SWAsmVisitorWrapper; +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.junit.Assert; @@ -92,7 +92,6 @@ protected static void checkConstructorInterceptor(int round) { protected void installMethodInterceptor(String className, String methodName, int round) { this.installMethodInterceptor1(className, methodName, round); -// this.installMethodInterceptor2(className, methodName, round); } protected void installMethodInterceptor1(String className, String methodName, int round) { @@ -112,13 +111,7 @@ protected void installMethodInterceptor1(String className, String methodName, in ; } ) - .with(new AgentBuilder.Listener.Adapter() { - @Override - public void onError(String typeName, ClassLoader classLoader, JavaModule module, boolean loaded, Throwable throwable) { - System.err.println(String.format("Transform Error: interceptorClassName: %s, typeName: %s, classLoader: %s, module: %s, loaded: %s", interceptorClassName, typeName, classLoader, module, loaded)); - throwable.printStackTrace(); - } - }) + .with(getListener(interceptorClassName)) .installOn(ByteBuddyAgent.install()); } @@ -138,19 +131,12 @@ protected void installMethodInterceptor2(String className, String methodName, in .intercept(Advice.to(InstMethodAdvice.class)); } ) - .with(new AgentBuilder.Listener.Adapter() { - @Override - public void onError(String typeName, ClassLoader classLoader, JavaModule module, boolean loaded, Throwable throwable) { - System.err.println(String.format("Transform Error: interceptorClassName: %s, typeName: %s, classLoader: %s, module: %s, loaded: %s", interceptorClassName, typeName, classLoader, module, loaded)); - throwable.printStackTrace(); - } - }) + .with(getListener(interceptorClassName)) .installOn(ByteBuddyAgent.install()); } protected void installConstructorInterceptor(String className, int round) { installConstructorInterceptor1(className, round); -// installConstructorInterceptor2(className, round); } protected void installConstructorInterceptor1(String className, int round) { @@ -172,13 +158,7 @@ protected void installConstructorInterceptor1(String className, int round) { )); } ) - .with(new AgentBuilder.Listener.Adapter() { - @Override - public void onError(String typeName, ClassLoader classLoader, JavaModule module, boolean loaded, Throwable throwable) { - System.err.println(String.format("Transform Error: interceptorClass:%s, typeName: %s, classLoader: %s, module: %s, loaded: %s", interceptorClassName, typeName, classLoader, module, loaded)); - throwable.printStackTrace(); - } - }) + .with(getListener(interceptorClassName)) .installOn(ByteBuddyAgent.install()); } @@ -198,13 +178,7 @@ protected void installConstructorInterceptor2(String className, int round) { .intercept(Advice.to(ConstructorAdvice.class)); } ) - .with(new AgentBuilder.Listener.Adapter() { - @Override - public void onError(String typeName, ClassLoader classLoader, JavaModule module, boolean loaded, Throwable throwable) { - System.err.println(String.format("Transform Error: interceptorClass:%s, typeName: %s, classLoader: %s, module: %s, loaded: %s", interceptorClassName, typeName, classLoader, module, loaded)); - throwable.printStackTrace(); - } - }) + .with(getListener(interceptorClassName)) .installOn(ByteBuddyAgent.install()); } @@ -215,8 +189,7 @@ protected String getNameTrait(int round) { protected AgentBuilder newAgentBuilder(String nameTrait) { ByteBuddy byteBuddy = new ByteBuddy() .with(new SWAuxiliaryTypeNamingStrategy(nameTrait)) - .with(new SWImplementationContextFactory(nameTrait)) - ; + .with(new SWImplementationContextFactory(nameTrait)); return new SWAgentBuilderDefault(byteBuddy, new SWNativeMethodStrategy(nameTrait)) .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION) @@ -224,10 +197,6 @@ protected AgentBuilder newAgentBuilder(String nameTrait) { .with(new SWClassFileLocator(ByteBuddyAgent.install(), getClassLoader())); } - private static ClassLoader getClassLoader() { - return AbstractInterceptTest.class.getClassLoader(); - } - protected void installTraceClassTransformer(String msg) { ClassFileTransformer classFileTransformer = new ClassFileTransformer() { @Override @@ -244,4 +213,18 @@ public byte[] transform(ClassLoader loader, String className, Class classBein }; ByteBuddyAgent.install().addTransformer(classFileTransformer, true); } + + private static ClassLoader getClassLoader() { + return AbstractInterceptTest.class.getClassLoader(); + } + + private static AgentBuilder.Listener.Adapter getListener(String interceptorClassName) { + return new AgentBuilder.Listener.Adapter() { + @Override + public void onError(String typeName, ClassLoader classLoader, JavaModule module, boolean loaded, Throwable throwable) { + System.err.println(String.format("Transform Error: interceptorClassName: %s, typeName: %s, classLoader: %s, module: %s, loaded: %s", interceptorClassName, typeName, classLoader, module, loaded)); + throwable.printStackTrace(); + } + }; + } } diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest1.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept1Test.java similarity index 96% rename from apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest1.java rename to apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept1Test.java index 7e00b32887..e1fbddb0ae 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest1.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept1Test.java @@ -23,7 +23,7 @@ import java.lang.instrument.UnmodifiableClassException; -public class InterceptTest1 extends AbstractInterceptTest { +public class Intercept1Test extends AbstractInterceptTest { @Test public void test1() throws UnmodifiableClassException { diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest2.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept2Test.java similarity index 96% rename from apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest2.java rename to apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept2Test.java index 6cb7204572..80f4a1539c 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest2.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept2Test.java @@ -23,7 +23,7 @@ import java.lang.instrument.UnmodifiableClassException; -public class InterceptTest2 extends AbstractInterceptTest { +public class Intercept2Test extends AbstractInterceptTest { @Test public void test2() throws UnmodifiableClassException { diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest3.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept3Test.java similarity index 96% rename from apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest3.java rename to apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept3Test.java index 3f84bcb02c..13be513007 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest3.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept3Test.java @@ -23,7 +23,7 @@ import java.lang.instrument.UnmodifiableClassException; -public class InterceptTest3 extends AbstractInterceptTest { +public class Intercept3Test extends AbstractInterceptTest { @Test public void test3() throws UnmodifiableClassException { diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest4.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept4Test.java similarity index 96% rename from apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest4.java rename to apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept4Test.java index 32afab95ab..cb04ef4b13 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest4.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept4Test.java @@ -23,7 +23,7 @@ import java.lang.instrument.UnmodifiableClassException; -public class InterceptTest4 extends AbstractInterceptTest { +public class Intercept4Test extends AbstractInterceptTest { @Test public void test4() throws UnmodifiableClassException { diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest5.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept5Test.java similarity index 96% rename from apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest5.java rename to apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept5Test.java index 8b177c0d47..c77b3fcd03 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest5.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept5Test.java @@ -23,7 +23,7 @@ import java.lang.instrument.UnmodifiableClassException; -public class InterceptTest5 extends AbstractInterceptTest { +public class Intercept5Test extends AbstractInterceptTest { @Test public void test5() throws UnmodifiableClassException { diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest6.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept6Test.java similarity index 96% rename from apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest6.java rename to apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept6Test.java index e02964821f..6bbf51a61f 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/InterceptTest6.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept6Test.java @@ -23,7 +23,7 @@ import java.lang.instrument.UnmodifiableClassException; -public class InterceptTest6 extends AbstractInterceptTest { +public class Intercept6Test extends AbstractInterceptTest { @Test public void test6() throws UnmodifiableClassException { diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/RetransformTest1.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Retransform1Test.java similarity index 97% rename from apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/RetransformTest1.java rename to apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Retransform1Test.java index 4324883d14..c59765b462 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/RetransformTest1.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Retransform1Test.java @@ -28,7 +28,7 @@ import java.lang.instrument.Instrumentation; import java.lang.instrument.UnmodifiableClassException; -public class RetransformTest1 extends AbstractRetransformTest { +public class Retransform1Test extends AbstractRetransformTest { @Test public void testInterceptConstructor() throws UnmodifiableClassException { diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/RetransformTest2.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Retransform2Test.java similarity index 98% rename from apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/RetransformTest2.java rename to apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Retransform2Test.java index f07bba93a1..081cf33601 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/RetransformTest2.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Retransform2Test.java @@ -28,7 +28,7 @@ import static org.apache.skywalking.apm.agent.bytebuddy.case1.AbstractRetransformTest.reTransform; -public class RetransformTest2 extends AbstractInterceptTest { +public class Retransform2Test extends AbstractInterceptTest { @Test public void testInterceptConstructor() throws UnmodifiableClassException { From 7c3499c16bc9db1e2a43aa9e8012c6abf86423c0 Mon Sep 17 00:00:00 2001 From: Gong Dewei Date: Fri, 23 Jun 2023 19:00:18 +0800 Subject: [PATCH 06/24] polish code --- .../skywalking/apm/agent/bytebuddy/SWClassFileLocator.java | 7 +------ .../agent/bytebuddy/SWExtractionClassFileTransformer.java | 5 ----- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWClassFileLocator.java b/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWClassFileLocator.java index 22bc502255..80ffaafc5f 100644 --- a/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWClassFileLocator.java +++ b/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWClassFileLocator.java @@ -30,7 +30,7 @@ import java.util.concurrent.TimeUnit; /** - * Resolve auxiliary type + * Resolve auxiliary type from Instrumentation.getAllLoadedClasses() */ public class SWClassFileLocator implements ClassFileLocator { private static ILog LOGGER = LogManager.getLogger(SWClassFileLocator.class); @@ -44,11 +44,6 @@ public class SWClassFileLocator implements ClassFileLocator { private int timeoutSeconds = 2; private volatile boolean closed; - public SWClassFileLocator(Instrumentation instrumentation, ClassLoader classLoader, String[] typeNameTraits) { - this(instrumentation, classLoader); - this.typeNameTraits = typeNameTraits; - } - public SWClassFileLocator(Instrumentation instrumentation, ClassLoader classLoader) { this.instrumentation = instrumentation; this.classLoader = classLoader; diff --git a/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWExtractionClassFileTransformer.java b/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWExtractionClassFileTransformer.java index 7466be2ebc..89c1108ce1 100644 --- a/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWExtractionClassFileTransformer.java +++ b/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWExtractionClassFileTransformer.java @@ -28,11 +28,6 @@ public class SWExtractionClassFileTransformer implements ClassFileTransformer { */ private static final byte[] DO_NOT_TRANSFORM = null; -// /** -// * The class loader that is expected to have loaded the looked-up a class. -// */ -// private final ClassLoader classLoader; - /** * The name of the type to look up. */ From ea829da05c845c607f4031d0f78c456991cbd688 Mon Sep 17 00:00:00 2001 From: Gong Dewei Date: Fri, 23 Jun 2023 19:03:38 +0800 Subject: [PATCH 07/24] polish code --- .../agent/bytebuddy/case1/AbstractInterceptTest.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/AbstractInterceptTest.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/AbstractInterceptTest.java index 5cbb7e9f01..d1be512e6b 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/AbstractInterceptTest.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/AbstractInterceptTest.java @@ -91,10 +91,10 @@ protected static void checkConstructorInterceptor(int round) { } protected void installMethodInterceptor(String className, String methodName, int round) { - this.installMethodInterceptor1(className, methodName, round); + this.installMethodInterceptorWithMethodDelegation(className, methodName, round); } - protected void installMethodInterceptor1(String className, String methodName, int round) { + protected void installMethodInterceptorWithMethodDelegation(String className, String methodName, int round) { String interceptorClassName = METHOD_INTERCEPTOR_CLASS + "$" + methodName + "$" + round; String nameTrait = getNameTrait(round); String fieldName = nameTrait + "_delegate$" + methodName + round; @@ -115,7 +115,7 @@ protected void installMethodInterceptor1(String className, String methodName, in .installOn(ByteBuddyAgent.install()); } - protected void installMethodInterceptor2(String className, String methodName, int round) { + protected void installMethodInterceptorWithAdvice(String className, String methodName, int round) { String interceptorClassName = METHOD_INTERCEPTOR_CLASS + "$" + methodName + "$" + round; String nameTrait = getNameTrait(round); String fieldName = nameTrait + "_delegate$" + methodName + round; @@ -136,10 +136,10 @@ protected void installMethodInterceptor2(String className, String methodName, in } protected void installConstructorInterceptor(String className, int round) { - installConstructorInterceptor1(className, round); + installConstructorInterceptorWithMethodDelegation(className, round); } - protected void installConstructorInterceptor1(String className, int round) { + protected void installConstructorInterceptorWithMethodDelegation(String className, int round) { String interceptorClassName = CONSTRUCTOR_INTERCEPTOR_CLASS + "$" + round; String nameTrait = getNameTrait(round); String fieldName = nameTrait + "_delegate$constructor" + round; @@ -162,7 +162,7 @@ protected void installConstructorInterceptor1(String className, int round) { .installOn(ByteBuddyAgent.install()); } - protected void installConstructorInterceptor2(String className, int round) { + protected void installConstructorInterceptorWithAdvice(String className, int round) { String interceptorClassName = CONSTRUCTOR_INTERCEPTOR_CLASS + "$" + round; String nameTrait = getNameTrait(round); String fieldName = nameTrait + "_delegate$constructor" + round; From 1d4baebd459bddd90e651193b13df4ec6c2e83df Mon Sep 17 00:00:00 2001 From: Gong Dewei Date: Fri, 23 Jun 2023 19:48:04 +0800 Subject: [PATCH 08/24] polish comments --- .../plugin/interceptor/enhance/DelegateNamingResolver.java | 2 +- .../bytebuddy/agent/builder/SWNativeMethodStrategy.java | 7 +++---- .../implementation/SWImplementationContextFactory.java | 2 ++ .../apm/agent/bytebuddy/SWAuxiliaryTypeNamingStrategy.java | 3 ++- .../apm/agent/bytebuddy/SWMethodNameTransformer.java | 5 +++-- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java index a02cf303ac..c7d2740da1 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java @@ -45,7 +45,7 @@ public static void setNameTrait(String nameTrait) { public DelegateNamingResolver(String className, int identifier) { this.className = className; this.identifier = identifier; - // delegate field name pattern: $delegate$$$ + // Interceptor delegate field name pattern: $delegate$$$ // something like: InstMethodsInter sw$delegate$td03673$sib0lj0$5n874b1; this.fieldNamePrefix = NAME_TRAIT + PREFIX + RandomString.hashOf(className.hashCode()) + "$" + RandomString.hashOf(identifier) + "$"; } diff --git a/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWNativeMethodStrategy.java b/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWNativeMethodStrategy.java index eccbe0fc41..219ae11f0a 100644 --- a/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWNativeMethodStrategy.java +++ b/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWNativeMethodStrategy.java @@ -25,17 +25,16 @@ import java.lang.instrument.Instrumentation; public class SWNativeMethodStrategy implements AgentBuilder.Default.NativeMethodStrategy { - private static final String DEFAULT_PREFIX = "origin$"; - private String prefix; + private String nameTrait; public SWNativeMethodStrategy(String nameTrait) { - this.prefix = nameTrait + DEFAULT_PREFIX; + this.nameTrait = nameTrait; } @Override public MethodNameTransformer resolve() { - return new SWMethodNameTransformer(prefix); + return new SWMethodNameTransformer(nameTrait); } @Override diff --git a/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/implementation/SWImplementationContextFactory.java b/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/implementation/SWImplementationContextFactory.java index f1aac5cb6e..3200da417f 100644 --- a/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/implementation/SWImplementationContextFactory.java +++ b/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/implementation/SWImplementationContextFactory.java @@ -52,6 +52,8 @@ public Implementation.Context.ExtractableView make(TypeDescription instrumentedT ClassFileVersion classFileVersion, ClassFileVersion auxiliaryClassFileVersion, Implementation.Context.FrameGeneration frameGeneration) { + // Method cache value field pattern: cachedValue$$$ + // Accessor method name pattern: $accessor$$ return new Implementation.Context.Default(instrumentedType, classFileVersion, auxiliaryTypeNamingStrategy, typeInitializer, auxiliaryClassFileVersion, frameGeneration, suffixNameTrait + RandomString.hashOf(instrumentedType.getName().hashCode())); diff --git a/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWAuxiliaryTypeNamingStrategy.java b/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWAuxiliaryTypeNamingStrategy.java index ac2b802eb4..b2756aef62 100644 --- a/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWAuxiliaryTypeNamingStrategy.java +++ b/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWAuxiliaryTypeNamingStrategy.java @@ -23,7 +23,7 @@ import net.bytebuddy.utility.RandomString; /** - * Generate predicated auxiliary type name for delegate method + * Generate predicated auxiliary type name for delegate method. */ public class SWAuxiliaryTypeNamingStrategy implements AuxiliaryType.NamingStrategy { private static final String DEFAULT_SUFFIX = "auxiliary$"; @@ -35,6 +35,7 @@ public SWAuxiliaryTypeNamingStrategy(String nameTrait) { @Override public String name(TypeDescription instrumentedType, AuxiliaryType auxiliaryType) { + // Auxiliary type name pattern: $$auxiliary$ return instrumentedType.getName() + "$" + suffix + RandomString.hashOf(auxiliaryType.hashCode()); } diff --git a/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWMethodNameTransformer.java b/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWMethodNameTransformer.java index 47441b6f4e..e70315d27f 100644 --- a/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWMethodNameTransformer.java +++ b/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWMethodNameTransformer.java @@ -35,12 +35,13 @@ public SWMethodNameTransformer() { this(DEFAULT_PREFIX); } - public SWMethodNameTransformer(String prefix) { - this.prefix = prefix; + public SWMethodNameTransformer(String nameTrait) { + this.prefix = nameTrait + DEFAULT_PREFIX; } @Override public String transform(MethodDescription methodDescription) { + // Origin method rename pattern: $original$$ return prefix + methodDescription.getInternalName() + "$" + RandomString.hashOf(methodDescription.toString().hashCode()); } From 461ae3086607e86384d27c081a8cc0cc19279f6b Mon Sep 17 00:00:00 2001 From: Gong Dewei Date: Fri, 23 Jun 2023 20:32:25 +0800 Subject: [PATCH 09/24] move unused class --- .../skywalking/apm/agent/bytebuddy/SWAsmVisitorWrapper.java | 0 .../skywalking/apm/agent/bytebuddy/SWClassFileLocator.java | 3 ++- .../apm/agent/bytebuddy/SWExtractionClassFileTransformer.java | 0 3 files changed, 2 insertions(+), 1 deletion(-) rename apm-sniffer/bytebuddy-patch/src/{main => test}/java/org/apache/skywalking/apm/agent/bytebuddy/SWAsmVisitorWrapper.java (100%) rename apm-sniffer/bytebuddy-patch/src/{main => test}/java/org/apache/skywalking/apm/agent/bytebuddy/SWClassFileLocator.java (97%) rename apm-sniffer/bytebuddy-patch/src/{main => test}/java/org/apache/skywalking/apm/agent/bytebuddy/SWExtractionClassFileTransformer.java (100%) diff --git a/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWAsmVisitorWrapper.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/SWAsmVisitorWrapper.java similarity index 100% rename from apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWAsmVisitorWrapper.java rename to apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/SWAsmVisitorWrapper.java diff --git a/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWClassFileLocator.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/SWClassFileLocator.java similarity index 97% rename from apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWClassFileLocator.java rename to apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/SWClassFileLocator.java index 80ffaafc5f..2d3c679ec9 100644 --- a/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWClassFileLocator.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/SWClassFileLocator.java @@ -30,7 +30,8 @@ import java.util.concurrent.TimeUnit; /** - * Resolve auxiliary type from Instrumentation.getAllLoadedClasses() + * Resolve auxiliary type from Instrumentation.getAllLoadedClasses(). + * Get class bytecode from separate thread to bypass jdk limitation or bug: https://github.com/raphw/byte-buddy/issues/1434 */ public class SWClassFileLocator implements ClassFileLocator { private static ILog LOGGER = LogManager.getLogger(SWClassFileLocator.class); diff --git a/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWExtractionClassFileTransformer.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/SWExtractionClassFileTransformer.java similarity index 100% rename from apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWExtractionClassFileTransformer.java rename to apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/SWExtractionClassFileTransformer.java From 988ffe41879fa528c852ae854ce97a0c9d58b09b Mon Sep 17 00:00:00 2001 From: Gong Dewei Date: Fri, 23 Jun 2023 22:30:13 +0800 Subject: [PATCH 10/24] move name trait to Constants --- .../apm/agent/core/conf/Constants.java | 6 +++++ .../enhance/DelegateNamingResolver.java | 8 ++---- .../skywalking/apm/agent/SkyWalkingAgent.java | 26 +++++++++---------- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Constants.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Constants.java index 0fd98f0c16..ae6095a06c 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Constants.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Constants.java @@ -32,4 +32,10 @@ public class Constants { public static String EVENT_LAYER_NAME = "GENERAL"; public static int NULL_VALUE = 0; + + /** + * The name trait for auxiliary type names, field names and method names which generated by ByteBuddy. + */ + public static final String NAME_TRAIT = "sw$"; + } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java index c7d2740da1..1076b80e05 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java @@ -19,6 +19,7 @@ package org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance; import net.bytebuddy.utility.RandomString; +import org.apache.skywalking.apm.agent.core.conf.Constants; import org.apache.skywalking.apm.agent.core.plugin.AbstractClassEnhancePluginDefine; import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; @@ -33,21 +34,16 @@ */ public class DelegateNamingResolver { private static final String PREFIX = "delegate$"; - private static String NAME_TRAIT = "sw$"; private final String className; private final int identifier; private final String fieldNamePrefix; - public static void setNameTrait(String nameTrait) { - DelegateNamingResolver.NAME_TRAIT = nameTrait; - } - public DelegateNamingResolver(String className, int identifier) { this.className = className; this.identifier = identifier; // Interceptor delegate field name pattern: $delegate$$$ // something like: InstMethodsInter sw$delegate$td03673$sib0lj0$5n874b1; - this.fieldNamePrefix = NAME_TRAIT + PREFIX + RandomString.hashOf(className.hashCode()) + "$" + RandomString.hashOf(identifier) + "$"; + this.fieldNamePrefix = Constants.NAME_TRAIT + PREFIX + RandomString.hashOf(className.hashCode()) + "$" + RandomString.hashOf(identifier) + "$"; } public String resolve(Object interceptPoint) { diff --git a/apm-sniffer/apm-agent/src/main/java/org/apache/skywalking/apm/agent/SkyWalkingAgent.java b/apm-sniffer/apm-agent/src/main/java/org/apache/skywalking/apm/agent/SkyWalkingAgent.java index 7e518bb231..8e0c2495b5 100644 --- a/apm-sniffer/apm-agent/src/main/java/org/apache/skywalking/apm/agent/SkyWalkingAgent.java +++ b/apm-sniffer/apm-agent/src/main/java/org/apache/skywalking/apm/agent/SkyWalkingAgent.java @@ -36,6 +36,7 @@ import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.matcher.ElementMatchers; import net.bytebuddy.utility.JavaModule; +import org.apache.skywalking.apm.agent.bytebuddy.SWMethodNameTransformer; import org.apache.skywalking.apm.agent.core.boot.AgentPackageNotFoundException; import org.apache.skywalking.apm.agent.core.boot.ServiceManager; import org.apache.skywalking.apm.agent.core.conf.Config; @@ -56,6 +57,7 @@ import static net.bytebuddy.matcher.ElementMatchers.nameContains; import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith; import static net.bytebuddy.matcher.ElementMatchers.not; +import static org.apache.skywalking.apm.agent.core.conf.Constants.NAME_TRAIT; /** * The main entrance of sky-walking agent, based on javaagent mechanism. @@ -96,10 +98,8 @@ public static void premain(String agentArgs, Instrumentation instrumentation) th } LOGGER.info("Skywalking agent begin to install transformer ..."); - String nameTrait = getNameTrait(); - DelegateNamingResolver.setNameTrait(nameTrait); - AgentBuilder agentBuilder = newAgentBuilder(instrumentation, nameTrait).ignore( + AgentBuilder agentBuilder = newAgentBuilder().ignore( nameStartsWith("net.bytebuddy.") .or(nameStartsWith("org.slf4j.")) .or(nameStartsWith("org.groovy.")) @@ -146,21 +146,19 @@ public static void premain(String agentArgs, Instrumentation instrumentation) th .addShutdownHook(new Thread(ServiceManager.INSTANCE::shutdown, "skywalking service shutdown thread")); } - private static AgentBuilder newAgentBuilder(Instrumentation instrumentation, String nameTrait) { + /** + * Create a new agent builder through customized {@link ByteBuddy} powered by + * {@link SWAuxiliaryTypeNamingStrategy} {@link DelegateNamingResolver} {@link SWMethodNameTransformer} and {@link SWImplementationContextFactory} + */ + private static AgentBuilder newAgentBuilder() { final ByteBuddy byteBuddy = new ByteBuddy() .with(TypeValidation.of(Config.Agent.IS_OPEN_DEBUGGING_CLASS)) - .with(new SWAuxiliaryTypeNamingStrategy(nameTrait)) - .with(new SWImplementationContextFactory(nameTrait)); - - SWNativeMethodStrategy nativeMethodStrategy = new SWNativeMethodStrategy(nameTrait); + .with(new SWAuxiliaryTypeNamingStrategy(NAME_TRAIT)) + .with(new SWImplementationContextFactory(NAME_TRAIT)); - AgentBuilder agentBuilder = new SWAgentBuilderDefault(byteBuddy, nativeMethodStrategy) + SWNativeMethodStrategy nativeMethodStrategy = new SWNativeMethodStrategy(NAME_TRAIT); + return new SWAgentBuilderDefault(byteBuddy, nativeMethodStrategy) .with(AgentBuilder.DescriptionStrategy.Default.POOL_FIRST); - return agentBuilder; - } - - private static String getNameTrait() { - return "sw$"; } private static class Transformer implements AgentBuilder.Transformer { From 417e52b98cb5847d61c5a7ff63c95ac5c23f9cee Mon Sep 17 00:00:00 2001 From: Gong Dewei Date: Fri, 23 Jun 2023 23:06:47 +0800 Subject: [PATCH 11/24] polish code --- .../agent/builder/SWAgentBuilderDefault.java | 4 -- .../bytebuddy/SWMethodNameTransformer.java | 4 -- .../agent/bytebuddy/ConstructorAdvice.java | 33 ------------- .../apm/agent/bytebuddy/InstMethodAdvice.java | 42 ---------------- .../apm/agent/bytebuddy/biz/DocDO.java | 43 ---------------- .../apm/agent/bytebuddy/biz/DocService.java | 39 --------------- .../case1/AbstractInterceptTest.java | 49 ++----------------- .../agent/bytebuddy/case1/Intercept1Test.java | 2 +- .../agent/bytebuddy/case1/Intercept2Test.java | 2 +- .../agent/bytebuddy/case1/Intercept3Test.java | 2 +- .../agent/bytebuddy/case1/Intercept4Test.java | 2 +- .../agent/bytebuddy/case1/Intercept5Test.java | 4 +- .../agent/bytebuddy/case1/Intercept6Test.java | 4 +- .../bytebuddy/case1/Retransform1Test.java | 17 +++++-- .../bytebuddy/case1/Retransform2Test.java | 16 +++--- 15 files changed, 31 insertions(+), 232 deletions(-) delete mode 100644 apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/ConstructorAdvice.java delete mode 100644 apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/InstMethodAdvice.java delete mode 100644 apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/DocDO.java delete mode 100644 apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/DocService.java diff --git a/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWAgentBuilderDefault.java b/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWAgentBuilderDefault.java index 388bc49ce0..958cf7c51e 100644 --- a/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWAgentBuilderDefault.java +++ b/apm-sniffer/bytebuddy-patch/src/main/java/net/bytebuddy/agent/builder/SWAgentBuilderDefault.java @@ -45,10 +45,6 @@ public class SWAgentBuilderDefault extends AgentBuilder.Default { */ private static final CircularityLock DEFAULT_LOCK = new CircularityLock.Default(); - public SWAgentBuilderDefault(NativeMethodStrategy nativeMethodStrategy) { - this(new ByteBuddy(), nativeMethodStrategy); - } - public SWAgentBuilderDefault(ByteBuddy byteBuddy, NativeMethodStrategy nativeMethodStrategy) { this(byteBuddy, Listener.NoOp.INSTANCE, diff --git a/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWMethodNameTransformer.java b/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWMethodNameTransformer.java index e70315d27f..9d329321ed 100644 --- a/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWMethodNameTransformer.java +++ b/apm-sniffer/bytebuddy-patch/src/main/java/org/apache/skywalking/apm/agent/bytebuddy/SWMethodNameTransformer.java @@ -31,10 +31,6 @@ public class SWMethodNameTransformer implements MethodNameTransformer { private String prefix; - public SWMethodNameTransformer() { - this(DEFAULT_PREFIX); - } - public SWMethodNameTransformer(String nameTrait) { this.prefix = nameTrait + DEFAULT_PREFIX; } diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/ConstructorAdvice.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/ConstructorAdvice.java deleted file mode 100644 index 43a36aba44..0000000000 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/ConstructorAdvice.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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; - -import net.bytebuddy.asm.Advice; - -import java.lang.reflect.Constructor; -import java.util.Arrays; - -public class ConstructorAdvice { - - @Advice.OnMethodExit(inline = false) - public static void onExit(@Advice.Origin Constructor constructor, - @Advice.AllArguments Object[] args) throws Exception { - Log.info(String.format("ConstructorAdvice: constructor: %s, args: %s", constructor, Arrays.asList(args))); - } -} \ No newline at end of file diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/InstMethodAdvice.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/InstMethodAdvice.java deleted file mode 100644 index 1307e520ca..0000000000 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/InstMethodAdvice.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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; - -import net.bytebuddy.asm.Advice; - -import java.lang.reflect.Method; -import java.util.Arrays; - -public class InstMethodAdvice { - - @Advice.OnMethodEnter(inline = false) - public static void onEnter(@Advice.This Object target, - @Advice.Origin Method method, - @Advice.AllArguments Object[] args) throws Exception { - Log.info(String.format("InstMethodAdvice.onEnter: constructor: %s, args: %s", method, Arrays.asList(args))); - } - - @Advice.OnMethodExit(inline = false) - public static void onExit(@Advice.This Object target, - @Advice.Origin Method method, - @Advice.AllArguments Object[] args) throws Exception { - Log.info(String.format("InstMethodAdvice.onExit: constructor: %s, args: %s", method, Arrays.asList(args))); - } - -} \ No newline at end of file diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/DocDO.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/DocDO.java deleted file mode 100644 index d2929cec0b..0000000000 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/DocDO.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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; - -import lombok.Builder; - -@Builder -public class DocDO { - private int id; - private String name; - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } -} diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/DocService.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/DocService.java deleted file mode 100644 index 2ceb9b31e4..0000000000 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/biz/DocService.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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; - -import java.util.ArrayList; -import java.util.List; - -public class DocService { - - private List cache = new ArrayList<>(); - - public void add(DocDO docDO) { - this.cache.add(docDO); - } - - public DocDO getById(int id) { - return cache.stream().filter(DocDO -> DocDO.getId() == id).findAny().orElse(null); - } - - public List list() { - return cache; - } -} diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/AbstractInterceptTest.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/AbstractInterceptTest.java index d1be512e6b..ce8071fbe5 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/AbstractInterceptTest.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/AbstractInterceptTest.java @@ -23,16 +23,13 @@ import net.bytebuddy.agent.builder.AgentBuilder; import net.bytebuddy.agent.builder.SWAgentBuilderDefault; import net.bytebuddy.agent.builder.SWNativeMethodStrategy; -import net.bytebuddy.asm.Advice; import net.bytebuddy.implementation.MethodDelegation; import net.bytebuddy.implementation.SWImplementationContextFactory; import net.bytebuddy.implementation.SuperMethodCall; import net.bytebuddy.matcher.ElementMatchers; import net.bytebuddy.utility.JavaModule; -import org.apache.skywalking.apm.agent.bytebuddy.ConstructorAdvice; import org.apache.skywalking.apm.agent.bytebuddy.ConstructorInter; import org.apache.skywalking.apm.agent.bytebuddy.EnhanceHelper; -import org.apache.skywalking.apm.agent.bytebuddy.InstMethodAdvice; import org.apache.skywalking.apm.agent.bytebuddy.InstMethodsInter; import org.apache.skywalking.apm.agent.bytebuddy.Log; import org.apache.skywalking.apm.agent.bytebuddy.SWAsmVisitorWrapper; @@ -83,9 +80,9 @@ protected static void checkMethodInterceptor(String method, int round) { Log.info("Found interceptor: " + interceptorName); } - protected static void checkConstructorInterceptor(int round) { + protected static void checkConstructorInterceptor(String className, int round) { List interceptors = EnhanceHelper.getInterceptors(); - String interceptorName = CONSTRUCTOR_INTERCEPTOR_CLASS + "$" + round; + String interceptorName = CONSTRUCTOR_INTERCEPTOR_CLASS + "$" + className + "$" + round; Assert.assertTrue("Not found interceptor: " + interceptorName, interceptors.contains(interceptorName)); Log.info("Found interceptor: " + interceptorName); } @@ -115,32 +112,12 @@ protected void installMethodInterceptorWithMethodDelegation(String className, St .installOn(ByteBuddyAgent.install()); } - protected void installMethodInterceptorWithAdvice(String className, String methodName, int round) { - String interceptorClassName = METHOD_INTERCEPTOR_CLASS + "$" + methodName + "$" + round; - String nameTrait = getNameTrait(round); - String fieldName = nameTrait + "_delegate$" + methodName + round; - - AgentBuilder agentBuilder = newAgentBuilder(nameTrait); - agentBuilder.type(ElementMatchers.named(className)) - .transform((builder, typeDescription, classLoader, module, protectionDomain) -> { - if (deleteDuplicatedFields) { - builder = builder.visit(new SWAsmVisitorWrapper()); - } - return builder - .method(ElementMatchers.nameContainsIgnoreCase(methodName)) - .intercept(Advice.to(InstMethodAdvice.class)); - } - ) - .with(getListener(interceptorClassName)) - .installOn(ByteBuddyAgent.install()); - } - protected void installConstructorInterceptor(String className, int round) { installConstructorInterceptorWithMethodDelegation(className, round); } protected void installConstructorInterceptorWithMethodDelegation(String className, int round) { - String interceptorClassName = CONSTRUCTOR_INTERCEPTOR_CLASS + "$" + round; + String interceptorClassName = CONSTRUCTOR_INTERCEPTOR_CLASS + "$" + className + "$" + round; String nameTrait = getNameTrait(round); String fieldName = nameTrait + "_delegate$constructor" + round; @@ -162,26 +139,6 @@ protected void installConstructorInterceptorWithMethodDelegation(String classNam .installOn(ByteBuddyAgent.install()); } - protected void installConstructorInterceptorWithAdvice(String className, int round) { - String interceptorClassName = CONSTRUCTOR_INTERCEPTOR_CLASS + "$" + round; - String nameTrait = getNameTrait(round); - String fieldName = nameTrait + "_delegate$constructor" + round; - - AgentBuilder agentBuilder = newAgentBuilder(nameTrait); - agentBuilder.type(ElementMatchers.named(className)) - .transform((builder, typeDescription, classLoader, module, protectionDomain) -> { - if (deleteDuplicatedFields) { - builder = builder.visit(new SWAsmVisitorWrapper()); - } - return builder - .constructor(ElementMatchers.any()) - .intercept(Advice.to(ConstructorAdvice.class)); - } - ) - .with(getListener(interceptorClassName)) - .installOn(ByteBuddyAgent.install()); - } - protected String getNameTrait(int round) { return nameTraits.get(round - 1); } diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept1Test.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept1Test.java index e1fbddb0ae..6162a170a1 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept1Test.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept1Test.java @@ -40,7 +40,7 @@ public void test1() throws UnmodifiableClassException { } finally { // check interceptors checkMethodInterceptor(SAY_HELLO_METHOD, 1); - checkConstructorInterceptor(1); + checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); } } } diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept2Test.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept2Test.java index 80f4a1539c..f552abdd97 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept2Test.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept2Test.java @@ -43,7 +43,7 @@ public void test2() throws UnmodifiableClassException { // check interceptors checkMethodInterceptor(SAY_HELLO_METHOD, 1); checkMethodInterceptor(SAY_HELLO_METHOD, 2); - checkConstructorInterceptor(1); + checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); } } } diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept3Test.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept3Test.java index 13be513007..26e7750406 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept3Test.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept3Test.java @@ -42,7 +42,7 @@ public void test3() throws UnmodifiableClassException { } finally { // check interceptors checkMethodInterceptor(SAY_HELLO_METHOD, 1); - checkConstructorInterceptor(1); + checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); checkMethodInterceptor(SAY_HELLO_METHOD, 2); } diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept4Test.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept4Test.java index cb04ef4b13..4ab331ed2e 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept4Test.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept4Test.java @@ -40,7 +40,7 @@ public void test4() throws UnmodifiableClassException { e.printStackTrace(); } finally { // check interceptors - checkConstructorInterceptor(1); + checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); checkMethodInterceptor(SAY_HELLO_METHOD, 1); } diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept5Test.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept5Test.java index c77b3fcd03..34c497834a 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept5Test.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept5Test.java @@ -42,9 +42,9 @@ public void test5() throws UnmodifiableClassException { e.printStackTrace(); } finally { // check interceptors - checkConstructorInterceptor(1); + checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); checkMethodInterceptor(SAY_HELLO_METHOD, 1); - checkConstructorInterceptor(2); + checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 2); checkMethodInterceptor(SAY_HELLO_METHOD, 2); } } diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept6Test.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept6Test.java index 6bbf51a61f..760ddd2aea 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept6Test.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept6Test.java @@ -43,9 +43,9 @@ public void test6() throws UnmodifiableClassException { } finally { // check interceptors checkMethodInterceptor(SAY_HELLO_METHOD, 1); - checkConstructorInterceptor(1); + checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); checkMethodInterceptor(SAY_HELLO_METHOD, 2); - checkConstructorInterceptor(2); + checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 2); } } diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Retransform1Test.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Retransform1Test.java index c59765b462..ce6b04ff7f 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Retransform1Test.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Retransform1Test.java @@ -23,6 +23,7 @@ import net.bytebuddy.agent.ByteBuddyAgent; import org.apache.skywalking.apm.agent.bytebuddy.biz.ProjectDO; import org.apache.skywalking.apm.agent.bytebuddy.biz.ProjectService; +import org.junit.Assert; import org.junit.Test; import java.lang.instrument.Instrumentation; @@ -51,14 +52,15 @@ public void testInterceptConstructor() throws UnmodifiableClassException { } finally { // check interceptors checkMethodInterceptor(SAY_HELLO_METHOD, 1); - checkConstructorInterceptor(1); + checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); } ProjectService projectService = new ProjectService(); - projectService.add(ProjectDO.builder() + ProjectDO originProjectDO = ProjectDO.builder() .name("test") .id(1) - .build()); + .build(); + projectService.add(originProjectDO); ProjectDO projectDO = projectService.getById(1); Log.info(projectDO); projectService.list(); @@ -72,8 +74,17 @@ public void testInterceptConstructor() throws UnmodifiableClassException { // test again callBizFoo(1); + // check interceptors + checkMethodInterceptor(SAY_HELLO_METHOD, 1); + checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); + projectDO = projectService.getById(1); Log.info(projectDO); + + checkConstructorInterceptor(PROJECT_SERVICE_CLASS_NAME, 1); + checkMethodInterceptor("add", 1); + checkMethodInterceptor("get", 1); + checkMethodInterceptor("list", 1); } } diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Retransform2Test.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Retransform2Test.java index 081cf33601..3e2dc7262e 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Retransform2Test.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Retransform2Test.java @@ -36,18 +36,15 @@ public void testInterceptConstructor() throws UnmodifiableClassException { //this.deleteDuplicatedFields = true; - // install transformer + // install transformer 1 installMethodInterceptor(BIZ_FOO_CLASS_NAME, SAY_HELLO_METHOD, 1); installConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); - // installTraceClassTransformer("Trace class 1: "); - + // install transformer 2 installConstructorInterceptor(BIZ_FOO_CLASS_NAME, 2); installMethodInterceptor(BIZ_FOO_CLASS_NAME, SAY_HELLO_METHOD, 2); installMethodInterceptor(BIZ_FOO_CLASS_NAME, "greeting", 2); - // installTraceClassTransformer("Trace class 2: "); - // call target class try { callBizFoo(2); @@ -57,15 +54,14 @@ public void testInterceptConstructor() throws UnmodifiableClassException { // check interceptors Log.info("-------------"); Log.info("Check interceptors .."); - checkConstructorInterceptor(1); - checkConstructorInterceptor(2); + checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); + checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 2); checkMethodInterceptor(SAY_HELLO_METHOD, 1); checkMethodInterceptor(SAY_HELLO_METHOD, 2); } // do retransform reTransform(instrumentation, BizFoo.class); -// reTransform(instrumentation, ProjectService.class); // test again try { @@ -76,8 +72,8 @@ public void testInterceptConstructor() throws UnmodifiableClassException { // check interceptors Log.info("-------------"); Log.info("Check interceptors .."); - checkConstructorInterceptor(1); - checkConstructorInterceptor(2); + checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); + checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 2); checkMethodInterceptor(SAY_HELLO_METHOD, 1); checkMethodInterceptor(SAY_HELLO_METHOD, 2); } From 3d9c851c209bf8066c58ada5913ece3f88cc261b Mon Sep 17 00:00:00 2001 From: Gong Dewei Date: Fri, 23 Jun 2023 23:13:14 +0800 Subject: [PATCH 12/24] remove unused imports --- .../skywalking/apm/agent/bytebuddy/case1/Retransform1Test.java | 1 - 1 file changed, 1 deletion(-) diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Retransform1Test.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Retransform1Test.java index ce6b04ff7f..73691b1837 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Retransform1Test.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Retransform1Test.java @@ -23,7 +23,6 @@ import net.bytebuddy.agent.ByteBuddyAgent; import org.apache.skywalking.apm.agent.bytebuddy.biz.ProjectDO; import org.apache.skywalking.apm.agent.bytebuddy.biz.ProjectService; -import org.junit.Assert; import org.junit.Test; import java.lang.instrument.Instrumentation; From 731d85ced792d03061ca04345d5d1bef18458256 Mon Sep 17 00:00:00 2001 From: Gong Dewei Date: Sat, 24 Jun 2023 00:25:42 +0800 Subject: [PATCH 13/24] polish code --- .../enhance/ClassEnhancePluginDefine.java | 4 +- .../enhance/DelegateNamingResolver.java | 12 +---- .../v2/ClassEnhancePluginDefineV2.java | 4 +- .../apm/agent/bytebuddy/EnhanceHelper.java | 8 +-- .../skywalking/apm/agent/bytebuddy/Log.java | 35 ++++++++---- .../AbstractInterceptTest.java | 31 +++++++++-- .../AbstractReTransformTest.java} | 13 +++-- .../{case1 => cases}/Intercept1Test.java | 21 +++----- .../{case1 => cases}/Intercept2Test.java | 23 ++++---- .../{case1 => cases}/Intercept3Test.java | 22 +++----- .../{case1 => cases}/Intercept4Test.java | 25 +++------ .../{case1 => cases}/Intercept5Test.java | 25 ++++----- .../{case1 => cases}/Intercept6Test.java | 25 ++++----- .../MultipleInterceptorTest.java | 19 +++---- .../ReTransform1Test.java} | 30 +++++------ .../ReTransform2Test.java} | 53 ++++++++----------- 16 files changed, 163 insertions(+), 187 deletions(-) rename apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/{case1 => cases}/AbstractInterceptTest.java (89%) rename apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/{case1/AbstractRetransformTest.java => cases/AbstractReTransformTest.java} (83%) rename apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/{case1 => cases}/Intercept1Test.java (71%) rename apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/{case1 => cases}/Intercept2Test.java (70%) rename apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/{case1 => cases}/Intercept3Test.java (70%) rename apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/{case1 => cases}/Intercept4Test.java (67%) rename apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/{case1 => cases}/Intercept5Test.java (69%) rename apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/{case1 => cases}/Intercept6Test.java (69%) rename apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/{case1 => cases}/MultipleInterceptorTest.java (91%) rename apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/{case1/Retransform1Test.java => cases/ReTransform1Test.java} (80%) rename apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/{case1/Retransform2Test.java => cases/ReTransform2Test.java} (55%) diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/ClassEnhancePluginDefine.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/ClassEnhancePluginDefine.java index af93e4593c..e1a1fa4261 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/ClassEnhancePluginDefine.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/ClassEnhancePluginDefine.java @@ -78,7 +78,7 @@ protected DynamicType.Builder enhanceInstance(TypeDescription typeDescription if (instanceMethodsInterceptPoints != null && instanceMethodsInterceptPoints.length > 0) { existedMethodsInterceptPoints = true; } - DelegateNamingResolver delegateNamingResolver = DelegateNamingResolver.get(typeDescription.getTypeName(), this); + DelegateNamingResolver delegateNamingResolver = new DelegateNamingResolver(typeDescription.getTypeName(), this); /** * nothing need to be enhanced in class instance, maybe need enhance static methods. @@ -184,7 +184,7 @@ protected DynamicType.Builder enhanceClass(TypeDescription typeDescription, D if (staticMethodsInterceptPoints == null || staticMethodsInterceptPoints.length == 0) { return newClassBuilder; } - DelegateNamingResolver delegateNamingResolver = DelegateNamingResolver.get(typeDescription.getTypeName(), this); + DelegateNamingResolver delegateNamingResolver = new DelegateNamingResolver(typeDescription.getTypeName(), this); for (StaticMethodsInterceptPoint staticMethodsInterceptPoint : staticMethodsInterceptPoints) { String interceptor = staticMethodsInterceptPoint.getMethodsInterceptor(); diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java index 1076b80e05..45c44e8d3e 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java @@ -34,16 +34,12 @@ */ public class DelegateNamingResolver { private static final String PREFIX = "delegate$"; - private final String className; - private final int identifier; private final String fieldNamePrefix; - public DelegateNamingResolver(String className, int identifier) { - this.className = className; - this.identifier = identifier; + public DelegateNamingResolver(String className, AbstractClassEnhancePluginDefine pluginDefine) { // Interceptor delegate field name pattern: $delegate$$$ // something like: InstMethodsInter sw$delegate$td03673$sib0lj0$5n874b1; - this.fieldNamePrefix = Constants.NAME_TRAIT + PREFIX + RandomString.hashOf(className.hashCode()) + "$" + RandomString.hashOf(identifier) + "$"; + this.fieldNamePrefix = Constants.NAME_TRAIT + PREFIX + RandomString.hashOf(className.hashCode()) + "$" + RandomString.hashOf(pluginDefine.hashCode()) + "$"; } public String resolve(Object interceptPoint) { @@ -72,8 +68,4 @@ private int computeHashCode(Object interceptPoint) { return interceptPoint.hashCode(); } - public static DelegateNamingResolver get(String className, AbstractClassEnhancePluginDefine pluginDefine) { - return new DelegateNamingResolver(className, pluginDefine.hashCode()); - } - } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/v2/ClassEnhancePluginDefineV2.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/v2/ClassEnhancePluginDefineV2.java index 277699b3d1..2436c2994b 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/v2/ClassEnhancePluginDefineV2.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/v2/ClassEnhancePluginDefineV2.java @@ -66,7 +66,7 @@ protected DynamicType.Builder enhanceClass(TypeDescription typeDescription, if (staticMethodsInterceptV2Points == null || staticMethodsInterceptV2Points.length == 0) { return newClassBuilder; } - DelegateNamingResolver delegateNamingResolver = DelegateNamingResolver.get(typeDescription.getTypeName(), this); + DelegateNamingResolver delegateNamingResolver = new DelegateNamingResolver(typeDescription.getTypeName(), this); for (StaticMethodsInterceptV2Point staticMethodsInterceptV2Point : staticMethodsInterceptV2Points) { String interceptor = staticMethodsInterceptV2Point.getMethodsInterceptorV2(); @@ -115,7 +115,7 @@ protected DynamicType.Builder enhanceInstance(TypeDescription typeDescription ConstructorInterceptPoint[] constructorInterceptPoints = getConstructorsInterceptPoints(); InstanceMethodsInterceptV2Point[] instanceMethodsInterceptV2Points = getInstanceMethodsInterceptV2Points(); String enhanceOriginClassName = typeDescription.getTypeName(); - DelegateNamingResolver fieldNamingResolver = DelegateNamingResolver.get(typeDescription.getTypeName(), this); + DelegateNamingResolver fieldNamingResolver = new DelegateNamingResolver(typeDescription.getTypeName(), this); boolean existedConstructorInterceptPoint = false; if (constructorInterceptPoints != null && constructorInterceptPoints.length > 0) { diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/EnhanceHelper.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/EnhanceHelper.java index 2b05697258..8eb808bb80 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/EnhanceHelper.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/EnhanceHelper.java @@ -24,11 +24,11 @@ public class EnhanceHelper { - private static List INTERCEPTORS = new ArrayList<>(); - private static List> ERRORS = new ArrayList<>(); + private static final List INTERCEPTORS = new ArrayList<>(); + private static final List> ERRORS = new ArrayList<>(); public static void onError(String message, Throwable error) { - ERRORS.add(new MapEntry(message, error)); + ERRORS.add(new MapEntry<>(message, error)); } public static void addInterceptor(String interceptor) { @@ -49,7 +49,7 @@ public static void clear() { } private static class MapEntry implements Map.Entry { - private T key; + private final T key; private P value; public MapEntry(T key, P value) { diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/Log.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/Log.java index 0bae0273bc..f1ee04f3dd 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/Log.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/Log.java @@ -18,25 +18,42 @@ package org.apache.skywalking.apm.agent.bytebuddy; +import java.io.ByteArrayOutputStream; import java.io.PrintStream; public class Log { - private static PrintStream PRINT = System.out; - private static PrintStream ERROR_PRINT = System.err; + private static ByteArrayOutputStream OUTPUT; + private static ByteArrayOutputStream ERR_OUTPUT; + private static PrintStream PRINT; + private static PrintStream ERROR_PRINT; - public static void info(String msg) { + public static void info(String msg, Object... args) { + msg = formatLog(msg, args); PRINT.println(msg); } - public static void info(int msg) { - PRINT.println(msg); + public static void error(String msg, Object... args) { + msg = formatLog(msg, args); + ERROR_PRINT.println(msg); } - public static void info(Object obj) { - PRINT.println(obj); + private static String formatLog(String msg, Object[] args) { + msg = msg.replaceAll("\\{}", "%s"); + msg = String.format(msg, args); + return msg; } - public static void error(String msg) { - ERROR_PRINT.println(msg); + public static void clear() { + OUTPUT = new ByteArrayOutputStream(128); + ERR_OUTPUT = new ByteArrayOutputStream(128); + PRINT = new PrintStream(OUTPUT, true); + ERROR_PRINT = new PrintStream(ERR_OUTPUT, true); + } + + public static void printToConsole() { + PrintStream out = System.out; + PrintStream err = System.err; + out.println(OUTPUT.toString()); + err.println(ERR_OUTPUT.toString()); } } diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/AbstractInterceptTest.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/AbstractInterceptTest.java similarity index 89% rename from apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/AbstractInterceptTest.java rename to apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/AbstractInterceptTest.java index ce8071fbe5..c89985ce18 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/AbstractInterceptTest.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/AbstractInterceptTest.java @@ -16,7 +16,7 @@ * */ -package org.apache.skywalking.apm.agent.bytebuddy.case1; +package org.apache.skywalking.apm.agent.bytebuddy.cases; import net.bytebuddy.ByteBuddy; import net.bytebuddy.agent.ByteBuddyAgent; @@ -37,6 +37,10 @@ import org.apache.skywalking.apm.agent.bytebuddy.SWClassFileLocator; import org.apache.skywalking.apm.agent.bytebuddy.biz.BizFoo; import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.rules.TestWatcher; +import org.junit.runner.Description; import org.objectweb.asm.ClassReader; import org.objectweb.asm.util.TraceClassVisitor; @@ -59,12 +63,27 @@ public class AbstractInterceptTest { protected List nameTraits = Arrays.asList("sw2023", "sw2024"); protected boolean deleteDuplicatedFields = false; + @BeforeClass + public static void setUp() { + EnhanceHelper.clear(); + Log.clear(); + } + + @Rule + public TestWatcher watcher = new TestWatcher() { + @Override + protected void failed(Throwable e, Description description) { + Log.error("Test failure: {}.{}(), error: {}", description.getTestClass(), description.getMethodName(), e); + Log.printToConsole(); + } + }; + protected static void callBizFoo(int round) { Log.info("-------------"); Log.info("callBizFoo: " + round); // load target class int intResult = new BizFoo().sayHello(BASE_INT_VALUE); - Log.info(intResult); + Log.info("result: " + intResult); String result = new BizFoo("Smith").sayHello("Joe"); Log.info(result); @@ -87,6 +106,10 @@ protected static void checkConstructorInterceptor(String className, int round) { Log.info("Found interceptor: " + interceptorName); } + protected static void checkErrors() { + Assert.assertEquals("Error occurred in transform", 0, EnhanceHelper.getErrors().size()); + } + protected void installMethodInterceptor(String className, String methodName, int round) { this.installMethodInterceptorWithMethodDelegation(className, methodName, round); } @@ -179,7 +202,9 @@ private static AgentBuilder.Listener.Adapter getListener(String interceptorClass return new AgentBuilder.Listener.Adapter() { @Override public void onError(String typeName, ClassLoader classLoader, JavaModule module, boolean loaded, Throwable throwable) { - System.err.println(String.format("Transform Error: interceptorClassName: %s, typeName: %s, classLoader: %s, module: %s, loaded: %s", interceptorClassName, typeName, classLoader, module, loaded)); + String msg = String.format("Transform Error: interceptorClassName: %s, typeName: %s, classLoader: %s, module: %s, loaded: %s", interceptorClassName, typeName, classLoader, module, loaded); + EnhanceHelper.onError(msg, throwable); + System.err.println(msg); throwable.printStackTrace(); } }; diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/AbstractRetransformTest.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/AbstractReTransformTest.java similarity index 83% rename from apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/AbstractRetransformTest.java rename to apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/AbstractReTransformTest.java index 33d7ee5c03..156326e62f 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/AbstractRetransformTest.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/AbstractReTransformTest.java @@ -16,21 +16,20 @@ * */ -package org.apache.skywalking.apm.agent.bytebuddy.case1; +package org.apache.skywalking.apm.agent.bytebuddy.cases; import org.apache.skywalking.apm.agent.bytebuddy.Log; import java.lang.instrument.ClassFileTransformer; import java.lang.instrument.IllegalClassFormatException; import java.lang.instrument.Instrumentation; -import java.lang.instrument.UnmodifiableClassException; import java.security.ProtectionDomain; -public class AbstractRetransformTest extends AbstractInterceptTest { +public class AbstractReTransformTest extends AbstractInterceptTest { - protected static void reTransform(Instrumentation instrumentation, Class clazz) throws UnmodifiableClassException { + protected static void reTransform(Instrumentation instrumentation, Class clazz) throws Exception { Log.info("-------------"); - Log.info("Begin to retransform class: " + clazz.getName() + " .."); + Log.info("Begin to re-transform class: " + clazz.getName() + " .."); ClassFileTransformer transformer = new ClassFileTransformer() { public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { @@ -42,10 +41,10 @@ public byte[] transform(ClassLoader loader, String className, Class classBein try { instrumentation.addTransformer(transformer, true); instrumentation.retransformClasses(clazz); - Log.info("Retransform class " + clazz.getName() + " successful."); + Log.info("ReTransform class " + clazz.getName() + " successful."); Log.info("-------------"); } catch (Throwable e) { - Log.info("Retransform class " + clazz.getName() + " failure: " + e); + Log.info("ReTransform class " + clazz.getName() + " failure: " + e); Log.info("-------------"); throw e; } finally { diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept1Test.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/Intercept1Test.java similarity index 71% rename from apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept1Test.java rename to apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/Intercept1Test.java index 6162a170a1..47d2881916 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept1Test.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/Intercept1Test.java @@ -16,32 +16,27 @@ * */ -package org.apache.skywalking.apm.agent.bytebuddy.case1; +package org.apache.skywalking.apm.agent.bytebuddy.cases; import net.bytebuddy.agent.ByteBuddyAgent; import org.junit.Test; -import java.lang.instrument.UnmodifiableClassException; - public class Intercept1Test extends AbstractInterceptTest { @Test - public void test1() throws UnmodifiableClassException { + public void test1() { ByteBuddyAgent.install(); // install transformer installMethodInterceptor(BIZ_FOO_CLASS_NAME, SAY_HELLO_METHOD, 1); installConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); - try { - callBizFoo(1); - } catch (Throwable e) { - e.printStackTrace(); - } finally { - // check interceptors - checkMethodInterceptor(SAY_HELLO_METHOD, 1); - checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); - } + callBizFoo(1); + + // check interceptors + checkMethodInterceptor(SAY_HELLO_METHOD, 1); + checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); + checkErrors(); } } diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept2Test.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/Intercept2Test.java similarity index 70% rename from apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept2Test.java rename to apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/Intercept2Test.java index f552abdd97..4d21ff2891 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept2Test.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/Intercept2Test.java @@ -16,17 +16,15 @@ * */ -package org.apache.skywalking.apm.agent.bytebuddy.case1; +package org.apache.skywalking.apm.agent.bytebuddy.cases; import net.bytebuddy.agent.ByteBuddyAgent; import org.junit.Test; -import java.lang.instrument.UnmodifiableClassException; - public class Intercept2Test extends AbstractInterceptTest { @Test - public void test2() throws UnmodifiableClassException { + public void test2() { ByteBuddyAgent.install(); // install transformer @@ -35,16 +33,13 @@ public void test2() throws UnmodifiableClassException { installConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); // load target class - try { - callBizFoo(2); - } catch (Throwable e) { - e.printStackTrace(); - } finally { - // check interceptors - checkMethodInterceptor(SAY_HELLO_METHOD, 1); - checkMethodInterceptor(SAY_HELLO_METHOD, 2); - checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); - } + callBizFoo(2); + + // check interceptors + checkMethodInterceptor(SAY_HELLO_METHOD, 1); + checkMethodInterceptor(SAY_HELLO_METHOD, 2); + checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); + checkErrors(); } } diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept3Test.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/Intercept3Test.java similarity index 70% rename from apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept3Test.java rename to apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/Intercept3Test.java index 26e7750406..f9ac67330e 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept3Test.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/Intercept3Test.java @@ -16,17 +16,15 @@ * */ -package org.apache.skywalking.apm.agent.bytebuddy.case1; +package org.apache.skywalking.apm.agent.bytebuddy.cases; import net.bytebuddy.agent.ByteBuddyAgent; import org.junit.Test; -import java.lang.instrument.UnmodifiableClassException; - public class Intercept3Test extends AbstractInterceptTest { @Test - public void test3() throws UnmodifiableClassException { + public void test3() { ByteBuddyAgent.install(); // install transformer @@ -35,17 +33,13 @@ public void test3() throws UnmodifiableClassException { installMethodInterceptor(BIZ_FOO_CLASS_NAME, SAY_HELLO_METHOD, 2); // load target class - try { - callBizFoo(2); - } catch (Throwable e) { - e.printStackTrace(); - } finally { - // check interceptors - checkMethodInterceptor(SAY_HELLO_METHOD, 1); - checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); - checkMethodInterceptor(SAY_HELLO_METHOD, 2); - } + callBizFoo(2); + // check interceptors + checkMethodInterceptor(SAY_HELLO_METHOD, 1); + checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); + checkMethodInterceptor(SAY_HELLO_METHOD, 2); + checkErrors(); } } diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept4Test.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/Intercept4Test.java similarity index 67% rename from apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept4Test.java rename to apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/Intercept4Test.java index 4ab331ed2e..75db479a8c 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept4Test.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/Intercept4Test.java @@ -16,17 +16,15 @@ * */ -package org.apache.skywalking.apm.agent.bytebuddy.case1; +package org.apache.skywalking.apm.agent.bytebuddy.cases; import net.bytebuddy.agent.ByteBuddyAgent; import org.junit.Test; -import java.lang.instrument.UnmodifiableClassException; - public class Intercept4Test extends AbstractInterceptTest { @Test - public void test4() throws UnmodifiableClassException { + public void test4() { ByteBuddyAgent.install(); // install transformer @@ -34,21 +32,12 @@ public void test4() throws UnmodifiableClassException { installMethodInterceptor(BIZ_FOO_CLASS_NAME, SAY_HELLO_METHOD, 1); // load target class - try { - callBizFoo(1); - } catch (Throwable e) { - e.printStackTrace(); - } finally { - // check interceptors - checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); - checkMethodInterceptor(SAY_HELLO_METHOD, 1); - } - -// try { -// TimeUnit.DAYS.sleep(1); -// } catch (InterruptedException e) { -// } + callBizFoo(1); + // check interceptors + checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); + checkMethodInterceptor(SAY_HELLO_METHOD, 1); + checkErrors(); } } diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept5Test.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/Intercept5Test.java similarity index 69% rename from apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept5Test.java rename to apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/Intercept5Test.java index 34c497834a..5976f7b327 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept5Test.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/Intercept5Test.java @@ -16,17 +16,15 @@ * */ -package org.apache.skywalking.apm.agent.bytebuddy.case1; +package org.apache.skywalking.apm.agent.bytebuddy.cases; import net.bytebuddy.agent.ByteBuddyAgent; import org.junit.Test; -import java.lang.instrument.UnmodifiableClassException; - public class Intercept5Test extends AbstractInterceptTest { @Test - public void test5() throws UnmodifiableClassException { + public void test5() { ByteBuddyAgent.install(); // install transformer @@ -36,17 +34,14 @@ public void test5() throws UnmodifiableClassException { installMethodInterceptor(BIZ_FOO_CLASS_NAME, SAY_HELLO_METHOD, 2); // load target class - try { - callBizFoo(2); - } catch (Throwable e) { - e.printStackTrace(); - } finally { - // check interceptors - checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); - checkMethodInterceptor(SAY_HELLO_METHOD, 1); - checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 2); - checkMethodInterceptor(SAY_HELLO_METHOD, 2); - } + callBizFoo(2); + + // check interceptors + checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); + checkMethodInterceptor(SAY_HELLO_METHOD, 1); + checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 2); + checkMethodInterceptor(SAY_HELLO_METHOD, 2); + checkErrors(); } } diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept6Test.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/Intercept6Test.java similarity index 69% rename from apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept6Test.java rename to apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/Intercept6Test.java index 760ddd2aea..53817179de 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Intercept6Test.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/Intercept6Test.java @@ -16,17 +16,15 @@ * */ -package org.apache.skywalking.apm.agent.bytebuddy.case1; +package org.apache.skywalking.apm.agent.bytebuddy.cases; import net.bytebuddy.agent.ByteBuddyAgent; import org.junit.Test; -import java.lang.instrument.UnmodifiableClassException; - public class Intercept6Test extends AbstractInterceptTest { @Test - public void test6() throws UnmodifiableClassException { + public void test6() { ByteBuddyAgent.install(); // install transformer @@ -36,17 +34,14 @@ public void test6() throws UnmodifiableClassException { installConstructorInterceptor(BIZ_FOO_CLASS_NAME, 2); // load target class - try { - callBizFoo(2); - } catch (Throwable e) { - e.printStackTrace(); - } finally { - // check interceptors - checkMethodInterceptor(SAY_HELLO_METHOD, 1); - checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); - checkMethodInterceptor(SAY_HELLO_METHOD, 2); - checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 2); - } + callBizFoo(2); + + // check interceptors + checkMethodInterceptor(SAY_HELLO_METHOD, 1); + checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); + checkMethodInterceptor(SAY_HELLO_METHOD, 2); + checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 2); + checkErrors(); } } diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/MultipleInterceptorTest.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/MultipleInterceptorTest.java similarity index 91% rename from apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/MultipleInterceptorTest.java rename to apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/MultipleInterceptorTest.java index 0add04f56b..9376ec3794 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/MultipleInterceptorTest.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/MultipleInterceptorTest.java @@ -16,15 +16,15 @@ * */ -package org.apache.skywalking.apm.agent.bytebuddy.case1; +package org.apache.skywalking.apm.agent.bytebuddy.cases; import net.bytebuddy.agent.ByteBuddyAgent; import net.bytebuddy.agent.builder.AgentBuilder; -import org.apache.skywalking.apm.agent.bytebuddy.SWAsmVisitorWrapper; import net.bytebuddy.implementation.MethodDelegation; import net.bytebuddy.matcher.ElementMatchers; import net.bytebuddy.utility.JavaModule; import org.apache.skywalking.apm.agent.bytebuddy.InstMethodsInter; +import org.apache.skywalking.apm.agent.bytebuddy.SWAsmVisitorWrapper; import org.apache.skywalking.apm.agent.core.util.FileUtils; import org.junit.Test; @@ -85,16 +85,11 @@ public void onError(String typeName, ClassLoader classLoader, JavaModule module, }) .installOn(ByteBuddyAgent.install()); - try { - callBizFoo(1); - } catch (Throwable e) { - e.printStackTrace(); - } finally { - // check interceptors -// checkMethodInterceptor(SAY_HELLO_METHOD, 1); -// checkMethodInterceptor(SAY_HELLO_METHOD, 2); - //checkConstructorInterceptor(1); - } + callBizFoo(1); + // check interceptors + // checkMethodInterceptor(SAY_HELLO_METHOD, 1); + checkMethodInterceptor(SAY_HELLO_METHOD, 2); + checkErrors(); } private void enableClassDump() { diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Retransform1Test.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/ReTransform1Test.java similarity index 80% rename from apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Retransform1Test.java rename to apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/ReTransform1Test.java index 73691b1837..a33d1bec45 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Retransform1Test.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/ReTransform1Test.java @@ -16,22 +16,21 @@ * */ -package org.apache.skywalking.apm.agent.bytebuddy.case1; +package org.apache.skywalking.apm.agent.bytebuddy.cases; -import org.apache.skywalking.apm.agent.bytebuddy.Log; -import org.apache.skywalking.apm.agent.bytebuddy.biz.BizFoo; import net.bytebuddy.agent.ByteBuddyAgent; +import org.apache.skywalking.apm.agent.bytebuddy.biz.BizFoo; import org.apache.skywalking.apm.agent.bytebuddy.biz.ProjectDO; import org.apache.skywalking.apm.agent.bytebuddy.biz.ProjectService; +import org.junit.Assert; import org.junit.Test; import java.lang.instrument.Instrumentation; -import java.lang.instrument.UnmodifiableClassException; -public class Retransform1Test extends AbstractRetransformTest { +public class ReTransform1Test extends AbstractReTransformTest { @Test - public void testInterceptConstructor() throws UnmodifiableClassException { + public void testInterceptConstructor() throws Exception { Instrumentation instrumentation = ByteBuddyAgent.install(); // install transformer @@ -44,15 +43,12 @@ public void testInterceptConstructor() throws UnmodifiableClassException { installConstructorInterceptor(PROJECT_SERVICE_CLASS_NAME, 1); // call target class - try { - callBizFoo(1); - } catch (Throwable e) { - e.printStackTrace(); - } finally { - // check interceptors - checkMethodInterceptor(SAY_HELLO_METHOD, 1); - checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); - } + callBizFoo(1); + + // check interceptors + checkMethodInterceptor(SAY_HELLO_METHOD, 1); + checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); + checkErrors(); ProjectService projectService = new ProjectService(); ProjectDO originProjectDO = ProjectDO.builder() @@ -61,7 +57,6 @@ public void testInterceptConstructor() throws UnmodifiableClassException { .build(); projectService.add(originProjectDO); ProjectDO projectDO = projectService.getById(1); - Log.info(projectDO); projectService.list(); // installTraceClassTransformer("Trace class: "); @@ -78,12 +73,13 @@ public void testInterceptConstructor() throws UnmodifiableClassException { checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); projectDO = projectService.getById(1); - Log.info(projectDO); + Assert.assertEquals(originProjectDO, projectDO); checkConstructorInterceptor(PROJECT_SERVICE_CLASS_NAME, 1); checkMethodInterceptor("add", 1); checkMethodInterceptor("get", 1); checkMethodInterceptor("list", 1); + checkErrors(); } } diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Retransform2Test.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/ReTransform2Test.java similarity index 55% rename from apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Retransform2Test.java rename to apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/ReTransform2Test.java index 3e2dc7262e..0dd8749da4 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/case1/Retransform2Test.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/cases/ReTransform2Test.java @@ -16,7 +16,7 @@ * */ -package org.apache.skywalking.apm.agent.bytebuddy.case1; +package org.apache.skywalking.apm.agent.bytebuddy.cases; import net.bytebuddy.agent.ByteBuddyAgent; import org.apache.skywalking.apm.agent.bytebuddy.Log; @@ -24,14 +24,11 @@ import org.junit.Test; import java.lang.instrument.Instrumentation; -import java.lang.instrument.UnmodifiableClassException; -import static org.apache.skywalking.apm.agent.bytebuddy.case1.AbstractRetransformTest.reTransform; - -public class Retransform2Test extends AbstractInterceptTest { +public class ReTransform2Test extends AbstractReTransformTest { @Test - public void testInterceptConstructor() throws UnmodifiableClassException { + public void testInterceptConstructor() throws Exception { Instrumentation instrumentation = ByteBuddyAgent.install(); //this.deleteDuplicatedFields = true; @@ -46,37 +43,29 @@ public void testInterceptConstructor() throws UnmodifiableClassException { installMethodInterceptor(BIZ_FOO_CLASS_NAME, "greeting", 2); // call target class - try { - callBizFoo(2); - } catch (Throwable e) { - e.printStackTrace(); - } finally { - // check interceptors - Log.info("-------------"); - Log.info("Check interceptors .."); - checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); - checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 2); - checkMethodInterceptor(SAY_HELLO_METHOD, 1); - checkMethodInterceptor(SAY_HELLO_METHOD, 2); - } + callBizFoo(2); + + // check interceptors + Log.info("-------------"); + Log.info("Check interceptors .."); + checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); + checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 2); + checkMethodInterceptor(SAY_HELLO_METHOD, 1); + checkMethodInterceptor(SAY_HELLO_METHOD, 2); // do retransform reTransform(instrumentation, BizFoo.class); // test again - try { - callBizFoo(2); - } catch (Throwable e) { - e.printStackTrace(); - } finally { - // check interceptors - Log.info("-------------"); - Log.info("Check interceptors .."); - checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); - checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 2); - checkMethodInterceptor(SAY_HELLO_METHOD, 1); - checkMethodInterceptor(SAY_HELLO_METHOD, 2); - } + callBizFoo(2); + // check interceptors + Log.info("-------------"); + Log.info("Check interceptors .."); + checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 1); + checkConstructorInterceptor(BIZ_FOO_CLASS_NAME, 2); + checkMethodInterceptor(SAY_HELLO_METHOD, 1); + checkMethodInterceptor(SAY_HELLO_METHOD, 2); + checkErrors(); } } From 9b9161c0debdeccbc5eb43e3b7bb30bf9a228a96 Mon Sep 17 00:00:00 2001 From: Gong Dewei Date: Sat, 24 Jun 2023 11:36:31 +0800 Subject: [PATCH 14/24] Add InterceptPoint interface --- .../ConstructorInterceptPoint.java | 8 ++++- .../InstanceMethodsInterceptPoint.java | 8 ++++- .../plugin/interceptor/InterceptPoint.java | 24 ++++++++++++++ .../StaticMethodsInterceptPoint.java | 8 ++++- .../enhance/DelegateNamingResolver.java | 32 ++----------------- .../v2/ConstructorInterceptV2Point.java | 9 +++++- .../v2/InstanceMethodsInterceptV2Point.java | 9 +++++- .../v2/StaticMethodsInterceptV2Point.java | 9 +++++- .../configuration.yml | 2 +- .../configuration.yml | 2 +- 10 files changed, 74 insertions(+), 37 deletions(-) create mode 100644 apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InterceptPoint.java diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/ConstructorInterceptPoint.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/ConstructorInterceptPoint.java index 9c98419466..d94a8d8600 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/ConstructorInterceptPoint.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/ConstructorInterceptPoint.java @@ -21,6 +21,8 @@ import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.matcher.ElementMatcher; +import java.util.Objects; + /** * One of the three "Intercept Point". "Intercept Point" is a definition about where and how intercept happens. In this * "Intercept Point", the definition targets class's constructors, and the interceptor. @@ -28,7 +30,7 @@ * ref to two others: {@link StaticMethodsInterceptPoint} and {@link InstanceMethodsInterceptPoint} *

*/ -public interface ConstructorInterceptPoint { +public interface ConstructorInterceptPoint extends InterceptPoint { /** * Constructor matcher * @@ -41,4 +43,8 @@ public interface ConstructorInterceptPoint { * org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor} */ String getConstructorInterceptor(); + + default int hashcode() { + return Objects.hash(this.getClass().getName(), this.getConstructorMatcher().toString(), this.getConstructorInterceptor()); + } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InstanceMethodsInterceptPoint.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InstanceMethodsInterceptPoint.java index 6ae8057e90..53c3abcf19 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InstanceMethodsInterceptPoint.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InstanceMethodsInterceptPoint.java @@ -21,6 +21,8 @@ import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.matcher.ElementMatcher; +import java.util.Objects; + /** * One of the three "Intercept Point". "Intercept Point" is a definition about where and how intercept happens. In this * "Intercept Point", the definition targets class's instance methods, and the interceptor. @@ -28,7 +30,7 @@ * ref to two others: {@link ConstructorInterceptPoint} and {@link StaticMethodsInterceptPoint} *

*/ -public interface InstanceMethodsInterceptPoint { +public interface InstanceMethodsInterceptPoint extends InterceptPoint { /** * class instance methods matcher. * @@ -42,4 +44,8 @@ public interface InstanceMethodsInterceptPoint { String getMethodsInterceptor(); boolean isOverrideArgs(); + + default int hashcode() { + return Objects.hash(this.getClass().getName(), this.getMethodsMatcher().toString(), this.getMethodsInterceptor(), this.isOverrideArgs()); + } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InterceptPoint.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InterceptPoint.java new file mode 100644 index 0000000000..5abce5e188 --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InterceptPoint.java @@ -0,0 +1,24 @@ +/* + * 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.core.plugin.interceptor; + +public interface InterceptPoint { + + int hashcode(); + +} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/StaticMethodsInterceptPoint.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/StaticMethodsInterceptPoint.java index 2af763bc29..78b2d54aa7 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/StaticMethodsInterceptPoint.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/StaticMethodsInterceptPoint.java @@ -21,6 +21,8 @@ import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.matcher.ElementMatcher; +import java.util.Objects; + /** * One of the three "Intercept Point". "Intercept Point" is a definition about where and how intercept happens. In this * "Intercept Point", the definition targets class's static methods, and the interceptor. @@ -28,7 +30,7 @@ * ref to two others: {@link ConstructorInterceptPoint} and {@link InstanceMethodsInterceptPoint} *

*/ -public interface StaticMethodsInterceptPoint { +public interface StaticMethodsInterceptPoint extends InterceptPoint { /** * static methods matcher. * @@ -42,4 +44,8 @@ public interface StaticMethodsInterceptPoint { String getMethodsInterceptor(); boolean isOverrideArgs(); + + default int hashcode() { + return Objects.hash(this.getClass().getName(), this.getMethodsMatcher().toString(), this.getMethodsInterceptor(), this.isOverrideArgs()); + } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java index 45c44e8d3e..bda18cbbe5 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java @@ -21,11 +21,7 @@ import net.bytebuddy.utility.RandomString; import org.apache.skywalking.apm.agent.core.conf.Constants; import org.apache.skywalking.apm.agent.core.plugin.AbstractClassEnhancePluginDefine; -import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; -import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; -import org.apache.skywalking.apm.agent.core.plugin.interceptor.StaticMethodsInterceptPoint; -import org.apache.skywalking.apm.agent.core.plugin.interceptor.v2.InstanceMethodsInterceptV2Point; -import org.apache.skywalking.apm.agent.core.plugin.interceptor.v2.StaticMethodsInterceptV2Point; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.InterceptPoint; import java.util.Objects; @@ -42,30 +38,8 @@ public DelegateNamingResolver(String className, AbstractClassEnhancePluginDefine this.fieldNamePrefix = Constants.NAME_TRAIT + PREFIX + RandomString.hashOf(className.hashCode()) + "$" + RandomString.hashOf(pluginDefine.hashCode()) + "$"; } - public String resolve(Object interceptPoint) { + public String resolve(InterceptPoint interceptPoint) { Objects.requireNonNull(interceptPoint, "interceptPoint cannot be null"); - return fieldNamePrefix + RandomString.hashOf(computeHashCode(interceptPoint)); + return fieldNamePrefix + RandomString.hashOf(interceptPoint.hashcode()); } - - private int computeHashCode(Object interceptPoint) { - String interceptPointClassName = interceptPoint.getClass().getName(); - if (interceptPoint instanceof ConstructorInterceptPoint) { - ConstructorInterceptPoint point = (ConstructorInterceptPoint) interceptPoint; - return Objects.hash(interceptPointClassName, point.getConstructorMatcher().toString(), point.getConstructorInterceptor()); - } else if (interceptPoint instanceof InstanceMethodsInterceptPoint) { - InstanceMethodsInterceptPoint point = (InstanceMethodsInterceptPoint) interceptPoint; - return Objects.hash(interceptPointClassName, point.getMethodsMatcher().toString(), point.getMethodsInterceptor(), point.isOverrideArgs()); - } else if (interceptPoint instanceof InstanceMethodsInterceptV2Point) { - InstanceMethodsInterceptV2Point point = (InstanceMethodsInterceptV2Point) interceptPoint; - return Objects.hash(interceptPointClassName, point.getMethodsMatcher().toString(), point.getMethodsInterceptorV2(), point.isOverrideArgs()); - } else if (interceptPoint instanceof StaticMethodsInterceptPoint) { - StaticMethodsInterceptPoint point = (StaticMethodsInterceptPoint) interceptPoint; - return Objects.hash(interceptPointClassName, point.getMethodsMatcher().toString(), point.getMethodsInterceptor(), point.isOverrideArgs()); - } else if (interceptPoint instanceof StaticMethodsInterceptV2Point) { - StaticMethodsInterceptV2Point point = (StaticMethodsInterceptV2Point) interceptPoint; - return Objects.hash(interceptPointClassName, point.getMethodsMatcher().toString(), point.getMethodsInterceptorV2(), point.isOverrideArgs()); - } - return interceptPoint.hashCode(); - } - } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/ConstructorInterceptV2Point.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/ConstructorInterceptV2Point.java index dcd0fa30b4..49e57aeaa3 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/ConstructorInterceptV2Point.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/ConstructorInterceptV2Point.java @@ -19,8 +19,11 @@ import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.matcher.ElementMatcher; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.InterceptPoint; -public interface ConstructorInterceptV2Point { +import java.util.Objects; + +public interface ConstructorInterceptV2Point extends InterceptPoint { /** * Constructor matcher @@ -35,4 +38,8 @@ public interface ConstructorInterceptV2Point { */ String getConstructorInterceptorV2(); + default int hashcode() { + return Objects.hash(this.getClass().getName(), this.getConstructorMatcher().toString(), this.getConstructorInterceptorV2()); + } + } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/InstanceMethodsInterceptV2Point.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/InstanceMethodsInterceptV2Point.java index e8932aa35b..44115caffc 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/InstanceMethodsInterceptV2Point.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/InstanceMethodsInterceptV2Point.java @@ -21,6 +21,9 @@ import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.matcher.ElementMatcher; import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.InterceptPoint; + +import java.util.Objects; /** * One of the three "Intercept Point". "Intercept Point" is a definition about where and how intercept happens. In this @@ -29,7 +32,7 @@ * ref to two others: {@link ConstructorInterceptPoint} and {@link StaticMethodsInterceptV2Point} *

*/ -public interface InstanceMethodsInterceptV2Point { +public interface InstanceMethodsInterceptV2Point extends InterceptPoint { /** * class instance methods matcher. * @@ -43,4 +46,8 @@ public interface InstanceMethodsInterceptV2Point { String getMethodsInterceptorV2(); boolean isOverrideArgs(); + + default int hashcode() { + return Objects.hash(this.getClass().getName(), this.getMethodsMatcher().toString(), this.getMethodsInterceptorV2(), this.isOverrideArgs()); + } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/StaticMethodsInterceptV2Point.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/StaticMethodsInterceptV2Point.java index 78052a806e..000a4cbfce 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/StaticMethodsInterceptV2Point.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/StaticMethodsInterceptV2Point.java @@ -21,6 +21,9 @@ import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.matcher.ElementMatcher; import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.InterceptPoint; + +import java.util.Objects; /** * One of the three "Intercept Point". "Intercept Point" is a definition about where and how intercept happens. In this @@ -29,7 +32,7 @@ * ref to two others: {@link ConstructorInterceptPoint} and {@link InstanceMethodsInterceptV2Point} *

*/ -public interface StaticMethodsInterceptV2Point { +public interface StaticMethodsInterceptV2Point extends InterceptPoint { /** * static methods matcher. * @@ -43,4 +46,8 @@ public interface StaticMethodsInterceptV2Point { String getMethodsInterceptorV2(); boolean isOverrideArgs(); + + default int hashcode() { + return Objects.hash(this.getClass().getName(), this.getMethodsMatcher().toString(), this.getMethodsInterceptorV2(), this.isOverrideArgs()); + } } diff --git a/test/plugin/scenarios/retransform-class-scenario/configuration.yml b/test/plugin/scenarios/retransform-class-scenario/configuration.yml index b5ea7d85d1..47884e13c2 100644 --- a/test/plugin/scenarios/retransform-class-scenario/configuration.yml +++ b/test/plugin/scenarios/retransform-class-scenario/configuration.yml @@ -20,4 +20,4 @@ healthCheck: http://localhost:8080/case/healthCheck startScript: ./bin/startup.sh environment: dependencies: -withPlugins: apm-*.jar +withPlugins: apm-spring-*.jar, apm-jdk-*.jar diff --git a/test/plugin/scenarios/retransform-class-tomcat-scenario/configuration.yml b/test/plugin/scenarios/retransform-class-tomcat-scenario/configuration.yml index 1334673771..51a59ec13e 100644 --- a/test/plugin/scenarios/retransform-class-tomcat-scenario/configuration.yml +++ b/test/plugin/scenarios/retransform-class-tomcat-scenario/configuration.yml @@ -18,4 +18,4 @@ type: tomcat entryService: http://localhost:8080/retransform-class-tomcat-scenario/case/retransform-class healthCheck: http://localhost:8080/retransform-class-tomcat-scenario/case/healthCheck dependencies: -withPlugins: apm-*.jar +withPlugins: apm-spring-*.jar, apm-jdk-*.jar From 53d503c5c88d307f59d69f31322cce0406bbac61 Mon Sep 17 00:00:00 2001 From: Gong Dewei Date: Sat, 24 Jun 2023 12:18:47 +0800 Subject: [PATCH 15/24] fix error: compile scala with interface default method --- apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/pom.xml index da691fa2e7..6837d9a75e 100644 --- a/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/pom.xml @@ -35,6 +35,8 @@ UTF-8 6.34.0 2.11.12 + 1.8 + 1.8 From 3ca80833457990a4cb0987b5d85f6148db35e911 Mon Sep 17 00:00:00 2001 From: Gong Dewei Date: Sat, 24 Jun 2023 13:01:22 +0800 Subject: [PATCH 16/24] improve hashcode method --- .../core/plugin/interceptor/ConstructorInterceptPoint.java | 2 +- .../core/plugin/interceptor/InstanceMethodsInterceptPoint.java | 2 +- .../apm/agent/core/plugin/interceptor/InterceptPoint.java | 2 +- .../core/plugin/interceptor/StaticMethodsInterceptPoint.java | 2 +- .../core/plugin/interceptor/enhance/DelegateNamingResolver.java | 2 +- .../core/plugin/interceptor/v2/ConstructorInterceptV2Point.java | 2 +- .../plugin/interceptor/v2/InstanceMethodsInterceptV2Point.java | 2 +- .../plugin/interceptor/v2/StaticMethodsInterceptV2Point.java | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/ConstructorInterceptPoint.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/ConstructorInterceptPoint.java index d94a8d8600..80e5f230d4 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/ConstructorInterceptPoint.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/ConstructorInterceptPoint.java @@ -44,7 +44,7 @@ public interface ConstructorInterceptPoint extends InterceptPoint { */ String getConstructorInterceptor(); - default int hashcode() { + default int computeHashCode() { return Objects.hash(this.getClass().getName(), this.getConstructorMatcher().toString(), this.getConstructorInterceptor()); } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InstanceMethodsInterceptPoint.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InstanceMethodsInterceptPoint.java index 53c3abcf19..eeae41e477 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InstanceMethodsInterceptPoint.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InstanceMethodsInterceptPoint.java @@ -45,7 +45,7 @@ public interface InstanceMethodsInterceptPoint extends InterceptPoint { boolean isOverrideArgs(); - default int hashcode() { + default int computeHashCode() { return Objects.hash(this.getClass().getName(), this.getMethodsMatcher().toString(), this.getMethodsInterceptor(), this.isOverrideArgs()); } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InterceptPoint.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InterceptPoint.java index 5abce5e188..a50e7698e5 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InterceptPoint.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InterceptPoint.java @@ -19,6 +19,6 @@ public interface InterceptPoint { - int hashcode(); + int computeHashCode(); } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/StaticMethodsInterceptPoint.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/StaticMethodsInterceptPoint.java index 78b2d54aa7..3254455149 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/StaticMethodsInterceptPoint.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/StaticMethodsInterceptPoint.java @@ -45,7 +45,7 @@ public interface StaticMethodsInterceptPoint extends InterceptPoint { boolean isOverrideArgs(); - default int hashcode() { + default int computeHashCode() { return Objects.hash(this.getClass().getName(), this.getMethodsMatcher().toString(), this.getMethodsInterceptor(), this.isOverrideArgs()); } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java index bda18cbbe5..ad30f9eac7 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java @@ -40,6 +40,6 @@ public DelegateNamingResolver(String className, AbstractClassEnhancePluginDefine public String resolve(InterceptPoint interceptPoint) { Objects.requireNonNull(interceptPoint, "interceptPoint cannot be null"); - return fieldNamePrefix + RandomString.hashOf(interceptPoint.hashcode()); + return fieldNamePrefix + RandomString.hashOf(interceptPoint.computeHashCode()); } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/ConstructorInterceptV2Point.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/ConstructorInterceptV2Point.java index 49e57aeaa3..5469ee7dc8 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/ConstructorInterceptV2Point.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/ConstructorInterceptV2Point.java @@ -38,7 +38,7 @@ public interface ConstructorInterceptV2Point extends InterceptPoint { */ String getConstructorInterceptorV2(); - default int hashcode() { + default int computeHashCode() { return Objects.hash(this.getClass().getName(), this.getConstructorMatcher().toString(), this.getConstructorInterceptorV2()); } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/InstanceMethodsInterceptV2Point.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/InstanceMethodsInterceptV2Point.java index 44115caffc..920415f5e4 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/InstanceMethodsInterceptV2Point.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/InstanceMethodsInterceptV2Point.java @@ -47,7 +47,7 @@ public interface InstanceMethodsInterceptV2Point extends InterceptPoint { boolean isOverrideArgs(); - default int hashcode() { + default int computeHashCode() { return Objects.hash(this.getClass().getName(), this.getMethodsMatcher().toString(), this.getMethodsInterceptorV2(), this.isOverrideArgs()); } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/StaticMethodsInterceptV2Point.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/StaticMethodsInterceptV2Point.java index 000a4cbfce..481f574f3e 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/StaticMethodsInterceptV2Point.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/StaticMethodsInterceptV2Point.java @@ -47,7 +47,7 @@ public interface StaticMethodsInterceptV2Point extends InterceptPoint { boolean isOverrideArgs(); - default int hashcode() { + default int computeHashCode() { return Objects.hash(this.getClass().getName(), this.getMethodsMatcher().toString(), this.getMethodsInterceptorV2(), this.isOverrideArgs()); } } From 64b29166e3ef2cd6b978c9c55f31de5897c6fdce Mon Sep 17 00:00:00 2001 From: Gong Dewei Date: Sat, 24 Jun 2023 13:43:19 +0800 Subject: [PATCH 17/24] Extract InterceptPointUtil --- .../ConstructorInterceptPoint.java | 6 -- .../InstanceMethodsInterceptPoint.java | 6 -- .../plugin/interceptor/InterceptPoint.java | 2 - .../StaticMethodsInterceptPoint.java | 6 -- .../enhance/DelegateNamingResolver.java | 3 +- .../v2/ConstructorInterceptV2Point.java | 7 --- .../v2/InstanceMethodsInterceptV2Point.java | 6 -- .../v2/StaticMethodsInterceptV2Point.java | 6 -- .../agent/core/util/InterceptPointUtil.java | 62 +++++++++++++++++++ 9 files changed, 64 insertions(+), 40 deletions(-) create mode 100644 apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/util/InterceptPointUtil.java diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/ConstructorInterceptPoint.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/ConstructorInterceptPoint.java index 80e5f230d4..0875f2e99a 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/ConstructorInterceptPoint.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/ConstructorInterceptPoint.java @@ -21,8 +21,6 @@ import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.matcher.ElementMatcher; -import java.util.Objects; - /** * One of the three "Intercept Point". "Intercept Point" is a definition about where and how intercept happens. In this * "Intercept Point", the definition targets class's constructors, and the interceptor. @@ -43,8 +41,4 @@ public interface ConstructorInterceptPoint extends InterceptPoint { * org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor} */ String getConstructorInterceptor(); - - default int computeHashCode() { - return Objects.hash(this.getClass().getName(), this.getConstructorMatcher().toString(), this.getConstructorInterceptor()); - } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InstanceMethodsInterceptPoint.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InstanceMethodsInterceptPoint.java index eeae41e477..14e6a62728 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InstanceMethodsInterceptPoint.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InstanceMethodsInterceptPoint.java @@ -21,8 +21,6 @@ import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.matcher.ElementMatcher; -import java.util.Objects; - /** * One of the three "Intercept Point". "Intercept Point" is a definition about where and how intercept happens. In this * "Intercept Point", the definition targets class's instance methods, and the interceptor. @@ -44,8 +42,4 @@ public interface InstanceMethodsInterceptPoint extends InterceptPoint { String getMethodsInterceptor(); boolean isOverrideArgs(); - - default int computeHashCode() { - return Objects.hash(this.getClass().getName(), this.getMethodsMatcher().toString(), this.getMethodsInterceptor(), this.isOverrideArgs()); - } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InterceptPoint.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InterceptPoint.java index a50e7698e5..26e863e5f2 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InterceptPoint.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InterceptPoint.java @@ -19,6 +19,4 @@ public interface InterceptPoint { - int computeHashCode(); - } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/StaticMethodsInterceptPoint.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/StaticMethodsInterceptPoint.java index 3254455149..906e9b0311 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/StaticMethodsInterceptPoint.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/StaticMethodsInterceptPoint.java @@ -21,8 +21,6 @@ import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.matcher.ElementMatcher; -import java.util.Objects; - /** * One of the three "Intercept Point". "Intercept Point" is a definition about where and how intercept happens. In this * "Intercept Point", the definition targets class's static methods, and the interceptor. @@ -44,8 +42,4 @@ public interface StaticMethodsInterceptPoint extends InterceptPoint { String getMethodsInterceptor(); boolean isOverrideArgs(); - - default int computeHashCode() { - return Objects.hash(this.getClass().getName(), this.getMethodsMatcher().toString(), this.getMethodsInterceptor(), this.isOverrideArgs()); - } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java index ad30f9eac7..ce97c384b6 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java @@ -22,6 +22,7 @@ import org.apache.skywalking.apm.agent.core.conf.Constants; import org.apache.skywalking.apm.agent.core.plugin.AbstractClassEnhancePluginDefine; import org.apache.skywalking.apm.agent.core.plugin.interceptor.InterceptPoint; +import org.apache.skywalking.apm.agent.core.util.InterceptPointUtil; import java.util.Objects; @@ -40,6 +41,6 @@ public DelegateNamingResolver(String className, AbstractClassEnhancePluginDefine public String resolve(InterceptPoint interceptPoint) { Objects.requireNonNull(interceptPoint, "interceptPoint cannot be null"); - return fieldNamePrefix + RandomString.hashOf(interceptPoint.computeHashCode()); + return fieldNamePrefix + RandomString.hashOf(InterceptPointUtil.computeHashCode(interceptPoint)); } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/ConstructorInterceptV2Point.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/ConstructorInterceptV2Point.java index 5469ee7dc8..22ba5f8fa1 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/ConstructorInterceptV2Point.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/ConstructorInterceptV2Point.java @@ -21,8 +21,6 @@ import net.bytebuddy.matcher.ElementMatcher; import org.apache.skywalking.apm.agent.core.plugin.interceptor.InterceptPoint; -import java.util.Objects; - public interface ConstructorInterceptV2Point extends InterceptPoint { /** @@ -37,9 +35,4 @@ public interface ConstructorInterceptV2Point extends InterceptPoint { * org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor} */ String getConstructorInterceptorV2(); - - default int computeHashCode() { - return Objects.hash(this.getClass().getName(), this.getConstructorMatcher().toString(), this.getConstructorInterceptorV2()); - } - } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/InstanceMethodsInterceptV2Point.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/InstanceMethodsInterceptV2Point.java index 920415f5e4..0390639aab 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/InstanceMethodsInterceptV2Point.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/InstanceMethodsInterceptV2Point.java @@ -23,8 +23,6 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; import org.apache.skywalking.apm.agent.core.plugin.interceptor.InterceptPoint; -import java.util.Objects; - /** * One of the three "Intercept Point". "Intercept Point" is a definition about where and how intercept happens. In this * "Intercept Point", the definition targets class's instance methods, and the interceptor. @@ -46,8 +44,4 @@ public interface InstanceMethodsInterceptV2Point extends InterceptPoint { String getMethodsInterceptorV2(); boolean isOverrideArgs(); - - default int computeHashCode() { - return Objects.hash(this.getClass().getName(), this.getMethodsMatcher().toString(), this.getMethodsInterceptorV2(), this.isOverrideArgs()); - } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/StaticMethodsInterceptV2Point.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/StaticMethodsInterceptV2Point.java index 481f574f3e..42c22b919e 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/StaticMethodsInterceptV2Point.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/StaticMethodsInterceptV2Point.java @@ -23,8 +23,6 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; import org.apache.skywalking.apm.agent.core.plugin.interceptor.InterceptPoint; -import java.util.Objects; - /** * One of the three "Intercept Point". "Intercept Point" is a definition about where and how intercept happens. In this * "Intercept Point", the definition targets class's static methods, and the interceptor. @@ -46,8 +44,4 @@ public interface StaticMethodsInterceptV2Point extends InterceptPoint { String getMethodsInterceptorV2(); boolean isOverrideArgs(); - - default int computeHashCode() { - return Objects.hash(this.getClass().getName(), this.getMethodsMatcher().toString(), this.getMethodsInterceptorV2(), this.isOverrideArgs()); - } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/util/InterceptPointUtil.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/util/InterceptPointUtil.java new file mode 100644 index 0000000000..b6ca1ee75d --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/util/InterceptPointUtil.java @@ -0,0 +1,62 @@ +/* + * 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.core.util; + +import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.InterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.StaticMethodsInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.v2.ConstructorInterceptV2Point; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.v2.InstanceMethodsInterceptV2Point; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.v2.StaticMethodsInterceptV2Point; + +import java.util.Objects; + +public class InterceptPointUtil { + + public static int computeHashCode(InterceptPoint interceptPoint) { + if (interceptPoint instanceof ConstructorInterceptPoint) { + ConstructorInterceptPoint point = (ConstructorInterceptPoint) interceptPoint; + return Objects.hash(point.getClass().getName(), point.getConstructorMatcher().toString(), + point.getConstructorInterceptor()); + } else if (interceptPoint instanceof ConstructorInterceptV2Point) { + ConstructorInterceptV2Point point = (ConstructorInterceptV2Point) interceptPoint; + return Objects.hash(point.getClass().getName(), point.getConstructorMatcher().toString(), + point.getConstructorInterceptorV2()); + } else if (interceptPoint instanceof InstanceMethodsInterceptPoint) { + InstanceMethodsInterceptPoint point = (InstanceMethodsInterceptPoint) interceptPoint; + return Objects.hash(point.getClass().getName(), point.getMethodsMatcher().toString(), + point.getMethodsInterceptor(), + point.isOverrideArgs()); + } else if (interceptPoint instanceof InstanceMethodsInterceptV2Point) { + InstanceMethodsInterceptV2Point point = (InstanceMethodsInterceptV2Point) interceptPoint; + return Objects.hash(point.getClass().getName(), point.getMethodsMatcher().toString(), + point.getMethodsInterceptorV2(), point.isOverrideArgs()); + } else if (interceptPoint instanceof StaticMethodsInterceptPoint) { + StaticMethodsInterceptPoint point = (StaticMethodsInterceptPoint) interceptPoint; + return Objects.hash(point.getClass().getName(), point.getMethodsMatcher().toString(), + point.getMethodsInterceptor(), point.isOverrideArgs()); + } else if (interceptPoint instanceof StaticMethodsInterceptV2Point) { + StaticMethodsInterceptV2Point point = (StaticMethodsInterceptV2Point) interceptPoint; + return Objects.hash(point.getClass().getName(), point.getMethodsMatcher().toString(), + point.getMethodsInterceptorV2(), point.isOverrideArgs()); + } + throw new UnsupportedOperationException("Unsupported compute hashcode for InterceptPoint: " + interceptPoint); + } + +} From 560ec88af432ad2bac9586d17ee34837a933fe71 Mon Sep 17 00:00:00 2001 From: Gong Dewei Date: Sat, 24 Jun 2023 14:01:46 +0800 Subject: [PATCH 18/24] Revert "Extract InterceptPointUtil" This reverts commit 64b29166e3ef2cd6b978c9c55f31de5897c6fdce. --- .../ConstructorInterceptPoint.java | 6 ++ .../InstanceMethodsInterceptPoint.java | 6 ++ .../plugin/interceptor/InterceptPoint.java | 2 + .../StaticMethodsInterceptPoint.java | 6 ++ .../enhance/DelegateNamingResolver.java | 3 +- .../v2/ConstructorInterceptV2Point.java | 7 +++ .../v2/InstanceMethodsInterceptV2Point.java | 6 ++ .../v2/StaticMethodsInterceptV2Point.java | 6 ++ .../agent/core/util/InterceptPointUtil.java | 62 ------------------- 9 files changed, 40 insertions(+), 64 deletions(-) delete mode 100644 apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/util/InterceptPointUtil.java diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/ConstructorInterceptPoint.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/ConstructorInterceptPoint.java index 0875f2e99a..80e5f230d4 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/ConstructorInterceptPoint.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/ConstructorInterceptPoint.java @@ -21,6 +21,8 @@ import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.matcher.ElementMatcher; +import java.util.Objects; + /** * One of the three "Intercept Point". "Intercept Point" is a definition about where and how intercept happens. In this * "Intercept Point", the definition targets class's constructors, and the interceptor. @@ -41,4 +43,8 @@ public interface ConstructorInterceptPoint extends InterceptPoint { * org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor} */ String getConstructorInterceptor(); + + default int computeHashCode() { + return Objects.hash(this.getClass().getName(), this.getConstructorMatcher().toString(), this.getConstructorInterceptor()); + } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InstanceMethodsInterceptPoint.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InstanceMethodsInterceptPoint.java index 14e6a62728..eeae41e477 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InstanceMethodsInterceptPoint.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InstanceMethodsInterceptPoint.java @@ -21,6 +21,8 @@ import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.matcher.ElementMatcher; +import java.util.Objects; + /** * One of the three "Intercept Point". "Intercept Point" is a definition about where and how intercept happens. In this * "Intercept Point", the definition targets class's instance methods, and the interceptor. @@ -42,4 +44,8 @@ public interface InstanceMethodsInterceptPoint extends InterceptPoint { String getMethodsInterceptor(); boolean isOverrideArgs(); + + default int computeHashCode() { + return Objects.hash(this.getClass().getName(), this.getMethodsMatcher().toString(), this.getMethodsInterceptor(), this.isOverrideArgs()); + } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InterceptPoint.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InterceptPoint.java index 26e863e5f2..a50e7698e5 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InterceptPoint.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InterceptPoint.java @@ -19,4 +19,6 @@ public interface InterceptPoint { + int computeHashCode(); + } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/StaticMethodsInterceptPoint.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/StaticMethodsInterceptPoint.java index 906e9b0311..3254455149 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/StaticMethodsInterceptPoint.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/StaticMethodsInterceptPoint.java @@ -21,6 +21,8 @@ import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.matcher.ElementMatcher; +import java.util.Objects; + /** * One of the three "Intercept Point". "Intercept Point" is a definition about where and how intercept happens. In this * "Intercept Point", the definition targets class's static methods, and the interceptor. @@ -42,4 +44,8 @@ public interface StaticMethodsInterceptPoint extends InterceptPoint { String getMethodsInterceptor(); boolean isOverrideArgs(); + + default int computeHashCode() { + return Objects.hash(this.getClass().getName(), this.getMethodsMatcher().toString(), this.getMethodsInterceptor(), this.isOverrideArgs()); + } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java index ce97c384b6..ad30f9eac7 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java @@ -22,7 +22,6 @@ import org.apache.skywalking.apm.agent.core.conf.Constants; import org.apache.skywalking.apm.agent.core.plugin.AbstractClassEnhancePluginDefine; import org.apache.skywalking.apm.agent.core.plugin.interceptor.InterceptPoint; -import org.apache.skywalking.apm.agent.core.util.InterceptPointUtil; import java.util.Objects; @@ -41,6 +40,6 @@ public DelegateNamingResolver(String className, AbstractClassEnhancePluginDefine public String resolve(InterceptPoint interceptPoint) { Objects.requireNonNull(interceptPoint, "interceptPoint cannot be null"); - return fieldNamePrefix + RandomString.hashOf(InterceptPointUtil.computeHashCode(interceptPoint)); + return fieldNamePrefix + RandomString.hashOf(interceptPoint.computeHashCode()); } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/ConstructorInterceptV2Point.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/ConstructorInterceptV2Point.java index 22ba5f8fa1..5469ee7dc8 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/ConstructorInterceptV2Point.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/ConstructorInterceptV2Point.java @@ -21,6 +21,8 @@ import net.bytebuddy.matcher.ElementMatcher; import org.apache.skywalking.apm.agent.core.plugin.interceptor.InterceptPoint; +import java.util.Objects; + public interface ConstructorInterceptV2Point extends InterceptPoint { /** @@ -35,4 +37,9 @@ public interface ConstructorInterceptV2Point extends InterceptPoint { * org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor} */ String getConstructorInterceptorV2(); + + default int computeHashCode() { + return Objects.hash(this.getClass().getName(), this.getConstructorMatcher().toString(), this.getConstructorInterceptorV2()); + } + } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/InstanceMethodsInterceptV2Point.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/InstanceMethodsInterceptV2Point.java index 0390639aab..920415f5e4 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/InstanceMethodsInterceptV2Point.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/InstanceMethodsInterceptV2Point.java @@ -23,6 +23,8 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; import org.apache.skywalking.apm.agent.core.plugin.interceptor.InterceptPoint; +import java.util.Objects; + /** * One of the three "Intercept Point". "Intercept Point" is a definition about where and how intercept happens. In this * "Intercept Point", the definition targets class's instance methods, and the interceptor. @@ -44,4 +46,8 @@ public interface InstanceMethodsInterceptV2Point extends InterceptPoint { String getMethodsInterceptorV2(); boolean isOverrideArgs(); + + default int computeHashCode() { + return Objects.hash(this.getClass().getName(), this.getMethodsMatcher().toString(), this.getMethodsInterceptorV2(), this.isOverrideArgs()); + } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/StaticMethodsInterceptV2Point.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/StaticMethodsInterceptV2Point.java index 42c22b919e..481f574f3e 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/StaticMethodsInterceptV2Point.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/StaticMethodsInterceptV2Point.java @@ -23,6 +23,8 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; import org.apache.skywalking.apm.agent.core.plugin.interceptor.InterceptPoint; +import java.util.Objects; + /** * One of the three "Intercept Point". "Intercept Point" is a definition about where and how intercept happens. In this * "Intercept Point", the definition targets class's static methods, and the interceptor. @@ -44,4 +46,8 @@ public interface StaticMethodsInterceptV2Point extends InterceptPoint { String getMethodsInterceptorV2(); boolean isOverrideArgs(); + + default int computeHashCode() { + return Objects.hash(this.getClass().getName(), this.getMethodsMatcher().toString(), this.getMethodsInterceptorV2(), this.isOverrideArgs()); + } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/util/InterceptPointUtil.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/util/InterceptPointUtil.java deleted file mode 100644 index b6ca1ee75d..0000000000 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/util/InterceptPointUtil.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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.core.util; - -import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; -import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; -import org.apache.skywalking.apm.agent.core.plugin.interceptor.InterceptPoint; -import org.apache.skywalking.apm.agent.core.plugin.interceptor.StaticMethodsInterceptPoint; -import org.apache.skywalking.apm.agent.core.plugin.interceptor.v2.ConstructorInterceptV2Point; -import org.apache.skywalking.apm.agent.core.plugin.interceptor.v2.InstanceMethodsInterceptV2Point; -import org.apache.skywalking.apm.agent.core.plugin.interceptor.v2.StaticMethodsInterceptV2Point; - -import java.util.Objects; - -public class InterceptPointUtil { - - public static int computeHashCode(InterceptPoint interceptPoint) { - if (interceptPoint instanceof ConstructorInterceptPoint) { - ConstructorInterceptPoint point = (ConstructorInterceptPoint) interceptPoint; - return Objects.hash(point.getClass().getName(), point.getConstructorMatcher().toString(), - point.getConstructorInterceptor()); - } else if (interceptPoint instanceof ConstructorInterceptV2Point) { - ConstructorInterceptV2Point point = (ConstructorInterceptV2Point) interceptPoint; - return Objects.hash(point.getClass().getName(), point.getConstructorMatcher().toString(), - point.getConstructorInterceptorV2()); - } else if (interceptPoint instanceof InstanceMethodsInterceptPoint) { - InstanceMethodsInterceptPoint point = (InstanceMethodsInterceptPoint) interceptPoint; - return Objects.hash(point.getClass().getName(), point.getMethodsMatcher().toString(), - point.getMethodsInterceptor(), - point.isOverrideArgs()); - } else if (interceptPoint instanceof InstanceMethodsInterceptV2Point) { - InstanceMethodsInterceptV2Point point = (InstanceMethodsInterceptV2Point) interceptPoint; - return Objects.hash(point.getClass().getName(), point.getMethodsMatcher().toString(), - point.getMethodsInterceptorV2(), point.isOverrideArgs()); - } else if (interceptPoint instanceof StaticMethodsInterceptPoint) { - StaticMethodsInterceptPoint point = (StaticMethodsInterceptPoint) interceptPoint; - return Objects.hash(point.getClass().getName(), point.getMethodsMatcher().toString(), - point.getMethodsInterceptor(), point.isOverrideArgs()); - } else if (interceptPoint instanceof StaticMethodsInterceptV2Point) { - StaticMethodsInterceptV2Point point = (StaticMethodsInterceptV2Point) interceptPoint; - return Objects.hash(point.getClass().getName(), point.getMethodsMatcher().toString(), - point.getMethodsInterceptorV2(), point.isOverrideArgs()); - } - throw new UnsupportedOperationException("Unsupported compute hashcode for InterceptPoint: " + interceptPoint); - } - -} From bbabc66db1f151477f11e39ab614508338643f1a Mon Sep 17 00:00:00 2001 From: Gong Dewei Date: Sat, 24 Jun 2023 14:07:07 +0800 Subject: [PATCH 19/24] overload resolve method --- .../ConstructorInterceptPoint.java | 2 +- .../InstanceMethodsInterceptPoint.java | 2 +- .../plugin/interceptor/InterceptPoint.java | 24 ------------- .../StaticMethodsInterceptPoint.java | 2 +- .../enhance/DelegateNamingResolver.java | 34 +++++++++++++++++-- .../v2/ConstructorInterceptV2Point.java | 3 +- .../v2/InstanceMethodsInterceptV2Point.java | 3 +- .../v2/StaticMethodsInterceptV2Point.java | 3 +- 8 files changed, 38 insertions(+), 35 deletions(-) delete mode 100644 apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InterceptPoint.java diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/ConstructorInterceptPoint.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/ConstructorInterceptPoint.java index 80e5f230d4..cb876ac448 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/ConstructorInterceptPoint.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/ConstructorInterceptPoint.java @@ -30,7 +30,7 @@ * ref to two others: {@link StaticMethodsInterceptPoint} and {@link InstanceMethodsInterceptPoint} *

*/ -public interface ConstructorInterceptPoint extends InterceptPoint { +public interface ConstructorInterceptPoint { /** * Constructor matcher * diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InstanceMethodsInterceptPoint.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InstanceMethodsInterceptPoint.java index eeae41e477..d4e29c10d7 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InstanceMethodsInterceptPoint.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InstanceMethodsInterceptPoint.java @@ -30,7 +30,7 @@ * ref to two others: {@link ConstructorInterceptPoint} and {@link StaticMethodsInterceptPoint} *

*/ -public interface InstanceMethodsInterceptPoint extends InterceptPoint { +public interface InstanceMethodsInterceptPoint { /** * class instance methods matcher. * diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InterceptPoint.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InterceptPoint.java deleted file mode 100644 index a50e7698e5..0000000000 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InterceptPoint.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * 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.core.plugin.interceptor; - -public interface InterceptPoint { - - int computeHashCode(); - -} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/StaticMethodsInterceptPoint.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/StaticMethodsInterceptPoint.java index 3254455149..64b6473360 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/StaticMethodsInterceptPoint.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/StaticMethodsInterceptPoint.java @@ -30,7 +30,7 @@ * ref to two others: {@link ConstructorInterceptPoint} and {@link InstanceMethodsInterceptPoint} *

*/ -public interface StaticMethodsInterceptPoint extends InterceptPoint { +public interface StaticMethodsInterceptPoint { /** * static methods matcher. * diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java index ad30f9eac7..8b4fe607ce 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/DelegateNamingResolver.java @@ -21,7 +21,12 @@ import net.bytebuddy.utility.RandomString; import org.apache.skywalking.apm.agent.core.conf.Constants; import org.apache.skywalking.apm.agent.core.plugin.AbstractClassEnhancePluginDefine; -import org.apache.skywalking.apm.agent.core.plugin.interceptor.InterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.StaticMethodsInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.v2.ConstructorInterceptV2Point; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.v2.InstanceMethodsInterceptV2Point; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.v2.StaticMethodsInterceptV2Point; import java.util.Objects; @@ -38,7 +43,32 @@ public DelegateNamingResolver(String className, AbstractClassEnhancePluginDefine this.fieldNamePrefix = Constants.NAME_TRAIT + PREFIX + RandomString.hashOf(className.hashCode()) + "$" + RandomString.hashOf(pluginDefine.hashCode()) + "$"; } - public String resolve(InterceptPoint interceptPoint) { + public String resolve(ConstructorInterceptPoint interceptPoint) { + Objects.requireNonNull(interceptPoint, "interceptPoint cannot be null"); + return fieldNamePrefix + RandomString.hashOf(interceptPoint.computeHashCode()); + } + + public String resolve(ConstructorInterceptV2Point interceptPoint) { + Objects.requireNonNull(interceptPoint, "interceptPoint cannot be null"); + return fieldNamePrefix + RandomString.hashOf(interceptPoint.computeHashCode()); + } + + public String resolve(InstanceMethodsInterceptPoint interceptPoint) { + Objects.requireNonNull(interceptPoint, "interceptPoint cannot be null"); + return fieldNamePrefix + RandomString.hashOf(interceptPoint.computeHashCode()); + } + + public String resolve(InstanceMethodsInterceptV2Point interceptPoint) { + Objects.requireNonNull(interceptPoint, "interceptPoint cannot be null"); + return fieldNamePrefix + RandomString.hashOf(interceptPoint.computeHashCode()); + } + + public String resolve(StaticMethodsInterceptPoint interceptPoint) { + Objects.requireNonNull(interceptPoint, "interceptPoint cannot be null"); + return fieldNamePrefix + RandomString.hashOf(interceptPoint.computeHashCode()); + } + + public String resolve(StaticMethodsInterceptV2Point interceptPoint) { Objects.requireNonNull(interceptPoint, "interceptPoint cannot be null"); return fieldNamePrefix + RandomString.hashOf(interceptPoint.computeHashCode()); } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/ConstructorInterceptV2Point.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/ConstructorInterceptV2Point.java index 5469ee7dc8..5dd90f7930 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/ConstructorInterceptV2Point.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/ConstructorInterceptV2Point.java @@ -19,11 +19,10 @@ import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.matcher.ElementMatcher; -import org.apache.skywalking.apm.agent.core.plugin.interceptor.InterceptPoint; import java.util.Objects; -public interface ConstructorInterceptV2Point extends InterceptPoint { +public interface ConstructorInterceptV2Point { /** * Constructor matcher diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/InstanceMethodsInterceptV2Point.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/InstanceMethodsInterceptV2Point.java index 920415f5e4..fb73dcfef5 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/InstanceMethodsInterceptV2Point.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/InstanceMethodsInterceptV2Point.java @@ -21,7 +21,6 @@ import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.matcher.ElementMatcher; import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; -import org.apache.skywalking.apm.agent.core.plugin.interceptor.InterceptPoint; import java.util.Objects; @@ -32,7 +31,7 @@ * ref to two others: {@link ConstructorInterceptPoint} and {@link StaticMethodsInterceptV2Point} *

*/ -public interface InstanceMethodsInterceptV2Point extends InterceptPoint { +public interface InstanceMethodsInterceptV2Point { /** * class instance methods matcher. * diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/StaticMethodsInterceptV2Point.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/StaticMethodsInterceptV2Point.java index 481f574f3e..d9c6555665 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/StaticMethodsInterceptV2Point.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/StaticMethodsInterceptV2Point.java @@ -21,7 +21,6 @@ import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.matcher.ElementMatcher; import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; -import org.apache.skywalking.apm.agent.core.plugin.interceptor.InterceptPoint; import java.util.Objects; @@ -32,7 +31,7 @@ * ref to two others: {@link ConstructorInterceptPoint} and {@link InstanceMethodsInterceptV2Point} *

*/ -public interface StaticMethodsInterceptV2Point extends InterceptPoint { +public interface StaticMethodsInterceptV2Point { /** * static methods matcher. * From ee80bfa60f4da93664651c5a387b310406728156 Mon Sep 17 00:00:00 2001 From: Gong Dewei Date: Sat, 24 Jun 2023 14:30:23 +0800 Subject: [PATCH 20/24] polish code --- .../skywalking/apm/agent/bytebuddy/SWClassFileLocator.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/SWClassFileLocator.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/SWClassFileLocator.java index 2d3c679ec9..0e815ab8c8 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/SWClassFileLocator.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/SWClassFileLocator.java @@ -111,6 +111,7 @@ private Resolution getResolution(String name) throws Exception { if (aClass == null) { return new Resolution.Illegal(name); } + // trigger re-transforming the target class, and receive bytecode in SWExtractionClassFileTransformer instrumentation.retransformClasses(new Class[]{aClass}); } finally { instrumentation.removeTransformer(classFileTransformer); @@ -140,16 +141,12 @@ private Class locateClass(String className) { } @Override - public void close() throws IOException { + public void close() { closed = true; queue.clear(); thread.interrupt(); } - public int getTimeoutSeconds() { - return timeoutSeconds; - } - public void setTimeoutSeconds(int timeoutSeconds) { this.timeoutSeconds = timeoutSeconds; } From 161cfc16bac456b0c893a11735211cb972e5b150 Mon Sep 17 00:00:00 2001 From: Gong Dewei Date: Sat, 24 Jun 2023 14:43:33 +0800 Subject: [PATCH 21/24] polish code --- .../agent/bytebuddy/SWClassFileLocator.java | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/SWClassFileLocator.java b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/SWClassFileLocator.java index 0e815ab8c8..564e4471aa 100644 --- a/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/SWClassFileLocator.java +++ b/apm-sniffer/bytebuddy-patch/src/test/java/org/apache/skywalking/apm/agent/bytebuddy/SWClassFileLocator.java @@ -34,20 +34,26 @@ * Get class bytecode from separate thread to bypass jdk limitation or bug: https://github.com/raphw/byte-buddy/issues/1434 */ public class SWClassFileLocator implements ClassFileLocator { - private static ILog LOGGER = LogManager.getLogger(SWClassFileLocator.class); + private static final ILog LOGGER = LogManager.getLogger(SWClassFileLocator.class); + private static final String[] TYPE_NAME_TRAITS = {"auxiliary$", "ByteBuddy$", "sw$"}; + private static final int DEFAULT_TIMEOUT_SECONDS = 2; private final ForInstrumentation.ClassLoadingDelegate classLoadingDelegate; - private Instrumentation instrumentation; - private ClassLoader classLoader; - private String[] typeNameTraits = {"auxiliary$", "ByteBuddy$", "sw$"}; - private BlockingQueue queue = new LinkedBlockingDeque<>(); - private Thread thread; - private int timeoutSeconds = 2; + private final Instrumentation instrumentation; + private final ClassLoader classLoader; + private final BlockingQueue queue = new LinkedBlockingDeque<>(); + private final Thread thread; + private final int timeoutSeconds; private volatile boolean closed; public SWClassFileLocator(Instrumentation instrumentation, ClassLoader classLoader) { + this(instrumentation, classLoader, DEFAULT_TIMEOUT_SECONDS); + } + + public SWClassFileLocator(Instrumentation instrumentation, ClassLoader classLoader, int resolveTimeoutSeconds) { this.instrumentation = instrumentation; this.classLoader = classLoader; + this.timeoutSeconds = resolveTimeoutSeconds; classLoadingDelegate = ForInstrumentation.ClassLoadingDelegate.ForDelegatingClassLoader.of(classLoader); // Use thread instead of ExecutorService here, avoiding conflicts with apm-jdk-threadpool-plugin @@ -94,7 +100,7 @@ public Resolution locate(String name) throws IOException { private boolean match(String name) { boolean matched = false; - for (String typeNameTrait : typeNameTraits) { + for (String typeNameTrait : TYPE_NAME_TRAITS) { if (name.contains(typeNameTrait)) { matched = true; break; @@ -147,10 +153,6 @@ public void close() { thread.interrupt(); } - public void setTimeoutSeconds(int timeoutSeconds) { - this.timeoutSeconds = timeoutSeconds; - } - private class ResolutionFutureTask { private CompletableFuture future; private String className; From c92f8d8f5adcb4553243b6c63260861fbc0e5017 Mon Sep 17 00:00:00 2001 From: Gong Dewei Date: Sat, 24 Jun 2023 15:01:43 +0800 Subject: [PATCH 22/24] update changes doc --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 52404c2dbd..c323acce3a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -12,6 +12,7 @@ Release Notes. * Fix the conflict between the logging kernel and the JDK threadpool plugin. * Fix the thread safety bug of finishing operation for the span named "SpringCloudGateway/sendRequest" * Fix NPE in guava-eventbus-plugin. +* Support re-transform/hot-swap classes with other java agents, and remove the obsolete cache enhanced class feature. #### Documentation From 5ab814abce0ae02262b1b09ea291ff85f8de4a7a Mon Sep 17 00:00:00 2001 From: Gong Dewei Date: Sat, 24 Jun 2023 15:08:31 +0800 Subject: [PATCH 23/24] add doc for intercept point hashcode --- .../agent/core/plugin/bytebuddy/AnnotationTypeNameMatch.java | 4 ++++ .../agent/core/plugin/bytebuddy/ArgumentTypeNameMatch.java | 4 ++++ .../apm/agent/core/plugin/bytebuddy/ReturnTypeNameMatch.java | 4 ++++ .../core/plugin/interceptor/ConstructorInterceptPoint.java | 5 +++++ .../plugin/interceptor/InstanceMethodsInterceptPoint.java | 5 +++++ .../core/plugin/interceptor/StaticMethodsInterceptPoint.java | 5 +++++ .../plugin/interceptor/v2/ConstructorInterceptV2Point.java | 5 +++++ .../interceptor/v2/InstanceMethodsInterceptV2Point.java | 5 +++++ .../plugin/interceptor/v2/StaticMethodsInterceptV2Point.java | 5 +++++ 9 files changed, 42 insertions(+) diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bytebuddy/AnnotationTypeNameMatch.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bytebuddy/AnnotationTypeNameMatch.java index f5aa7aacc3..8bfbe781aa 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bytebuddy/AnnotationTypeNameMatch.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bytebuddy/AnnotationTypeNameMatch.java @@ -55,6 +55,10 @@ public boolean matches(T target) { return target.getAnnotationType().asErasure().getName().equals(annotationTypeName); } + /** + * To ensure that the hashCode for recreating the XxxInterceptPoint instance is the same as the previous instance, + * each ElementMatcher implementation class needs to implement toString() method. + */ @Override public String toString() { return "AnnotationTypeNameMatch{" + diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bytebuddy/ArgumentTypeNameMatch.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bytebuddy/ArgumentTypeNameMatch.java index 60ee56d490..e2256cf460 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bytebuddy/ArgumentTypeNameMatch.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bytebuddy/ArgumentTypeNameMatch.java @@ -68,6 +68,10 @@ public boolean matches(MethodDescription target) { return false; } + /** + * To ensure that the hashCode for recreating the XxxInterceptPoint instance is the same as the previous instance, + * each ElementMatcher implementation class needs to implement toString() method. + */ @Override public String toString() { return "ArgumentTypeNameMatch{" + diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bytebuddy/ReturnTypeNameMatch.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bytebuddy/ReturnTypeNameMatch.java index 238e06a81f..d8c65a5f2f 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bytebuddy/ReturnTypeNameMatch.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bytebuddy/ReturnTypeNameMatch.java @@ -53,6 +53,10 @@ public boolean matches(MethodDescription target) { return target.getReturnType().asErasure().getName().equals(returnTypeName); } + /** + * To ensure that the hashCode for recreating the XxxInterceptPoint instance is the same as the previous instance, + * each ElementMatcher implementation class needs to implement toString() method. + */ @Override public String toString() { return "ReturnTypeNameMatch{" + diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/ConstructorInterceptPoint.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/ConstructorInterceptPoint.java index cb876ac448..200c1890e0 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/ConstructorInterceptPoint.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/ConstructorInterceptPoint.java @@ -44,6 +44,11 @@ public interface ConstructorInterceptPoint { */ String getConstructorInterceptor(); + /** + * To ensure that the hashCode for recreating the XxxInterceptPoint instance is the same as the previous instance, + * each ElementMatcher implementation class needs to implement toString() method. + * @return hashCode of this intercept point + */ default int computeHashCode() { return Objects.hash(this.getClass().getName(), this.getConstructorMatcher().toString(), this.getConstructorInterceptor()); } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InstanceMethodsInterceptPoint.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InstanceMethodsInterceptPoint.java index d4e29c10d7..aeb8bac5fe 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InstanceMethodsInterceptPoint.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/InstanceMethodsInterceptPoint.java @@ -45,6 +45,11 @@ public interface InstanceMethodsInterceptPoint { boolean isOverrideArgs(); + /** + * To ensure that the hashCode for recreating the XxxInterceptPoint instance is the same as the previous instance, + * each ElementMatcher implementation class needs to implement toString() method. + * @return hashCode of this intercept point + */ default int computeHashCode() { return Objects.hash(this.getClass().getName(), this.getMethodsMatcher().toString(), this.getMethodsInterceptor(), this.isOverrideArgs()); } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/StaticMethodsInterceptPoint.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/StaticMethodsInterceptPoint.java index 64b6473360..9e0eb2f4f2 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/StaticMethodsInterceptPoint.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/StaticMethodsInterceptPoint.java @@ -45,6 +45,11 @@ public interface StaticMethodsInterceptPoint { boolean isOverrideArgs(); + /** + * To ensure that the hashCode for recreating the XxxInterceptPoint instance is the same as the previous instance, + * each ElementMatcher implementation class needs to implement toString() method. + * @return hashCode of this intercept point + */ default int computeHashCode() { return Objects.hash(this.getClass().getName(), this.getMethodsMatcher().toString(), this.getMethodsInterceptor(), this.isOverrideArgs()); } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/ConstructorInterceptV2Point.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/ConstructorInterceptV2Point.java index 5dd90f7930..f494627890 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/ConstructorInterceptV2Point.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/ConstructorInterceptV2Point.java @@ -37,6 +37,11 @@ public interface ConstructorInterceptV2Point { */ String getConstructorInterceptorV2(); + /** + * To ensure that the hashCode for recreating the XxxInterceptPoint instance is the same as the previous instance, + * each ElementMatcher implementation class needs to implement toString() method. + * @return hashCode of this intercept point + */ default int computeHashCode() { return Objects.hash(this.getClass().getName(), this.getConstructorMatcher().toString(), this.getConstructorInterceptorV2()); } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/InstanceMethodsInterceptV2Point.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/InstanceMethodsInterceptV2Point.java index fb73dcfef5..18ed4b0beb 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/InstanceMethodsInterceptV2Point.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/InstanceMethodsInterceptV2Point.java @@ -46,6 +46,11 @@ public interface InstanceMethodsInterceptV2Point { boolean isOverrideArgs(); + /** + * To ensure that the hashCode for recreating the XxxInterceptPoint instance is the same as the previous instance, + * each ElementMatcher implementation class needs to implement toString() method. + * @return hashCode of this intercept point + */ default int computeHashCode() { return Objects.hash(this.getClass().getName(), this.getMethodsMatcher().toString(), this.getMethodsInterceptorV2(), this.isOverrideArgs()); } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/StaticMethodsInterceptV2Point.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/StaticMethodsInterceptV2Point.java index d9c6555665..a9fb4f9287 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/StaticMethodsInterceptV2Point.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/v2/StaticMethodsInterceptV2Point.java @@ -46,6 +46,11 @@ public interface StaticMethodsInterceptV2Point { boolean isOverrideArgs(); + /** + * To ensure that the hashCode for recreating the XxxInterceptPoint instance is the same as the previous instance, + * each ElementMatcher implementation class needs to implement toString() method. + * @return hashCode of this intercept point + */ default int computeHashCode() { return Objects.hash(this.getClass().getName(), this.getMethodsMatcher().toString(), this.getMethodsInterceptorV2(), this.isOverrideArgs()); } From 47bf95126cf706c745272b9aab3e8cac3856a9f8 Mon Sep 17 00:00:00 2001 From: Gong Dewei Date: Sat, 24 Jun 2023 18:07:44 +0800 Subject: [PATCH 24/24] verify subclass of ElementMatcher --- .../apm/agent/core/bytebuddy/ClassScan.java | 106 ++++++++++++++++++ .../ElementMatcherSubclassVerifyTest.java | 90 +++++++++++++++ 2 files changed, 196 insertions(+) create mode 100644 apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/bytebuddy/ClassScan.java create mode 100644 apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/bytebuddy/ElementMatcherSubclassVerifyTest.java diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/bytebuddy/ClassScan.java b/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/bytebuddy/ClassScan.java new file mode 100644 index 0000000000..fa927fc624 --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/bytebuddy/ClassScan.java @@ -0,0 +1,106 @@ +/* + * 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.core.bytebuddy; + +import com.google.common.collect.ImmutableSet; +import com.google.common.reflect.ClassPath; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.matcher.ElementMatcher; + +import java.util.Comparator; +import java.util.LinkedList; +import java.util.List; + +/** + * Scan the classes, and notify the listener(s) + */ +public class ClassScan { + + private final List listeners; + + public ClassScan() { + this.listeners = new LinkedList<>(); + } + + /** + * Register the callback listener + * + * @param listener to be called after class found + */ + public void registerListener(ClassScanListener listener) { + listeners.add(new ListenerCache(listener)); + } + + /** + * Begin to scan classes. + */ + public void scan() throws Exception { + ClassPath classpath = ClassPath.from(this.getClass().getClassLoader()); + ImmutableSet classes = classpath.getAllClasses(); + String packagePrefix = "org.apache.skywalking."; + for (ClassPath.ClassInfo classInfo : classes) { + if (!classInfo.getName().startsWith(packagePrefix)) { + continue; + } + Class aClass = classInfo.load(); + + for (ListenerCache listener : listeners) { + if (listener.classMatch().matches(TypeDescription.ForLoadedType.of(aClass))) { + listener.addMatch(aClass); + } + } + } + + for (ListenerCache listener : listeners) { + listener.complete(); + } + } + + public interface ClassScanListener { + + ElementMatcher classMatch(); + + void notify(Class aClass) throws Exception; + } + + private class ListenerCache { + private ClassScanListener listener; + private List> matchedClass; + + private ListenerCache(ClassScanListener listener) { + this.listener = listener; + matchedClass = new LinkedList<>(); + } + + private ElementMatcher classMatch() { + return this.listener.classMatch(); + } + + private void addMatch(Class aClass) { + matchedClass.add(aClass); + } + + private void complete() throws Exception { + matchedClass.sort(Comparator.comparing(Class::getName)); + for (Class aClass : matchedClass) { + listener.notify(aClass); + } + } + } +} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/bytebuddy/ElementMatcherSubclassVerifyTest.java b/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/bytebuddy/ElementMatcherSubclassVerifyTest.java new file mode 100644 index 0000000000..85e1c1dff8 --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/bytebuddy/ElementMatcherSubclassVerifyTest.java @@ -0,0 +1,90 @@ +/* + * 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.core.bytebuddy; + +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.DelegateNamingResolver; +import org.junit.Assert; +import org.junit.Test; + +import java.io.PrintStream; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +import static net.bytebuddy.matcher.ElementMatchers.hasSuperType; +import static net.bytebuddy.matcher.ElementMatchers.isAbstract; +import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith; +import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.not; + +/** + * Verify subclass of ElementMatcher make sure to impl 'toString()' method. + * see {@link InstanceMethodsInterceptPoint#computeHashCode()}, {@link DelegateNamingResolver} + */ +public class ElementMatcherSubclassVerifyTest { + + // ignore nest subclass inside PluginFinder + private final ElementMatcher ignoredClass = nameStartsWith("org.apache.skywalking.apm.agent.core.plugin.PluginFinder$"); + + @Test + public void test() throws Exception { + List> matchedCLasses = new ArrayList<>(); + ClassScan classScan = new ClassScan(); + classScan.registerListener(new ClassScan.ClassScanListener() { + @Override + public ElementMatcher classMatch() { + return hasSuperType(named(ElementMatcher.class.getName())).and(not(isAbstract())); + } + + @Override + public void notify(Class aClass) throws Exception { + if (ignoredClass.matches(TypeDescription.ForLoadedType.of(aClass))) { + return; + } + try { + // make sure subclass of ElementMatcher has implement "toString" method + Method toStringMethod = aClass.getDeclaredMethod("toString"); + } catch (NoSuchMethodException e) { + matchedCLasses.add(aClass); + } + } + }); + classScan.scan(); + + // print matched classes + PrintStream err = System.err; + for (Class aClass : matchedCLasses) { + String className = aClass.getName(); + if (!className.equals(BadMatcher.class.getName())) { + err.println("Requiring toString() method for subclass of ElementMatcher: " + className); + } + } + Assert.assertEquals(1, matchedCLasses.size()); + } + + public static class BadMatcher implements ElementMatcher { + @Override + public boolean matches(T target) { + return false; + } + } +}