@Test public void testDeclaredMethod() throws InstrumentException { JavassistClassPool pool = new JavassistClassPool(new GlobalInterceptorRegistryBinder(), null); String testObjectName = "com.navercorp.pinpoint.profiler.interceptor.bci.TestObject"; InstrumentClass testObject = pool.getClass(null, testObjectName, null); Assert.assertEquals(testObject.getName(), testObjectName); InstrumentMethod declaredMethod = testObject.getDeclaredMethod("callA", null); Assert.assertNotNull(declaredMethod); }
@Test public void hasEnclodingMethod() throws Exception { JavassistClassPool pool = new JavassistClassPool(new GlobalInterceptorRegistryBinder(), null); String testObjectName = "com.navercorp.pinpoint.profiler.interceptor.bci.TestObjectNestedClass"; InstrumentClass testObject = pool.getClass(null, testObjectName, null); Assert.assertEquals(testObject.getName(), testObjectName); assertEquals( 1, testObject .getNestedClasses( ClassFilters.enclosingMethod("enclosingMethod", "java.lang.String", "int")) .size()); assertEquals( 0, testObject.getNestedClasses(ClassFilters.enclosingMethod("enclosingMethod", "int")).size()); }
public byte[] modify( ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) { if (logger.isInfoEnabled()) { logger.info("Modifying. {}", javassistClassName); } try { InstrumentClass statementClass = byteCodeInstrumentor.getClass(classLoader, javassistClassName, classFileBuffer); Interceptor interceptor = new StatementExecuteQueryInterceptor(); statementClass.addGroupInterceptor( "executeQuery", new String[] {"java.lang.String"}, interceptor, MYSQLScope.SCOPE_NAME); // FIXME Interceptor executeUpdateInterceptor1 = new StatementExecuteUpdateInterceptor(); statementClass.addGroupInterceptor( "executeUpdate", new String[] {"java.lang.String"}, executeUpdateInterceptor1, MYSQLScope.SCOPE_NAME); Interceptor executeUpdateInterceptor2 = new StatementExecuteUpdateInterceptor(); statementClass.addGroupInterceptor( "executeUpdate", new String[] {"java.lang.String", "int"}, executeUpdateInterceptor2, MYSQLScope.SCOPE_NAME); Interceptor executeUpdateInterceptor3 = new StatementExecuteUpdateInterceptor(); statementClass.addGroupInterceptor( "execute", new String[] {"java.lang.String"}, executeUpdateInterceptor3, MYSQLScope.SCOPE_NAME); Interceptor executeUpdateInterceptor4 = new StatementExecuteUpdateInterceptor(); statementClass.addGroupInterceptor( "execute", new String[] {"java.lang.String", "int"}, executeUpdateInterceptor4, MYSQLScope.SCOPE_NAME); statementClass.addTraceValue(DatabaseInfoTraceValue.class); return statementClass.toBytecode(); } catch (InstrumentException e) { if (logger.isWarnEnabled()) { logger.warn("{} modify fail. Cause:{}", this.getClass().getSimpleName(), e.getMessage(), e); } return null; } }
@Test public void testClassHierarchy() throws InstrumentException { JavassistClassPool pool = new JavassistClassPool(new GlobalInterceptorRegistryBinder(), null); String testObjectName = "com.navercorp.pinpoint.profiler.interceptor.bci.TestObject"; // final CallLoader loader = null; // systemClassLoader // final ClassLoader loader = ClassLoader.getSystemClassLoader(); InstrumentClass testObject = pool.getClass(null, testObjectName, null); Assert.assertEquals(testObject.getName(), testObjectName); String testObjectSuperClass = testObject.getSuperClass(); Assert.assertEquals("java.lang.Object", testObjectSuperClass); String[] testObjectSuperClassInterfaces = testObject.getInterfaces(); Assert.assertEquals(testObjectSuperClassInterfaces.length, 0); InstrumentClass classHierarchyObject = pool.getClass( null, "com.navercorp.pinpoint.profiler.interceptor.bci.ClassHierarchyTestMock", null); String hierarchySuperClass = classHierarchyObject.getSuperClass(); Assert.assertEquals("java.util.HashMap", hierarchySuperClass); String[] hierarchyInterfaces = classHierarchyObject.getInterfaces(); Assert.assertEquals(hierarchyInterfaces.length, 2); Assert.assertEquals(hierarchyInterfaces[0], "java.lang.Runnable"); Assert.assertEquals(hierarchyInterfaces[1], "java.lang.Comparable"); }
@Override public byte[] transform( ClassLoader classLoader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { try { InstrumentClass target = context.getInstrumentClass(classLoader, className, classfileBuffer); recipe.edit(classLoader, target); return target.toBytecode(); } catch (PinpointException e) { throw e; } catch (Throwable e) { String msg = "Fail to invoke plugin class recipe: " + toString(); throw new PinpointException(msg, e); } }
/* (non-Javadoc) * @see com.navercorp.pinpoint.bootstrap.plugin.transformer.PinpointClassFileTransformer#transform(com.navercorp.pinpoint.bootstrap.plugin.PinpointInstrument, java.lang.ClassLoader, java.lang.String, java.lang.Class, java.security.ProtectionDomain, byte[]) */ @Override public byte[] transform( Instrumentor instrumentContext, ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws InstrumentException { if (logger.isInfoEnabled()) { logger.info("Modify {}", className); } try { InstrumentClass target = instrumentContext.getInstrumentClass(loader, className, classfileBuffer); if (!target.isInterceptable()) { return null; } List<InstrumentMethod> methodList = target.getDeclaredMethods(METHOD_FILTER); for (InstrumentMethod method : methodList) { if (logger.isTraceEnabled()) { logger.trace( "### c={}, m={}, params={}", new Object[] { className, method.getName(), Arrays.toString(method.getParameterTypes()) }); } method.addInterceptor( BasicMethodInterceptor.class.getName(), va(SpringBeansConstants.SERVICE_TYPE)); } return target.toBytecode(); } catch (Exception e) { logger.warn("modify fail. Cause:{}", e.getMessage(), e); return null; } }
@Test public void testDeclaredMethods() throws InstrumentException { JavassistClassPool pool = new JavassistClassPool(new GlobalInterceptorRegistryBinder(), null); String testObjectName = "com.navercorp.pinpoint.profiler.interceptor.bci.TestObject"; InstrumentClass testObject = pool.getClass(null, testObjectName, null); Assert.assertEquals(testObject.getName(), testObjectName); int findMethodCount = 0; for (InstrumentMethod methodInfo : testObject.getDeclaredMethods()) { if (!methodInfo.getName().equals("callA")) { continue; } String[] parameterTypes = methodInfo.getParameterTypes(); if (parameterTypes == null || parameterTypes.length == 0) { findMethodCount++; } } Assert.assertEquals(findMethodCount, 1); }
@Override public void edit(ClassLoader classLoader, InstrumentClass target) throws Throwable { for (InstrumentMethod targetMethod : target.getDeclaredMethods(filter)) { for (MethodRecipe recipe : recipes) { try { recipe.edit(classLoader, target, targetMethod); } catch (Throwable t) { if (exceptionHandler != null) { exceptionHandler.handle( target.getName(), targetMethod.getName(), targetMethod.getParameterTypes(), t); logger.info( "Exception thrown while editing" + targetMethod.getDescriptor().getApiDescriptor() + " but MethodTransformerExceptionHandler handled it.", t); } else { throw new InstrumentException( "Fail to edit method " + targetMethod.getDescriptor().getApiDescriptor(), t); } } } } }
@Override public byte[] doInTransform( Instrumentor instrumentor, ClassLoader classLoader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws InstrumentException { InstrumentClass target = instrumentor.getInstrumentClass(classLoader, className, classfileBuffer); target.addGetter( "com.navercorp.pinpoint.plugin.sample._13_RPC_Client.ServerAddressGetter", "serverAddress"); target.addGetter( "com.navercorp.pinpoint.plugin.sample._13_RPC_Client.ServerPortGetter", "serverPort"); target .getDeclaredMethod( "sendRequest", "com.navercorp.plugin.sample.target.TargetClass13_Request") .addInterceptor( "com.navercorp.pinpoint.plugin.sample._13_RPC_Client.SendRequestInterceptor"); return target.toBytecode(); }
@Test public void getNestedClasses() throws Exception { JavassistClassPool pool = new JavassistClassPool(new GlobalInterceptorRegistryBinder(), null); String testObjectName = "com.navercorp.pinpoint.profiler.interceptor.bci.TestObjectNestedClass"; InstrumentClass testObject = pool.getClass(null, testObjectName, null); Assert.assertEquals(testObject.getName(), testObjectName); // find class name condition. final String targetClassName = "com.navercorp.pinpoint.profiler.interceptor.bci.TestObjectNestedClass$InstanceInner"; for (InstrumentClass c : testObject.getNestedClasses(ClassFilters.name(targetClassName))) { assertEquals(targetClassName, c.getName()); } // find enclosing method condition. assertEquals( 2, testObject.getNestedClasses(ClassFilters.enclosingMethod("annonymousInnerClass")).size()); // find interface condition. assertEquals( 2, testObject .getNestedClasses(ClassFilters.interfaze("java.util.concurrent.Callable")) .size()); // find enclosing method & interface condition. assertEquals( 1, testObject .getNestedClasses( ClassFilters.chain( ClassFilters.enclosingMethod("annonymousInnerClass"), ClassFilters.interfaze("java.util.concurrent.Callable"))) .size()); }
@Override public void edit(ClassLoader classLoader, InstrumentClass target) throws InstrumentException { target.weave(aspectClassName, classLoader); }