public static byte[] patchByteCode(ClassLoader l, String className, ProtectionDomain pd, byte[] arr) throws IllegalClassFormatException { if (ACTIVE == null) { return arr; } if (Boolean.TRUE.equals(IN.get())) { return arr; } try { IN.set(Boolean.TRUE); for (NbInstrumentation inst : ACTIVE) { for (ClassFileTransformer t : inst.transformers) { arr = t.transform(l, className, null, pd, arr); } } } finally { IN.set(null); } return arr; }
protected <T> Class<T> execute(Class<T> clazz, Configuration config) throws Exception { String className = dotToSlash(clazz.getName()); String classAsPath = className + ".class"; ClassFileTransformer cft = new AnnotatedMetricClassTransformer(config, true); byte[] classfileBuffer = cft.transform( clazz.getClassLoader(), className, null, null, IOUtils.toByteArray(clazz.getClassLoader().getResourceAsStream(classAsPath))); traceBytecode(classfileBuffer); verifyBytecode(classfileBuffer); return getClassFromBytes(clazz, classfileBuffer); }
/** * Adds the specified class file transformer to this class loader. The * transformer will then be able to modify the bytecode of any classes * loaded by this class loader after the invocation of this method. * * @param transformer The transformer to add to the class loader */ @Override public void addTransformer(ClassFileTransformer transformer) { if (transformer == null) { throw new IllegalArgumentException(sm.getString( "webappClassLoader.addTransformer.illegalArgument", getContextName())); } if (this.transformers.contains(transformer)) { // if the same instance of this transformer was already added, bail out log.warn(sm.getString("webappClassLoader.addTransformer.duplicate", transformer, getContextName())); return; } this.transformers.add(transformer); log.info(sm.getString("webappClassLoader.addTransformer", transformer, getContextName())); }
/** * Create a new SimpleLoadTimeWeaver for the given class loader. * @param classLoader the {@code ClassLoader} to delegate to for * weaving (<i>must</i> support the required weaving methods). * @throws IllegalStateException if the supplied {@code ClassLoader} * does not support the required weaving methods */ public ReflectiveLoadTimeWeaver(ClassLoader classLoader) { Assert.notNull(classLoader, "ClassLoader must not be null"); this.classLoader = classLoader; this.addTransformerMethod = ClassUtils.getMethodIfAvailable( this.classLoader.getClass(), ADD_TRANSFORMER_METHOD_NAME, new Class<?>[] {ClassFileTransformer.class}); if (this.addTransformerMethod == null) { throw new IllegalStateException( "ClassLoader [" + classLoader.getClass().getName() + "] does NOT provide an " + "'addTransformer(ClassFileTransformer)' method."); } this.getThrowawayClassLoaderMethod = ClassUtils.getMethodIfAvailable( this.classLoader.getClass(), GET_THROWAWAY_CLASS_LOADER_METHOD_NAME, new Class<?>[0]); // getThrowawayClassLoader method is optional if (this.getThrowawayClassLoaderMethod == null) { if (logger.isInfoEnabled()) { logger.info("The ClassLoader [" + classLoader.getClass().getName() + "] does NOT provide a " + "'getThrowawayClassLoader()' method; SimpleThrowawayClassLoader will be used instead."); } } }
/** * Apply transformation on a given class byte definition. * The method will always return a non-null byte array (if no transformation has taken place * the array content will be identical to the original one). * @param className the full qualified name of the class in dot format (i.e. some.package.SomeClass) * @param internalName class name internal name in / format (i.e. some/package/SomeClass) * @param bytes class byte definition * @param pd protection domain to be used (can be null) * @return (possibly transformed) class byte definition */ public byte[] transformIfNecessary(String className, String internalName, byte[] bytes, ProtectionDomain pd) { byte[] result = bytes; for (ClassFileTransformer cft : this.transformers) { try { byte[] transformed = cft.transform(this.classLoader, internalName, null, pd, result); if (transformed != null) { result = transformed; } } catch (IllegalClassFormatException ex) { throw new IllegalStateException("Class file transformation failed", ex); } } return result; }
@Override public void addTransformer(ClassFileTransformer transformer) { Assert.notNull(transformer, "Transformer must not be null"); FilteringClassFileTransformer actualTransformer = new FilteringClassFileTransformer(transformer, this.classLoader); synchronized (this.transformers) { if (this.instrumentation == null) { throw new IllegalStateException( "Must start with Java agent to use InstrumentationLoadTimeWeaver. See Spring documentation."); } this.instrumentation.addTransformer(actualTransformer); this.transformers.add(actualTransformer); } }
public JBossModulesAdapter(ClassLoader loader) { this.classLoader = loader; try { Field transformer = ReflectionUtils.findField(loader.getClass(), "transformer"); transformer.setAccessible(true); this.delegatingTransformer = transformer.get(loader); if (!this.delegatingTransformer.getClass().getName().equals(DELEGATING_TRANSFORMER_CLASS_NAME)) { throw new IllegalStateException("Transformer not of the expected type DelegatingClassFileTransformer: " + this.delegatingTransformer.getClass().getName()); } this.addTransformer = ReflectionUtils.findMethod(this.delegatingTransformer.getClass(), "addTransformer", ClassFileTransformer.class); this.addTransformer.setAccessible(true); } catch (Exception ex) { throw new IllegalStateException("Could not initialize JBoss 7 LoadTimeWeaver", ex); } }
public synchronized void addTransformer(ClassFileTransformer transformer, boolean canRetransform) { if (transformer == null) { throw new NullPointerException("null passed as 'transformer' in addTransformer"); } if (canRetransform) { if (!isRetransformClassesSupported()) { throw new UnsupportedOperationException( "adding retransformable transformers is not supported in this environment"); } if (mRetransfomableTransformerManager == null) { mRetransfomableTransformerManager = new TransformerManager(true); } mRetransfomableTransformerManager.addTransformer(transformer); if (mRetransfomableTransformerManager.getTransformerCount() == 1) { setHasRetransformableTransformers(mNativeAgent, true); } } else { mTransformerManager.addTransformer(transformer); } }
public synchronized void setNativeMethodPrefix(ClassFileTransformer transformer, String prefix) { if (!isNativeMethodPrefixSupported()) { throw new UnsupportedOperationException( "setNativeMethodPrefix is not supported in this environment"); } if (transformer == null) { throw new NullPointerException( "null passed as 'transformer' in setNativeMethodPrefix"); } TransformerManager mgr = findTransformerManager(transformer); if (mgr == null) { throw new IllegalArgumentException( "transformer not registered in setNativeMethodPrefix"); } mgr.setNativeMethodPrefix(transformer, prefix); String[] prefixes = mgr.getNativeMethodPrefixes(); setNativeMethodPrefixes(mNativeAgent, prefixes, mgr.isRetransformable()); }
/** * Adds the specified class file transformer to this class loader. The * transformer will then be able to modify the bytecode of any classes * loaded by this class loader after the invocation of this method. * * @param transformer * The transformer to add to the class loader */ @Override public void addTransformer(ClassFileTransformer transformer) { if (transformer == null) { throw new IllegalArgumentException( sm.getString("webappClassLoader.addTransformer.illegalArgument", getContextName())); } if (this.transformers.contains(transformer)) { // if the same instance of this transformer was already added, bail // out log.warn(sm.getString("webappClassLoader.addTransformer.duplicate", transformer, getContextName())); return; } this.transformers.add(transformer); log.info(sm.getString("webappClassLoader.addTransformer", transformer, getContextName())); }
@Override public byte[] transform(String name, String transformedName, byte[] classBuffer) { String internalClassName = name.replace('.', '/'); for (ClassFileTransformer transformer : AuthlibInjectorTweaker.transformers) { byte[] result = null; try { result = transformer.transform(Launch.classLoader, internalClassName, null, null, classBuffer); } catch (IllegalClassFormatException e) { log("exception while invoking {0}: {1}", transformer, e); e.printStackTrace(); } if (result != null) { classBuffer = result; } } return classBuffer; }
public static void premain(String options, Instrumentation inst) { // Handle duplicate agents if (initialized) { return; } initialized = true; inst.addTransformer(new ClassFileTransformer() { public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { if (classBeingRedefined != null) { try { Field callSiteArrayField = classBeingRedefined.getDeclaredField("$callSiteArray"); callSiteArrayField.setAccessible(true); callSiteArrayField.set(null, null); } catch (Throwable ignored) { } } return removeTimestampField(classfileBuffer); } }); }
@Test public void premainTest() { // Prepare to verify the instrumentation added Instrumentation mockIntrumentation = mock(Instrumentation.class); JVoid.premain(DEFAULT_TEST_CONFIGURATION_FILE, mockIntrumentation); // The configuration is loaded // assertTrue(!JVoidContext.getConfiguration().dbLocation().isEmpty()); // JVoidExecutionContext jvoidExecutionContext; // // The execution is setup // JExecution execution = jvoidExecutionContext.getCurrentExecution(); // assertNotNull(execution); // assertEquals(JVoidContext.getCurrentExecution(), execution); // The transformer is added ArgumentCaptor<ClassFileTransformer> argument = ArgumentCaptor.forClass(ClassFileTransformer.class); verify(mockIntrumentation).addTransformer(argument.capture()); assertTrue(argument.getValue() instanceof JVoidClassFileTransformer); }
/** * Create a new SimpleLoadTimeWeaver for the given class loader. * @param classLoader the {@code ClassLoader} to delegate to for * weaving (<i>must</i> support the required weaving methods). * @throws IllegalStateException if the supplied {@code ClassLoader} * does not support the required weaving methods */ public ReflectiveLoadTimeWeaver(ClassLoader classLoader) { Assert.notNull(classLoader, "ClassLoader must not be null"); this.classLoader = classLoader; this.addTransformerMethod = ClassUtils.getMethodIfAvailable( this.classLoader.getClass(), ADD_TRANSFORMER_METHOD_NAME, ClassFileTransformer.class); if (this.addTransformerMethod == null) { throw new IllegalStateException( "ClassLoader [" + classLoader.getClass().getName() + "] does NOT provide an " + "'addTransformer(ClassFileTransformer)' method."); } this.getThrowawayClassLoaderMethod = ClassUtils.getMethodIfAvailable( this.classLoader.getClass(), GET_THROWAWAY_CLASS_LOADER_METHOD_NAME); // getThrowawayClassLoader method is optional if (this.getThrowawayClassLoaderMethod == null) { if (logger.isInfoEnabled()) { logger.info("The ClassLoader [" + classLoader.getClass().getName() + "] does NOT provide a " + "'getThrowawayClassLoader()' method; SimpleThrowawayClassLoader will be used instead."); } } }
/** * Removes the specified class file transformer from this class loader. * It will no longer be able to modify the byte code of any classes * loaded by the class loader after the invocation of this method. * However, any classes already modified by this transformer will * remain transformed. * * @param transformer The transformer to remove */ @Override public void removeTransformer(ClassFileTransformer transformer) { if (transformer == null) { return; } if (this.transformers.remove(transformer)) { log.info(sm.getString("webappClassLoader.removeTransformer", transformer, getContextName())); return; } }
/** * Render a String representation of this object. */ @Override public String toString() { StringBuilder sb = new StringBuilder(this.getClass().getSimpleName()); sb.append("\r\n context: "); sb.append(contextName); sb.append("\r\n delegate: "); sb.append(delegate); sb.append("\r\n repositories:\r\n"); if (repositories != null) { for (int i = 0; i < repositories.length; i++) { sb.append(" "); sb.append(repositories[i]); sb.append("\r\n"); } } if (this.parent != null) { sb.append("----------> Parent Classloader:\r\n"); sb.append(this.parent.toString()); sb.append("\r\n"); } if (this.transformers.size() > 0) { sb.append("----------> Class file transformers:\r\n"); for (ClassFileTransformer transformer : this.transformers) { sb.append(transformer).append("\r\n"); } } return (sb.toString()); }
/** * Add a class file transformer to be applied by this weaver. * @param transformer the class file transformer to register */ public void addTransformer(ClassFileTransformer transformer) { if (transformer == null) { throw new IllegalArgumentException("Transformer must not be null"); } this.transformers.add(transformer); }
/** * Create a new {@link WebSphereClassPreDefinePlugin}. * @param transformer the {@link ClassFileTransformer} to be adapted * (must not be {@code null}) */ public WebSphereClassPreDefinePlugin(ClassFileTransformer transformer) { this.transformer = transformer; ClassLoader classLoader = transformer.getClass().getClassLoader(); // first force the full class loading of the weaver by invoking transformation on a dummy class try { String dummyClass = Dummy.class.getName().replace('.', '/'); byte[] bytes = FileCopyUtils.copyToByteArray(classLoader.getResourceAsStream(dummyClass + ".class")); transformer.transform(classLoader, dummyClass, null, null, bytes); } catch (Throwable ex) { throw new IllegalArgumentException("Cannot load transformer", ex); } }
private byte[] applyTransformers(String name, byte[] bytes) { String internalName = StringUtils.replace(name, ".", "/"); try { for (ClassFileTransformer transformer : this.classFileTransformers) { byte[] transformed = transformer.transform(this, internalName, null, null, bytes); bytes = (transformed != null ? transformed : bytes); } return bytes; } catch (IllegalClassFormatException ex) { throw new IllegalStateException(ex); } }
@Override public void addTransformer(ClassFileTransformer transformer) { InvocationHandler adapter = new JBossMCTranslatorAdapter(transformer); Object adapterInstance = Proxy.newProxyInstance(this.translatorClass.getClassLoader(), new Class<?>[] {this.translatorClass}, adapter); try { this.addTranslator.invoke(this.target, adapterInstance); } catch (Exception ex) { throw new IllegalStateException("Could not add transformer on JBoss 6 ClassLoader " + this.classLoader, ex); } }
@Override public void addTransformer(ClassFileTransformer transformer) { try { this.addTransformer.invoke(this.delegatingTransformer, transformer); } catch (Exception ex) { throw new IllegalStateException("Could not add transformer on JBoss 7 ClassLoader " + this.classLoader, ex); } }