Search in sources :

Example 1 with ClassWeave

use of com.newrelic.weave.ClassWeave in project newrelic-java-agent by newrelic.

the class PackageValidationResult method getAnnotationMatchComposite.

private ClassNode getAnnotationMatchComposite(ClassNode targetNode, ClassNode weaveNode, ClassNode composite, Map<String, List<Method>> weavedMethods, ClassCache cache, Map<String, byte[]> annotationProxyClasses, Map<Method, Collection<String>> skipMethods) {
    try {
        boolean isInterfaceMatch = WeaveUtils.isWeaveWithAnnotationInterfaceMatch(weaveNode);
        Map<String, PreparedMatch> results = new HashMap<>();
        buildResults(cache, targetNode, weaveNode.name, weaveNode, results, isInterfaceMatch, weavePackage.getRequiredAnnotationClassesForAnnotationWeave(weaveNode.name), weavePackage.getRequiredAnnotationClassesForMethodAnnotationWeave(weaveNode.name), errorHandler, annotationProxyClasses);
        if (!violations.isEmpty()) {
            return composite;
        }
        for (Map.Entry<String, PreparedMatch> result : results.entrySet()) {
            PreparedMatch prepared = result.getValue();
            if (prepared != null) {
                ClassWeave classWeave = ClassWeave.weave(prepared, composite, weavePackage, skipMethods);
                composite = classWeave.getComposite();
                // Key is only used for logging at the moment.
                final String key = prepared.getWeaveName();
                if (weavedMethods.containsKey(key)) {
                    weavedMethods.get(key).addAll(classWeave.getWeavedMethods());
                } else {
                    weavedMethods.put(key, classWeave.getWeavedMethods());
                }
            }
        }
    } catch (Exception ignored) {
    }
    return composite;
}
Also used : HashMap(java.util.HashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ClassWeave(com.newrelic.weave.ClassWeave) PreparedMatch(com.newrelic.weave.PreparedMatch) HashMap(java.util.HashMap) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) IOException(java.io.IOException)

Example 2 with ClassWeave

use of com.newrelic.weave.ClassWeave in project newrelic-java-agent by newrelic.

the class PackageValidationResult method weave.

/**
 * Weave the target class and return a {@link PackageWeaveResult}.
 */
