diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/JavassistMethod.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/JavassistMethod.java index 950174b8d..486a4c592 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/JavassistMethod.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/JavassistMethod.java @@ -65,8 +65,8 @@ public class JavassistMethod implements InstrumentMethod { private final InstrumentClass declaringClass; private final MethodDescriptor descriptor; - // TODO fix inject InterceptorTypeDetector - private static final InterceptorTypeDetector INTERCEPTOR_TYPE_DETECTOR = new InterceptorTypeDetector(); + // TODO fix inject InterceptorDefinitionFactory + private static final InterceptorDefinitionFactory interceptorDefinitionFactory = new InterceptorDefinitionFactory(); public JavassistMethod(Instrumentor pluginContext, InterceptorRegistryBinder interceptorRegistryBinder, InstrumentClass declaringClass, CtBehavior behavior) { this.pluginContext = pluginContext; @@ -291,20 +291,14 @@ public class JavassistMethod implements InstrumentMethod { throw new NullPointerException("interceptor must not be null"); } - final InterceptorDefinition interceptorDefinition = INTERCEPTOR_TYPE_DETECTOR.getInterceptorDefinition(interceptor.getClass()); + final InterceptorDefinition interceptorDefinition = interceptorDefinitionFactory.createInterceptorDefinition(interceptor.getClass()); - StringBuilder initVars = new StringBuilder(); - String interceptorInstanceVar = InvokeCodeGenerator.getInterceptorVar(interceptorId); - addLocalVariable(interceptorInstanceVar, Interceptor.class); - initVars.append(interceptorInstanceVar); - initVars.append(" = null;"); - - int originalCodeOffset = insertBefore(-1, initVars.toString()); + final String localVariableName = initializeLocalVariable(interceptorId); + int originalCodeOffset = insertBefore(-1, localVariableName); boolean localVarsInitialized = false; - int offset = addBeforeInterceptor(interceptorDefinition, interceptorId, originalCodeOffset); - + final int offset = addBeforeInterceptor(interceptorDefinition, interceptorId, originalCodeOffset); if (offset != -1) { localVarsInitialized = true; originalCodeOffset = offset; @@ -312,25 +306,26 @@ public class JavassistMethod implements InstrumentMethod { addAfterInterceptor(interceptorDefinition, interceptorId, localVarsInitialized, originalCodeOffset); } - - private static Method findMethod(Class interceptorClass, String name) { - for (Method m : interceptorClass.getMethods()) { - if (m.getName().equals(name)) { - return m; - } - } - return null; + private String initializeLocalVariable(int interceptorId) throws CannotCompileException, NotFoundException { + + final String interceptorInstanceVar = InvokeCodeGenerator.getInterceptorVar(interceptorId); + addLocalVariable(interceptorInstanceVar, Interceptor.class); + + final StringBuilder initVars = new StringBuilder(); + initVars.append(interceptorInstanceVar); + initVars.append(" = null;"); + return initVars.toString(); } - private void addAfterInterceptor(InterceptorDefinition interceptor, int interceptorId, boolean localVarsInitialized, int originalCodeOffset) throws NotFoundException, CannotCompileException { + private void addAfterInterceptor(InterceptorDefinition interceptorDefinition, int interceptorId, boolean localVarsInitialized, int originalCodeOffset) throws NotFoundException, CannotCompileException { - final Class interceptorClass = interceptor.getInterceptorClazz(); - final CaptureType captureType = interceptor.getCaptureType(); + final Class interceptorClass = interceptorDefinition.getInterceptorClass(); + final CaptureType captureType = interceptorDefinition.getCaptureType(); if (!isAfterInterceptor(captureType)) { return; } - final Method interceptorMethod = interceptor.getAfterMethod(); + final Method interceptorMethod = interceptorDefinition.getAfterMethod(); if (interceptorMethod == null) { if (isDebug) { @@ -338,9 +333,8 @@ public class JavassistMethod implements InstrumentMethod { } return; } - - - InvokeAfterCodeGenerator catchGenerator = new InvokeAfterCodeGenerator(interceptorId, interceptorClass, interceptorMethod, declaringClass, this, pluginContext.getTraceContext(), localVarsInitialized, true); + + InvokeAfterCodeGenerator catchGenerator = new InvokeAfterCodeGenerator(interceptorId, interceptorDefinition, declaringClass, this, pluginContext.getTraceContext(), localVarsInitialized, true); String catchCode = catchGenerator.generate(); if (isDebug) { @@ -351,7 +345,7 @@ public class JavassistMethod implements InstrumentMethod { insertCatch(originalCodeOffset, catchCode, throwable, "$e"); - InvokeAfterCodeGenerator afterGenerator = new InvokeAfterCodeGenerator(interceptorId, interceptorClass, interceptorMethod, declaringClass, this, pluginContext.getTraceContext(), localVarsInitialized, false); + InvokeAfterCodeGenerator afterGenerator = new InvokeAfterCodeGenerator(interceptorId, interceptorDefinition, declaringClass, this, pluginContext.getTraceContext(), localVarsInitialized, false); final String afterCode = afterGenerator.generate(); if (isDebug) { @@ -365,23 +359,23 @@ public class JavassistMethod implements InstrumentMethod { return CaptureType.AFTER == captureType || CaptureType.AROUND == captureType; } - private int addBeforeInterceptor(InterceptorDefinition interceptor, int interceptorId, int pos) throws CannotCompileException, NotFoundException { - final Class interceptorClass = interceptor.getInterceptorClazz(); - final CaptureType captureType = interceptor.getCaptureType(); + private int addBeforeInterceptor(InterceptorDefinition interceptorDefinition, int interceptorId, int pos) throws CannotCompileException, NotFoundException { + final Class interceptorClass = interceptorDefinition.getInterceptorClass(); + final CaptureType captureType = interceptorDefinition.getCaptureType(); if (!isBeforeInterceptor(captureType)) { return -1; } - final Method interceptorMethod = interceptor.getBeforeMethod(); + final Method interceptorMethod = interceptorDefinition.getBeforeMethod(); if (interceptorMethod == null) { if (isDebug) { - logger.debug("Skip adding before interceptor because the interceptor doesn't have before method: {}", interceptorClass.getName()); + logger.debug("Skip adding before interceptorDefinition because the interceptorDefinition doesn't have before method: {}", interceptorClass.getName()); } return -1; } - InvokeBeforeCodeGenerator generator = new InvokeBeforeCodeGenerator(interceptorId, interceptorClass, interceptorMethod, declaringClass, this, pluginContext.getTraceContext()); - String beforeCode = generator.generate(); + final InvokeBeforeCodeGenerator generator = new InvokeBeforeCodeGenerator(interceptorId, interceptorDefinition, declaringClass, this, pluginContext.getTraceContext()); + final String beforeCode = generator.generate(); if (isDebug) { logger.debug("addBeforeInterceptor before behavior:{} code:{}", behavior.getLongName(), beforeCode); diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/interceptor/DefaultInterceptorDefinition.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/interceptor/DefaultInterceptorDefinition.java new file mode 100644 index 000000000..7dd9e7ed9 --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/interceptor/DefaultInterceptorDefinition.java @@ -0,0 +1,89 @@ +/* + * * + * * Copyright 2014 NAVER Corp. + * * Licensed 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 com.navercorp.pinpoint.profiler.instrument.interceptor; + +import com.navercorp.pinpoint.bootstrap.interceptor.Interceptor; + +import java.lang.reflect.Method; + +/** + * @author Woonduk Kang(emeroad) + */ +public class DefaultInterceptorDefinition implements InterceptorDefinition { + private final Class baseInterceptorClazz; + private final Class interceptorClazz; + private final InterceptorType interceptorType; + private final CaptureType captureType; + private final Method beforeMethod; + private final Method afterMethod; + + public DefaultInterceptorDefinition(Class baseInterceptorClazz, Class interceptorClazz, InterceptorType interceptorType, CaptureType captureType, Method beforeMethod, Method afterMethod) { + if (baseInterceptorClazz == null) { + throw new NullPointerException("baseInterceptorClazz must not be null"); + } + if (interceptorClazz == null) { + throw new NullPointerException("interceptorClazz must not be null"); + } + if (interceptorType == null) { + throw new NullPointerException("interceptorType must not be null"); + } + if (captureType == null) { + throw new NullPointerException("captureType must not be null"); + } + this.baseInterceptorClazz = baseInterceptorClazz; + this.interceptorClazz = interceptorClazz; + this.interceptorType = interceptorType; + this.captureType = captureType; + this.beforeMethod = beforeMethod; + this.afterMethod = afterMethod; + } + + @Override + public Class getInterceptorBaseClass() { + return baseInterceptorClazz; + } + + + @Override + public Class getInterceptorClass() { + return interceptorClazz; + } + + @Override + public InterceptorType getInterceptorType() { + return interceptorType; + } + + + @Override + public CaptureType getCaptureType() { + return captureType; + } + + @Override + public Method getBeforeMethod() { + return beforeMethod; + } + + @Override + public Method getAfterMethod() { + return afterMethod; + } + + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/interceptor/InterceptorDefinition.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/interceptor/InterceptorDefinition.java index 82a9706d2..9827f5dad 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/interceptor/InterceptorDefinition.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/interceptor/InterceptorDefinition.java @@ -17,55 +17,23 @@ package com.navercorp.pinpoint.profiler.instrument.interceptor; +import com.navercorp.pinpoint.bootstrap.interceptor.Interceptor; + import java.lang.reflect.Method; /** * @author Woonduk Kang(emeroad) */ -public class InterceptorDefinition { - private final Class interceptorClazz; - private final InterceptorType interceptorType; - private final CaptureType captureType; - private final Method beforeMethod; - private final Method afterMethod; +public interface InterceptorDefinition { + Class getInterceptorBaseClass(); - public InterceptorDefinition(Class interceptorClazz, InterceptorType interceptorType, CaptureType captureType, Method beforeMethod, Method afterMethod) { - if (interceptorClazz == null) { - throw new NullPointerException("interceptorClazz must not be null"); - } - if (interceptorType == null) { - throw new NullPointerException("interceptorType must not be null"); - } - if (captureType == null) { - throw new NullPointerException("captureType must not be null"); - } - this.interceptorClazz = interceptorClazz; - this.interceptorType = interceptorType; - this.captureType = captureType; - this.beforeMethod = beforeMethod; - this.afterMethod = afterMethod; - } + Class getInterceptorClass(); - public Class getInterceptorClazz() { - return interceptorClazz; - } + InterceptorType getInterceptorType(); - public InterceptorType getInterceptorType() { - return interceptorType; - } - - - public CaptureType getCaptureType() { - return captureType; - } - - public Method getBeforeMethod() { - return beforeMethod; - } - - public Method getAfterMethod() { - return afterMethod; - } + CaptureType getCaptureType(); + Method getBeforeMethod(); + Method getAfterMethod(); } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/interceptor/InterceptorTypeDetector.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/interceptor/InterceptorDefinitionFactory.java similarity index 62% rename from profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/interceptor/InterceptorTypeDetector.java rename to profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/interceptor/InterceptorDefinitionFactory.java index c1f57e2e5..1666daf7a 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/interceptor/InterceptorTypeDetector.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/interceptor/InterceptorDefinitionFactory.java @@ -19,6 +19,7 @@ package com.navercorp.pinpoint.profiler.instrument.interceptor; import com.navercorp.pinpoint.bootstrap.interceptor.*; import com.navercorp.pinpoint.bootstrap.interceptor.annotation.IgnoreMethod; +import com.navercorp.pinpoint.profiler.util.Maps; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -26,23 +27,25 @@ import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Map; /** * @author Woonduk Kang(emeroad) */ -public class InterceptorTypeDetector { +public class InterceptorDefinitionFactory { private final Logger logger = LoggerFactory.getLogger(this.getClass()); - private final List detectHandlers = new ArrayList(); + private final List detectHandlers; - public InterceptorTypeDetector() { - register(); + public InterceptorDefinitionFactory() { + this.detectHandlers = register(); } - public InterceptorDefinition getInterceptorDefinition(Class interceptorClazz) { + public InterceptorDefinition createInterceptorDefinition(Class interceptorClazz) { if (interceptorClazz == null) { - throw new NullPointerException("interceptorClazz must not be null"); + throw new NullPointerException("targetInterceptorClazz must not be null"); } + for (TypeHandler typeHandler : detectHandlers) { final InterceptorDefinition interceptorDefinition = typeHandler.resolveType(interceptorClazz); if (interceptorDefinition != null) { @@ -53,43 +56,34 @@ public class InterceptorTypeDetector { } - private void register() { + private List register() { + final List typeHandlerList = new ArrayList(); - TypeHandler around = createInterceptorTypeHandler(AroundInterceptor.class, InterceptorType.ARRAY_ARGS); - add(around); + addTypeHandler(typeHandlerList, AroundInterceptor.class, InterceptorType.ARRAY_ARGS); - TypeHandler around0 = createInterceptorTypeHandler(AroundInterceptor0.class, InterceptorType.BASIC); - add(around0); + addTypeHandler(typeHandlerList, AroundInterceptor0.class, InterceptorType.BASIC); + addTypeHandler(typeHandlerList, AroundInterceptor1.class, InterceptorType.BASIC); + addTypeHandler(typeHandlerList, AroundInterceptor2.class, InterceptorType.BASIC); + addTypeHandler(typeHandlerList, AroundInterceptor3.class, InterceptorType.BASIC); + addTypeHandler(typeHandlerList, AroundInterceptor4.class, InterceptorType.BASIC); + addTypeHandler(typeHandlerList, AroundInterceptor5.class, InterceptorType.BASIC); - TypeHandler around1 = createInterceptorTypeHandler(AroundInterceptor1.class, InterceptorType.BASIC); - add(around1); - TypeHandler around2 = createInterceptorTypeHandler(AroundInterceptor2.class, InterceptorType.BASIC); - add(around2); + addTypeHandler(typeHandlerList, StaticAroundInterceptor.class, InterceptorType.STATIC); - TypeHandler around3 = createInterceptorTypeHandler(AroundInterceptor3.class, InterceptorType.BASIC); - add(around3); + addTypeHandler(typeHandlerList, ApiIdAwareAroundInterceptor.class, InterceptorType.API_ID_AWARE); - TypeHandler around4 = createInterceptorTypeHandler(AroundInterceptor4.class, InterceptorType.BASIC); - add(around4); - - TypeHandler around5 = createInterceptorTypeHandler(AroundInterceptor5.class, InterceptorType.BASIC); - add(around5); - - TypeHandler staticAround = createInterceptorTypeHandler(StaticAroundInterceptor.class, InterceptorType.STATIC); - add(staticAround); - - TypeHandler apiIdAwareAroundInterceptor = createInterceptorTypeHandler(ApiIdAwareAroundInterceptor.class, InterceptorType.API_ID_AWARE); - add(apiIdAwareAroundInterceptor); + return typeHandlerList; } - private void add(TypeHandler around) { - this.detectHandlers.add(around); + private void addTypeHandler(List typeHandlerList, Class interceptorClazz, InterceptorType arrayArgs) { + final TypeHandler typeHandler = createInterceptorTypeHandler(interceptorClazz, arrayArgs); + typeHandlerList.add(typeHandler); } private TypeHandler createInterceptorTypeHandler(Class interceptorClazz, InterceptorType interceptorType) { if (interceptorClazz == null) { - throw new NullPointerException("interceptorClazz must not be null"); + throw new NullPointerException("targetInterceptorClazz must not be null"); } if (interceptorType == null) { throw new NullPointerException("interceptorType must not be null"); @@ -113,32 +107,34 @@ public class InterceptorTypeDetector { private Method findMethodByName(Method[] declaredMethods, String methodName) { Method findMethod = null; + int count = 0; for (Method method : declaredMethods) { if (method.getName().equals(methodName)) { - if (findMethod != null) { - throw new RuntimeException("duplicated method exist. methodName:" + methodName); - } + count++; findMethod = method; } } if (findMethod == null) { throw new RuntimeException(methodName + " not found"); } + if (count > 1 ) { + throw new RuntimeException("duplicated method exist. methodName:" + methodName); + } return findMethod; } private class TypeHandler { - private final Class interceptorClazz; + private final Class interceptorClazz; private final InterceptorType interceptorType; private final String before; private final Class[] beforeParamList; private final String after; private final Class[] afterParamList; - public TypeHandler(Class interceptorClazz, InterceptorType interceptorType, String before, final Class[] beforeParamList, final String after, final Class[] afterParamList) { + public TypeHandler(Class interceptorClazz, InterceptorType interceptorType, String before, final Class[] beforeParamList, final String after, final Class[] afterParamList) { if (interceptorClazz == null) { - throw new NullPointerException("interceptorClazz must not be null"); + throw new NullPointerException("targetInterceptorClazz must not be null"); } if (interceptorType == null) { throw new NullPointerException("interceptorType must not be null"); @@ -168,19 +164,21 @@ public class InterceptorTypeDetector { if(!this.interceptorClazz.isAssignableFrom(targetClazz)) { return null; } - return createInterceptorDefinition(targetClazz); + @SuppressWarnings("unchecked") + final Class casting = (Class) targetClazz; + return createInterceptorDefinition(casting); } - private InterceptorDefinition createInterceptorDefinition(Class interceptorClazz) { + private InterceptorDefinition createInterceptorDefinition(Class targetInterceptorClazz) { - final Method beforeMethod = searchMethod(interceptorClazz, before, beforeParamList); + final Method beforeMethod = searchMethod(targetInterceptorClazz, before, beforeParamList); if (beforeMethod == null) { throw new RuntimeException(before + " method not found. " + Arrays.toString(beforeParamList)); } final boolean beforeIgnoreMethod = beforeMethod.isAnnotationPresent(IgnoreMethod.class); - final Method afterMethod = searchMethod(interceptorClazz, after, afterParamList); + final Method afterMethod = searchMethod(targetInterceptorClazz, after, afterParamList); if (afterMethod == null) { throw new RuntimeException(after + " method not found. " + Arrays.toString(afterParamList)); } @@ -188,15 +186,15 @@ public class InterceptorTypeDetector { if (beforeIgnoreMethod == false && afterIgnoreMethod == false) { - return new InterceptorDefinition(interceptorClazz, interceptorType, CaptureType.AROUND, beforeMethod, afterMethod); + return new DefaultInterceptorDefinition(interceptorClazz, targetInterceptorClazz, interceptorType, CaptureType.AROUND, beforeMethod, afterMethod); } if (beforeIgnoreMethod == true) { - return new InterceptorDefinition(interceptorClazz, interceptorType, CaptureType.AFTER, null, afterMethod); + return new DefaultInterceptorDefinition(interceptorClazz, targetInterceptorClazz, interceptorType, CaptureType.AFTER, null, afterMethod); } if (afterIgnoreMethod == true) { - return new InterceptorDefinition(interceptorClazz, interceptorType, CaptureType.BEFORE, beforeMethod, null); + return new DefaultInterceptorDefinition(interceptorClazz, targetInterceptorClazz, interceptorType, CaptureType.BEFORE, beforeMethod, null); } - return new InterceptorDefinition(interceptorClazz, interceptorType, CaptureType.NON, null, null); + return new DefaultInterceptorDefinition(interceptorClazz, targetInterceptorClazz, interceptorType, CaptureType.NON, null, null); } private Method searchMethod(Class interceptorClazz, String searchMethodName, Class[] searchMethodParameter) { @@ -205,7 +203,7 @@ public class InterceptorTypeDetector { } // only DeclaredMethod search ? // try { -// return interceptorClazz.getDeclaredMethod(searchMethodName, searchMethodParameter); +// return targetInterceptorClazz.getDeclaredMethod(searchMethodName, searchMethodParameter); // } catch (NoSuchMethodException ex) { // logger.debug(searchMethodName + " DeclaredMethod not found. search parent class"); // } @@ -213,7 +211,7 @@ public class InterceptorTypeDetector { try { return interceptorClazz.getMethod(searchMethodName, searchMethodParameter); } catch (NoSuchMethodException ex) { - logger.debug(searchMethodName +"DeclaredMethod not found."); + logger.debug(searchMethodName +" DeclaredMethod not found."); } return null; } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/interceptor/InvokeAfterCodeGenerator.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/interceptor/InvokeAfterCodeGenerator.java index 8b95774aa..2e121d407 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/interceptor/InvokeAfterCodeGenerator.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/interceptor/InvokeAfterCodeGenerator.java @@ -29,24 +29,23 @@ public class InvokeAfterCodeGenerator extends InvokeCodeGenerator { private static final int THIS_RETURN_EXCEPTION_SIZE = 3; private final int interceptorId; - private final Method interceptorMethod; + private final InterceptorDefinition interceptorDefinition; private final InstrumentClass targetClass; private final boolean localVarsInitialized; private final boolean catchClause; - public InvokeAfterCodeGenerator(int interceptorId, Class interceptorClass, Method interceptorMethod, InstrumentClass targetClass, InstrumentMethod targetMethod, TraceContext traceContext, boolean localVarsInitialized, boolean catchClause) { - super(interceptorId, interceptorClass, targetMethod, traceContext); - + public InvokeAfterCodeGenerator(int interceptorId, InterceptorDefinition interceptorDefinition, InstrumentClass targetClass, InstrumentMethod targetMethod, TraceContext traceContext, boolean localVarsInitialized, boolean catchClause) { + super(interceptorId, interceptorDefinition, targetMethod, traceContext); + this.interceptorDefinition = interceptorDefinition; this.interceptorId = interceptorId; - this.interceptorMethod = interceptorMethod; this.targetClass = targetClass; this.localVarsInitialized = localVarsInitialized; this.catchClause = catchClause; } public String generate() { - CodeBuilder builder = new CodeBuilder(); - + final CodeBuilder builder = new CodeBuilder(); + builder.begin(); // try { @@ -56,25 +55,25 @@ public class InvokeAfterCodeGenerator extends InvokeCodeGenerator { // } // // throw e; - + builder.append("try { "); if (!localVarsInitialized) { builder.format("%1$s = %2$s.getInterceptor(%3$d); ", getInterceptorVar(), getInterceptorRegistryClassName(), interceptorId); - } - - if (interceptorMethod != null) { + } + final Method afterMethod = interceptorDefinition.getAfterMethod(); + if (afterMethod != null) { builder.format("((%1$s)%2$s).after(", getInterceptorType(), getInterceptorVar()); appendArguments(builder); builder.format(");"); } - + builder.format("} catch (java.lang.Throwable _$PINPOINT_EXCEPTION$_) { %1$s.handleException(_$PINPOINT_EXCEPTION$_); }", getInterceptorInvokerHelperClassName()); - + if (catchClause) { builder.append(" throw $e;"); } - + builder.end(); return builder.toString(); @@ -104,6 +103,7 @@ public class InvokeAfterCodeGenerator extends InvokeCodeGenerator { } private void appendArguments(CodeBuilder builder) { + final InterceptorType type = interceptorDefinition.getInterceptorType(); switch (type) { case ARRAY_ARGS: appendSimpleAfterArguments(builder); @@ -133,6 +133,7 @@ public class InvokeAfterCodeGenerator extends InvokeCodeGenerator { } private void appendCustomAfterArguments(CodeBuilder builder) { + final Method interceptorMethod = interceptorDefinition.getAfterMethod(); final Class[] interceptorParamTypes = interceptorMethod.getParameterTypes(); if (interceptorParamTypes.length == 0) { diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/interceptor/InvokeBeforeCodeGenerator.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/interceptor/InvokeBeforeCodeGenerator.java index a9c0be4df..701d69d47 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/interceptor/InvokeBeforeCodeGenerator.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/interceptor/InvokeBeforeCodeGenerator.java @@ -26,19 +26,17 @@ import com.navercorp.pinpoint.bootstrap.instrument.InstrumentMethod; */ public class InvokeBeforeCodeGenerator extends InvokeCodeGenerator { private final int interceptorId; - private final Method interceptorMethod; private final InstrumentClass targetClass; - public InvokeBeforeCodeGenerator(int interceptorId, Class interceptorClass, Method interceptorMethod, InstrumentClass targetClass, InstrumentMethod targetMethod, TraceContext traceContext) { - super(interceptorId, interceptorClass, targetMethod, traceContext); + public InvokeBeforeCodeGenerator(int interceptorId, InterceptorDefinition interceptorDefinition, InstrumentClass targetClass, InstrumentMethod targetMethod, TraceContext traceContext) { + super(interceptorId, interceptorDefinition, targetMethod, traceContext); this.interceptorId = interceptorId; - this.interceptorMethod = interceptorMethod; this.targetClass = targetClass; } public String generate() { - CodeBuilder builder = new CodeBuilder(); + final CodeBuilder builder = new CodeBuilder(); builder.begin(); @@ -51,8 +49,9 @@ public class InvokeBeforeCodeGenerator extends InvokeCodeGenerator { builder.append("try { "); builder.format("%1$s = %2$s.getInterceptor(%3$d); ", getInterceptorVar(), getInterceptorRegistryClassName(), interceptorId); - - if (interceptorMethod != null) { + + final Method beforeMethod = interceptorDefinition.getBeforeMethod(); + if (beforeMethod != null) { builder.format("((%1$s)%2$s).before(", getInterceptorType(), getInterceptorVar()); appendArguments(builder); builder.format(");"); @@ -66,6 +65,7 @@ public class InvokeBeforeCodeGenerator extends InvokeCodeGenerator { } private void appendArguments(CodeBuilder builder) { + final InterceptorType type = interceptorDefinition.getInterceptorType(); switch (type) { case ARRAY_ARGS: appendSimpleBeforeArguments(builder); @@ -95,7 +95,8 @@ public class InvokeBeforeCodeGenerator extends InvokeCodeGenerator { } private void appendCustomBeforeArguments(CodeBuilder builder) { - Class[] paramTypes = interceptorMethod.getParameterTypes(); + final Method interceptorMethod = interceptorDefinition.getBeforeMethod(); + final Class[] paramTypes = interceptorMethod.getParameterTypes(); if (paramTypes.length == 0) { return; diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/interceptor/InvokeCodeGenerator.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/interceptor/InvokeCodeGenerator.java index 0ae09b9b4..59f9f9887 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/interceptor/InvokeCodeGenerator.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/interceptor/InvokeCodeGenerator.java @@ -29,14 +29,13 @@ import com.navercorp.pinpoint.profiler.util.JavaAssistUtils; */ public class InvokeCodeGenerator { private final TraceContext traceContext; - protected final Class interceptorClass; + protected final InterceptorDefinition interceptorDefinition; protected final InstrumentMethod targetMethod; protected final int interceptorId; - protected final InterceptorType type; - public InvokeCodeGenerator(int interceptorId, Class interceptorClass, InstrumentMethod targetMethod, TraceContext traceContext) { - if (interceptorClass == null) { - throw new NullPointerException("interceptorClass must not be null"); + public InvokeCodeGenerator(int interceptorId, InterceptorDefinition interceptorDefinition, InstrumentMethod targetMethod, TraceContext traceContext) { + if (interceptorDefinition == null) { + throw new NullPointerException("interceptorDefinition must not be null"); } if (targetMethod == null) { throw new NullPointerException("targetMethod must not be null"); @@ -44,25 +43,17 @@ public class InvokeCodeGenerator { if (traceContext == null) { throw new NullPointerException("traceContext must not be null"); } - this.interceptorClass = interceptorClass; + + this.interceptorDefinition = interceptorDefinition; this.targetMethod = targetMethod; this.interceptorId = interceptorId; this.traceContext = traceContext; - // TODO remove - if (AroundInterceptor.class.isAssignableFrom(interceptorClass)) { - type = InterceptorType.ARRAY_ARGS; - } else if (StaticAroundInterceptor.class.isAssignableFrom(interceptorClass)) { - type = InterceptorType.STATIC; - } else if (ApiIdAwareAroundInterceptor.class.isAssignableFrom(interceptorClass)) { - type = InterceptorType.API_ID_AWARE; - } else { - type = InterceptorType.BASIC; - } } protected String getInterceptorType() { - return interceptorClass.getName(); +// return interceptorDefinition.getInterceptorClass().getName(); + return interceptorDefinition.getInterceptorBaseClass().getName(); } protected String getParameterTypes() { diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/instrument/interceptor/InterceptorCaptureTypeDetectorTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/instrument/interceptor/InterceptorDefinitionFactoryTest.java similarity index 57% rename from profiler/src/test/java/com/navercorp/pinpoint/profiler/instrument/interceptor/InterceptorCaptureTypeDetectorTest.java rename to profiler/src/test/java/com/navercorp/pinpoint/profiler/instrument/interceptor/InterceptorDefinitionFactoryTest.java index c7779735b..6a9c9b956 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/instrument/interceptor/InterceptorCaptureTypeDetectorTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/instrument/interceptor/InterceptorDefinitionFactoryTest.java @@ -30,33 +30,33 @@ import java.lang.reflect.Method; /** * @author Woonduk Kang(emeroad) */ -public class InterceptorCaptureTypeDetectorTest { +public class InterceptorDefinitionFactoryTest { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Test public void testGetInterceptorType_BasicType() throws Exception { - InterceptorTypeDetector typeDetector = new InterceptorTypeDetector(); + InterceptorDefinitionFactory typeDetector = new InterceptorDefinitionFactory(); - Assert.assertSame(typeDetector.getInterceptorDefinition(AroundInterceptor.class).getCaptureType(), CaptureType.AROUND); + Assert.assertSame(typeDetector.createInterceptorDefinition(AroundInterceptor.class).getCaptureType(), CaptureType.AROUND); - Assert.assertSame(typeDetector.getInterceptorDefinition(AroundInterceptor0.class).getCaptureType(), CaptureType.AROUND); - Assert.assertSame(typeDetector.getInterceptorDefinition(AroundInterceptor1.class).getCaptureType(), CaptureType.AROUND); - Assert.assertSame(typeDetector.getInterceptorDefinition(AroundInterceptor2.class).getCaptureType(), CaptureType.AROUND); - Assert.assertSame(typeDetector.getInterceptorDefinition(AroundInterceptor3.class).getCaptureType(), CaptureType.AROUND); - Assert.assertSame(typeDetector.getInterceptorDefinition(AroundInterceptor4.class).getCaptureType(), CaptureType.AROUND); - Assert.assertSame(typeDetector.getInterceptorDefinition(AroundInterceptor5.class).getCaptureType(), CaptureType.AROUND); + Assert.assertSame(typeDetector.createInterceptorDefinition(AroundInterceptor0.class).getCaptureType(), CaptureType.AROUND); + Assert.assertSame(typeDetector.createInterceptorDefinition(AroundInterceptor1.class).getCaptureType(), CaptureType.AROUND); + Assert.assertSame(typeDetector.createInterceptorDefinition(AroundInterceptor2.class).getCaptureType(), CaptureType.AROUND); + Assert.assertSame(typeDetector.createInterceptorDefinition(AroundInterceptor3.class).getCaptureType(), CaptureType.AROUND); + Assert.assertSame(typeDetector.createInterceptorDefinition(AroundInterceptor4.class).getCaptureType(), CaptureType.AROUND); + Assert.assertSame(typeDetector.createInterceptorDefinition(AroundInterceptor5.class).getCaptureType(), CaptureType.AROUND); - Assert.assertSame(typeDetector.getInterceptorDefinition(StaticAroundInterceptor.class).getCaptureType(), CaptureType.AROUND); + Assert.assertSame(typeDetector.createInterceptorDefinition(StaticAroundInterceptor.class).getCaptureType(), CaptureType.AROUND); - Assert.assertSame(typeDetector.getInterceptorDefinition(ApiIdAwareAroundInterceptor.class).getCaptureType(), CaptureType.AROUND); + Assert.assertSame(typeDetector.createInterceptorDefinition(ApiIdAwareAroundInterceptor.class).getCaptureType(), CaptureType.AROUND); } @Test public void testGetInterceptorType_Inherited() throws Exception { - InterceptorTypeDetector typeDetector = new InterceptorTypeDetector(); + InterceptorDefinitionFactory typeDetector = new InterceptorDefinitionFactory(); - Assert.assertSame(typeDetector.getInterceptorDefinition(InheritedAroundInterceptor.class).getCaptureType(), CaptureType.AROUND); + Assert.assertSame(typeDetector.createInterceptorDefinition(InheritedAroundInterceptor.class).getCaptureType(), CaptureType.AROUND); } @Test @@ -72,22 +72,22 @@ public class InterceptorCaptureTypeDetectorTest { @Test(expected = RuntimeException.class) public void testGetType_Error() throws Exception { - InterceptorTypeDetector typeDetector = new InterceptorTypeDetector(); - typeDetector.getInterceptorDefinition(Interceptor.class); + InterceptorDefinitionFactory typeDetector = new InterceptorDefinitionFactory(); + typeDetector.createInterceptorDefinition(Interceptor.class); } @Test public void testGetInterceptorCaptureType() throws Exception { - InterceptorTypeDetector interceptorTypeDetector = new InterceptorTypeDetector(); + InterceptorDefinitionFactory interceptorDefinitionFactory = new InterceptorDefinitionFactory(); - CaptureType before = interceptorTypeDetector.getInterceptorDefinition(TestBeforeInterceptor.class).getCaptureType(); + CaptureType before = interceptorDefinitionFactory.createInterceptorDefinition(TestBeforeInterceptor.class).getCaptureType(); Assert.assertSame(before, CaptureType.BEFORE); - CaptureType after = interceptorTypeDetector.getInterceptorDefinition(TestAfterInterceptor.class).getCaptureType(); + CaptureType after = interceptorDefinitionFactory.createInterceptorDefinition(TestAfterInterceptor.class).getCaptureType(); Assert.assertSame(after, CaptureType.AFTER); - CaptureType around = interceptorTypeDetector.getInterceptorDefinition(TestAroundInterceptor.class).getCaptureType(); + CaptureType around = interceptorDefinitionFactory.createInterceptorDefinition(TestAroundInterceptor.class).getCaptureType(); Assert.assertSame(around, CaptureType.AROUND); } diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/instrument/interceptor/InvokeAfterCodeGeneratorTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/instrument/interceptor/InvokeAfterCodeGeneratorTest.java index 17c33c87a..ed02acfe3 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/instrument/interceptor/InvokeAfterCodeGeneratorTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/instrument/interceptor/InvokeAfterCodeGeneratorTest.java @@ -18,8 +18,6 @@ package com.navercorp.pinpoint.profiler.instrument.interceptor; import static org.mockito.Mockito.*; -import java.lang.reflect.Method; - import org.junit.Assert; import org.junit.Test; import org.mockito.Mockito; @@ -38,13 +36,13 @@ import com.navercorp.pinpoint.bootstrap.interceptor.AroundInterceptor3; public class InvokeAfterCodeGeneratorTest { private final Logger logger = LoggerFactory.getLogger(this.getClass()); - + private final InterceptorDefinitionFactory interceptorDefinitionFactory = new InterceptorDefinitionFactory(); @Test public void testGenerate_AroundInterceptor3_catchClause() throws Exception { final Class aroundInterceptor3Class = AroundInterceptor3.class; - // this, param0, param1, param2, return, throwable - final Method interceptorAfter = aroundInterceptor3Class.getMethod("after", Object.class, Object.class, Object.class, Object.class, Object.class, Throwable.class); + final InterceptorDefinition interceptorDefinition = interceptorDefinitionFactory.createInterceptorDefinition(aroundInterceptor3Class); + final InstrumentClass mockClass = mock(InstrumentClass.class); Mockito.when(mockClass.getName()).thenReturn("TestClass"); @@ -56,7 +54,7 @@ public class InvokeAfterCodeGeneratorTest { TraceContext context = mock(TraceContext.class); - final InvokeAfterCodeGenerator invokeAfterCodeGenerator = new InvokeAfterCodeGenerator(100, aroundInterceptor3Class, interceptorAfter, mockClass, mockMethod, context, false, true); + final InvokeAfterCodeGenerator invokeAfterCodeGenerator = new InvokeAfterCodeGenerator(100, interceptorDefinition, mockClass, mockMethod, context, false, true); final String generate = invokeAfterCodeGenerator.generate(); logger.debug("testGenerate_AroundInterceptor3_catchClause:{}", generate); @@ -72,8 +70,8 @@ public class InvokeAfterCodeGeneratorTest { public void testGenerate_AroundInterceptor3_NoCatchClause() throws Exception { final Class aroundInterceptor3Class = AroundInterceptor3.class; - // this, param0, param1, param2, return, throwable - final Method interceptorAfter = aroundInterceptor3Class.getMethod("after", Object.class, Object.class, Object.class, Object.class, Object.class, Throwable.class); + final InterceptorDefinition interceptorDefinition = interceptorDefinitionFactory.createInterceptorDefinition(aroundInterceptor3Class); + final InstrumentClass mockClass = mock(InstrumentClass.class); Mockito.when(mockClass.getName()).thenReturn("TestClass"); @@ -84,7 +82,7 @@ public class InvokeAfterCodeGeneratorTest { TraceContext context = mock(TraceContext.class); - final InvokeAfterCodeGenerator invokeAfterCodeGenerator = new InvokeAfterCodeGenerator(100, aroundInterceptor3Class, interceptorAfter, mockClass, mockMethod, context, false, false); + final InvokeAfterCodeGenerator invokeAfterCodeGenerator = new InvokeAfterCodeGenerator(100, interceptorDefinition, mockClass, mockMethod, context, false, false); final String generate = invokeAfterCodeGenerator.generate(); logger.debug("testGenerate_AroundInterceptor3_NoCatchClause:{}", generate); @@ -100,8 +98,8 @@ public class InvokeAfterCodeGeneratorTest { public void testGenerate_AroundInterceptor3_methodParam2() throws Exception { final Class aroundInterceptor3Class = AroundInterceptor3.class; - // this, param0, param1, param2, return, throwable - final Method interceptorAfter = aroundInterceptor3Class.getMethod("after", Object.class, Object.class, Object.class, Object.class, Object.class, Throwable.class); + final InterceptorDefinition interceptorDefinition = interceptorDefinitionFactory.createInterceptorDefinition(aroundInterceptor3Class); + final InstrumentClass mockClass = mock(InstrumentClass.class); Mockito.when(mockClass.getName()).thenReturn("TestClass"); @@ -113,7 +111,7 @@ public class InvokeAfterCodeGeneratorTest { TraceContext context = mock(TraceContext.class); - final InvokeAfterCodeGenerator invokeAfterCodeGenerator = new InvokeAfterCodeGenerator(100, aroundInterceptor3Class, interceptorAfter, mockClass, mockMethod, context, false, true); + final InvokeAfterCodeGenerator invokeAfterCodeGenerator = new InvokeAfterCodeGenerator(100, interceptorDefinition, mockClass, mockMethod, context, false, true); final String generate = invokeAfterCodeGenerator.generate(); logger.debug("testGenerate_AroundInterceptor3_methodParam2:{}", generate); @@ -129,8 +127,8 @@ public class InvokeAfterCodeGeneratorTest { public void testGenerate_AroundInterceptor3_methodParam4() throws Exception { final Class aroundInterceptor3Class = AroundInterceptor3.class; - // this, param0, param1, param2, return, throwable - final Method interceptorAfter = aroundInterceptor3Class.getMethod("after", Object.class, Object.class, Object.class, Object.class, Object.class, Throwable.class); + final InterceptorDefinition interceptorDefinition = interceptorDefinitionFactory.createInterceptorDefinition(aroundInterceptor3Class); + final InstrumentClass mockClass = mock(InstrumentClass.class); Mockito.when(mockClass.getName()).thenReturn("TestClass"); @@ -141,7 +139,7 @@ public class InvokeAfterCodeGeneratorTest { TraceContext context = mock(TraceContext.class); - final InvokeAfterCodeGenerator invokeAfterCodeGenerator = new InvokeAfterCodeGenerator(100, aroundInterceptor3Class, interceptorAfter, mockClass, mockMethod, context, false, true); + final InvokeAfterCodeGenerator invokeAfterCodeGenerator = new InvokeAfterCodeGenerator(100, interceptorDefinition, mockClass, mockMethod, context, false, true); final String generate = invokeAfterCodeGenerator.generate(); logger.debug("testGenerate_AroundInterceptor3_methodParam4:{}", generate); @@ -159,8 +157,8 @@ public class InvokeAfterCodeGeneratorTest { public void testGenerate_AroundInterceptor0() throws Exception { final Class aroundInterceptor3Class = AroundInterceptor0.class; - // this, return, throwable - final Method interceptorAfter = aroundInterceptor3Class.getMethod("after", Object.class, Object.class, Throwable.class); + final InterceptorDefinition interceptorDefinition = interceptorDefinitionFactory.createInterceptorDefinition(aroundInterceptor3Class); + final InstrumentClass mockClass = mock(InstrumentClass.class); Mockito.when(mockClass.getName()).thenReturn("TestClass"); @@ -171,7 +169,7 @@ public class InvokeAfterCodeGeneratorTest { TraceContext context = mock(TraceContext.class); - final InvokeAfterCodeGenerator invokeAfterCodeGenerator = new InvokeAfterCodeGenerator(100, aroundInterceptor3Class, interceptorAfter, mockClass, mockMethod, context, false, true); + final InvokeAfterCodeGenerator invokeAfterCodeGenerator = new InvokeAfterCodeGenerator(100, interceptorDefinition, mockClass, mockMethod, context, false, true); final String generate = invokeAfterCodeGenerator.generate(); logger.debug("testGenerate_AroundInterceptor0:{}", generate);