/** * {@inheritDoc} */ @Override protected void initHook(Map<String, Object> parameters) { hook = new ClassLoadingDelegationHook(); }
/** * Delegates the class loading to the {@link #inspectItClassLoader} if the class name starts * with {@value #CLASS_NAME_PREFIX}. Otherwise loads the class with the target class loader. If * the inspectIT class loader throws {@link ClassNotFoundException}, the target class loader * will be used. * * @param classLoader * Class loader loading the class (object where the method is executed). * @param className * Class name. * @return Loaded class or <code>null</code> if it can not be found with inspectIT class loader. */ private Class<?> loadClass(Object classLoader, String className) { if (loadWithInspectItClassLoader(classLoader, className)) { try { return getInspectITClassLoader().loadClass(className); } catch (ClassNotFoundException e) { LOG.warn("Class " + className + " could not be loaded with the inspectIT class loader, although it has the correct prefix.", e); return null; } } else { return null; } }
/** * {@inheritDoc} */ @Override public Object beforeBody(long methodId, Object object, Object[] parameters, SpecialSensorConfig ssc) { return loadClass(object, parameters); }
@Test public void notExistingOurClass() { Object[] parameters = new String[] { "rocks.inspectit.agent.java.StupidClass" }; Object result = hook.beforeBody(METHOD_ID, object, parameters, ssc); assertThat(result, is(nullValue())); verifyZeroInteractions(object, ssc); }
@Test public void ignored() { long methodId = 11L; Object[] parameters = new Object[] {}; Object result = mock(Object.class); Object resultAfter = hook.afterBody(methodId, object, parameters, result, ssc); assertThat(resultAfter, is(nullValue())); verifyZeroInteractions(object, result, ssc); } }
@Test public void wrongParameterType() { Object[] parameters = new Long[] { 1L }; Object result = hook.beforeBody(METHOD_ID, object, parameters, ssc); assertThat(result, is(nullValue())); verifyZeroInteractions(object, ssc); }
@Test public void nullParameters() { Object[] parameters = null; Object result = hook.beforeBody(METHOD_ID, object, parameters, ssc); assertThat(result, is(nullValue())); verifyZeroInteractions(object, ssc); }
/** * Loads class with the given parameters that have been passed to the target class loader. * <p> * Loading will be delegated only if parameters are of size 1 and that single parameter is * String type. * * @see #loadClass(String) * @param classLoader * Class loader loading the class (object where the method is executed). * @param params * Original parameters passed to class loader. * @return Loaded class or <code>null</code>. */ private Class<?> loadClass(Object classLoader, Object[] params) { if ((null != params) && (params.length == 1)) { Object p = params[0]; if (p instanceof String) { return loadClass(classLoader, (String) p); } } return null; }
@Test public void opentracingClass() throws Exception { Object[] parameters = new String[] { io.opentracing.Tracer.class.getName() }; Object result = hook.beforeBody(METHOD_ID, object, parameters, ssc); assertThat(result, is((Object) io.opentracing.Tracer.class)); verifyZeroInteractions(object, ssc); }
@Test public void happyPath() { Object[] parameters = new String[] { ClassLoadingDelegationHookTest.class.getName() }; Object result = hook.beforeBody(METHOD_ID, object, parameters, ssc); assertThat(result, is((Object) ClassLoadingDelegationHookTest.class)); verifyZeroInteractions(object, ssc); }
@Test public void emptyParameters() { Object[] parameters = new String[] {}; Object result = hook.beforeBody(METHOD_ID, object, parameters, ssc); assertThat(result, is(nullValue())); verifyZeroInteractions(object, ssc); }
@Test public void nullFirstParameter() { Object[] parameters = new String[] { null }; Object result = hook.beforeBody(METHOD_ID, object, parameters, ssc); assertThat(result, is(nullValue())); verifyZeroInteractions(object, ssc); }
@Test public void tooMuchParameters() { Object[] parameters = new String[] { "bla", "nah" }; Object result = hook.beforeBody(METHOD_ID, object, parameters, ssc); assertThat(result, is(nullValue())); verifyZeroInteractions(object, ssc); }
@Test public void notOurClass() { Object[] parameters = new String[] { String.class.getName() }; Object result = hook.beforeBody(METHOD_ID, object, parameters, ssc); assertThat(result, is(nullValue())); verifyZeroInteractions(object, ssc); }
@Test public void reflectAsmClassLoader() throws Exception { Class<?> classLoaderClass = Class.forName("com.esotericsoftware.reflectasm.AccessClassLoader"); Constructor<?> constructor = classLoaderClass.getDeclaredConstructor(ClassLoader.class); constructor.setAccessible(true); Object classLoader = constructor.newInstance(this.getClass().getClassLoader()); Object[] parameters = new String[] { ClassLoadingDelegationHookTest.class.getName() }; Object result = hook.beforeBody(METHOD_ID, classLoader, parameters, ssc); assertThat(result, is(nullValue())); verifyZeroInteractions(ssc); }