Search in sources :

Example 1 with PluginClassFileTransformer

use of org.hotswap.agent.annotation.handler.PluginClassFileTransformer in project HotswapAgent by HotswapProjects.

the class HotswapTransformer method transform.

/**
 * Main transform method called by Java instrumentation.
 * <p/>
 * <p>It does not do the instrumentation itself, instead iterates registered transformers and compares
 * registration class regexp - if the regexp matches, the classloader is called.
 * <p/>
 * <p>Note that class bytes may be send to multiple transformers, but the order is not defined.
 *
 * @see ClassFileTransformer#transform(ClassLoader, String, Class, java.security.ProtectionDomain, byte[])
 */
@Override
public byte[] transform(final ClassLoader classLoader, String className, Class<?> redefiningClass, final ProtectionDomain protectionDomain, byte[] bytes) throws IllegalClassFormatException {
    LOGGER.trace("Transform on class '{}' @{} redefiningClass '{}'.", className, classLoader, redefiningClass);
    List<ClassFileTransformer> toApply = new LinkedList<>();
    List<PluginClassFileTransformer> pluginTransformers = new LinkedList<>();
    try {
        // call transform on all registered transformers
        for (RegisteredTransformersRecord transformerRecord : new LinkedList<RegisteredTransformersRecord>(registeredTransformers.values())) {
            if ((className != null && transformerRecord.pattern.matcher(className).matches()) || (redefiningClass != null && transformerRecord.pattern.matcher(redefiningClass.getName()).matches())) {
                for (ClassFileTransformer transformer : new LinkedList<ClassFileTransformer>(transformerRecord.transformerList)) {
                    if (transformer instanceof PluginClassFileTransformer) {
                        PluginClassFileTransformer pcft = PluginClassFileTransformer.class.cast(transformer);
                        if (!pcft.isPluginDisabled(classLoader)) {
                            pluginTransformers.add(pcft);
                        }
                    } else {
                        toApply.add(transformer);
                    }
                }
            }
        }
    } catch (Throwable t) {
        LOGGER.error("Error transforming class '" + className + "'.", t);
    }
    if (!pluginTransformers.isEmpty()) {
        pluginTransformers = reduce(classLoader, pluginTransformers, className);
    }
    if (toApply.isEmpty() && pluginTransformers.isEmpty()) {
        LOGGER.trace("No transformers defing for {} ", className);
        return bytes;
    }
    // ensure classloader initialized
    ensureClassLoaderInitialized(classLoader, protectionDomain);
    try {
        byte[] result = bytes;
        for (ClassFileTransformer transformer : pluginTransformers) {
            LOGGER.trace("Transforming class '" + className + "' with transformer '" + transformer + "' " + "@ClassLoader" + classLoader + ".");
            result = transformer.transform(classLoader, className, redefiningClass, protectionDomain, result);
        }
        for (ClassFileTransformer transformer : toApply) {
            LOGGER.trace("Transforming class '" + className + "' with transformer '" + transformer + "' " + "@ClassLoader" + classLoader + ".");
            result = transformer.transform(classLoader, className, redefiningClass, protectionDomain, result);
        }
        return result;
    } catch (Throwable t) {
        LOGGER.error("Error transforming class '" + className + "'.", t);
    }
    return bytes;
}
Also used : ClassFileTransformer(java.lang.instrument.ClassFileTransformer) PluginClassFileTransformer(org.hotswap.agent.annotation.handler.PluginClassFileTransformer) PluginClassFileTransformer(org.hotswap.agent.annotation.handler.PluginClassFileTransformer) LinkedList(java.util.LinkedList)

Example 2 with PluginClassFileTransformer

use of org.hotswap.agent.annotation.handler.PluginClassFileTransformer in project HotswapAgent by HotswapProjects.

the class HotswapTransformer method reduce.

LinkedList<PluginClassFileTransformer> reduce(final ClassLoader classLoader, List<PluginClassFileTransformer> pluginCalls, String className) {
    LinkedList<PluginClassFileTransformer> reduced = new LinkedList<>();
    Map<String, PluginClassFileTransformer> fallbackMap = new HashMap<>();
    for (PluginClassFileTransformer pcft : pluginCalls) {
        try {
            String pluginGroup = pcft.getPluginGroup();
            if (pcft.versionMatches(classLoader)) {
                if (pluginGroup != null) {
                    fallbackMap.put(pluginGroup, null);
                }
                reduced.add(pcft);
            } else if (pcft.isFallbackPlugin()) {
                if (pluginGroup != null && !fallbackMap.containsKey(pluginGroup)) {
                    fallbackMap.put(pluginGroup, pcft);
                }
            }
        } catch (Exception e) {
            LOGGER.warning("Error evaluating aplicability of plugin", e);
        }
    }
    for (PluginClassFileTransformer pcft : fallbackMap.values()) {
        if (pcft != null) {
            reduced.add(pcft);
        }
    }
    return reduced;
}
Also used : HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) WeakHashMap(java.util.WeakHashMap) PluginClassFileTransformer(org.hotswap.agent.annotation.handler.PluginClassFileTransformer) LinkedList(java.util.LinkedList) IllegalClassFormatException(java.lang.instrument.IllegalClassFormatException)

Aggregations

LinkedList (java.util.LinkedList)2 PluginClassFileTransformer (org.hotswap.agent.annotation.handler.PluginClassFileTransformer)2 ClassFileTransformer (java.lang.instrument.ClassFileTransformer)1 IllegalClassFormatException (java.lang.instrument.IllegalClassFormatException)1 HashMap (java.util.HashMap)1 LinkedHashMap (java.util.LinkedHashMap)1 WeakHashMap (java.util.WeakHashMap)1