public PackageWeaveResult weave(String className, String[] superNames, String[] interfaceNames, ClassNode targetNode, ClassCache cache, Map<Method, Collection<String>> skipMethods) {
    ClassNode composite = targetNode;
    final Map<String, List<Method>> weavedMethods = new HashMap<>();
    // Locks during weaving are due to the non-thread safe nature of {@link ClassNode}.
    // first apply exact matches
    {
        PreparedMatch exactMatch = exactMatches.get(className);
        if (null != exactMatch) {
            ClassWeave classWeave;
            classWeave = ClassWeave.weave(exactMatch, composite, weavePackage, skipMethods);
            composite = classWeave.getComposite();
            final String key = exactMatch.getOriginalName();
            if (weavedMethods.containsKey(key)) {
                weavedMethods.get(key).addAll(classWeave.getWeavedMethods());
            } else {
                weavedMethods.put(key, classWeave.getWeavedMethods());
            }
        }
    }
    {
        // matcher for abstract class
        PreparedMatch exactMatch = baseMatches.get(className);
        if (null != exactMatch) {
            ClassWeave classWeave;
            classWeave = ClassWeave.weave(exactMatch, composite, weavePackage, skipMethods);
            composite = classWeave.getComposite();
            final String key = exactMatch.getOriginalName();
            if (weavedMethods.containsKey(key)) {
                weavedMethods.get(key).addAll(classWeave.getWeavedMethods());
            } else {
                weavedMethods.put(key, classWeave.getWeavedMethods());
            }
        }
    }
    // then apply super classes
    for (int i = 0; i < superNames.length; ++i) {
        PreparedMatch baseMatch = baseMatches.get(superNames[i]);
        if (null != baseMatch) {
            ClassWeave classWeave;
            classWeave = ClassWeave.weave(baseMatch, composite, weavePackage, skipMethods);
            composite = classWeave.getComposite();
            final String key = baseMatch.getOriginalName();
            if (weavedMethods.containsKey(key)) {
                weavedMethods.get(key).addAll(classWeave.getWeavedMethods());
            } else {
                weavedMethods.put(key, classWeave.getWeavedMethods());
            }
        }
    }
    // then apply interfaces
    for (int i = 0; i < interfaceNames.length; ++i) {
        PreparedMatch baseMatch = baseMatches.get(interfaceNames[i]);
        if (null != baseMatch) {
            ClassWeave classWeave;
            classWeave = ClassWeave.weave(baseMatch, composite, weavePackage, skipMethods);
            composite = classWeave.getComposite();
            final String key = baseMatch.getOriginalName();
            if (weavedMethods.containsKey(key)) {
                weavedMethods.get(key).addAll(classWeave.getWeavedMethods());
            } else {
                weavedMethods.put(key, classWeave.getWeavedMethods());
            }
        }
    }
    final Map<String, byte[]> annotationProxyClasses = new HashMap<>();
    // class annotation matches
    if (!allAnnotationClasses.isEmpty()) {
        Set<String> targetAnnotationsClasses = getAnnotationClasses(targetNode);
        Set<String> targetInterfacesAnnotationClasses = Collections.emptySet();
        if (!baseAnnotationClasses.isEmpty()) {
            targetInterfacesAnnotationClasses = getAllInterfaceAnnotationClasses(targetNode, cache);
        }
        // check for exact annotation matches
        for (Map.Entry<String, ClassNode> entry : allAnnotationClasses.entrySet()) {
            if (targetAnnotationsClasses.contains(entry.getKey())) {
                composite = getAnnotationMatchComposite(targetNode, entry.getValue(), composite, weavedMethods, cache, annotationProxyClasses, skipMethods);
            }
        }
        // check for base annotation matches
        for (Map.Entry<String, ClassNode> entry : baseAnnotationClasses.entrySet()) {
            if (targetInterfacesAnnotationClasses.contains(entry.getKey())) {
                composite = getAnnotationMatchComposite(targetNode, entry.getValue(), composite, weavedMethods, cache, annotationProxyClasses, skipMethods);
            }
        }
    }
    // method annotation matches
    if (!allMethodAnnotationClasses.isEmpty()) {
        Set<String> targetMethodAnnotationsClasses = getMethodAnnotationClasses(targetNode);
        for (Map.Entry<String, ClassNode> entry : allMethodAnnotationClasses.entrySet()) {
            if (targetMethodAnnotationsClasses.contains(entry.getKey())) {
                composite = getAnnotationMatchComposite(targetNode, entry.getValue(), composite, weavedMethods, cache, annotationProxyClasses, skipMethods);
                // due to having multiple matching annotations that have the same underlying weave code.
                break;
            }
        }
    }
    if (weavePackage != null) {
        // Run any postprocessors that were passed in. It's important that we do this before the inliner runs below
        ClassNode result = new SynchronizedClassNode(WeaveUtils.ASM_API_LEVEL);
        ClassVisitor postprocessChain = weavePackage.getConfig().getPostprocessor().postprocess(className, result, Collections.<String>emptySet(), weavePackage, false);
        composite.accept(postprocessChain);
        composite = result;
    }
    return new PackageWeaveResult(this, className, composite, weavedMethods, annotationProxyClasses);
}
Also used : SynchronizedClassNode(com.newrelic.weave.utils.SynchronizedClassNode) ClassNode(org.objectweb.asm.tree.ClassNode) HashMap(java.util.HashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ClassWeave(com.newrelic.weave.ClassWeave) PreparedMatch(com.newrelic.weave.PreparedMatch) ClassVisitor(org.objectweb.asm.ClassVisitor) SynchronizedClassNode(com.newrelic.weave.utils.SynchronizedClassNode) ArrayList(java.util.ArrayList) List(java.util.List) HashMap(java.util.HashMap) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

Aggregations

ClassWeave (com.newrelic.weave.ClassWeave)2 PreparedMatch (com.newrelic.weave.PreparedMatch)2 HashMap (java.util.HashMap)2 Map (java.util.Map)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 SynchronizedClassNode (com.newrelic.weave.utils.SynchronizedClassNode)1 IOException (java.io.IOException)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 ClassVisitor (org.objectweb.asm.ClassVisitor)1 ClassNode (org.objectweb.asm.tree.ClassNode)1