Search in sources :

Example 1 with WeaveClassInfo

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

the class WeavePackage method processWeaveBytes.

/**
 * Processes all classes in the package.  Part of package initialization.
 * @param weavePackageBytes list of all class bytes in the package
 * @return list of weave violations found during package initialization
 */
protected final List<WeaveViolation> processWeaveBytes(List<byte[]> weavePackageBytes) {
    List<WeaveViolation> violations = new ArrayList<>();
    for (LanguageAdapter adapter : RegisteredLanguageAdapters.getLanguageAdapters()) {
        try {
            LanguageAdapterResult result = adapter.adapt(weavePackageBytes);
            weavePackageBytes = result.getAdaptedBytes();
            violations.addAll(result.getViolations());
        } catch (Throwable ignored) {
        }
    }
    // read weave annotations on each class bytes and put in appropriate map
    for (byte[] weaveClassBytes : weavePackageBytes) {
        ClassNode weaveNode = WeaveUtils.convertToClassNode(weaveClassBytes);
        WeaveClassInfo weave = new WeaveClassInfo(weaveNode);
        violations.addAll(weave.getViolations());
        final boolean isClassAnnotationMatch = !weave.getRequiredClassAnnotations().isEmpty();
        final boolean isMethodAnnotationMatch = !weave.getRequiredMethodAnnotations().isEmpty();
        if (isClassAnnotationMatch || isMethodAnnotationMatch) {
            if (isClassAnnotationMatch) {
                for (String requiredAnnotation : weave.getRequiredClassAnnotations()) {
                    if (weave.getMatchType().equals(Interface)) {
                        baseAnnotationWeaves.put(requiredAnnotation, weaveNode);
                    }
                    allClassAnnotationWeaves.put(requiredAnnotation, weaveNode);
                }
                requiredClassAnnotationsLookup.put(weaveNode.name, weave.getRequiredClassAnnotations());
            }
            if (isMethodAnnotationMatch) {
                for (String requiredAnnotation : weave.getRequiredMethodAnnotations()) {
                    if (!isClassAnnotationMatch) {
                        allMethodAnnotationWeaves.put(requiredAnnotation, weaveNode);
                    } else if (!allMethodAnnotationWeaves.containsKey(requiredAnnotation)) {
                        allMethodAnnotationWeaves.put(requiredAnnotation, weaveNode);
                    }
                }
                requiredMethodAnnotationsLookup.put(weaveNode.name, weave.getRequiredMethodAnnotations());
            }
        } else if (null == weave.getMatchType()) {
            if (weave.isSkipIfPresent()) {
                skipIfPresentClasses.add(weave.getOriginalName());
            } else {
                utilClasses.put(weaveNode.name, weaveNode);
            }
        } else {
            if (!weaveNode.name.equals(weave.getOriginalName())) {
                renames.put(weaveNode.name, weave.getOriginalName());
            }
            // check if added and merge
            weaveMatches.put(weave.getOriginalName(), weave.getMatchType());
            switch(weave.getMatchType()) {
                case BaseClass:
                case Interface:
                    baseWeaves.put(weave.getOriginalName(), weaveNode);
                    break;
                case ExactClass:
                default:
                    exactWeaves.put(weave.getOriginalName(), weaveNode);
                    break;
            }
        }
    }
    // preprocess
    this.preprocessAllWeaveCode();
    this.packageViolations.addAll(violations);
    if (isBootstrapClassName(this.exactWeaves.keySet()) || isBootstrapClassName(this.baseWeaves.keySet())) {
        this.weavesBootstrap = true;
    }
    return violations;
}
Also used : SynchronizedClassNode(com.newrelic.weave.utils.SynchronizedClassNode) ClassNode(org.objectweb.asm.tree.ClassNode) LanguageAdapterResult(com.newrelic.weave.weavepackage.language.LanguageAdapterResult) LanguageAdapter(com.newrelic.weave.weavepackage.language.LanguageAdapter) ArrayList(java.util.ArrayList) WeaveClassInfo(com.newrelic.weave.utils.WeaveClassInfo) WeaveViolation(com.newrelic.weave.violation.WeaveViolation)

Example 2 with WeaveClassInfo

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

the class WeaveTestUtils method weave.

public static ClassWeave weave(ClassNode originalClass, ClassNode weaveClass, ClassNode target, boolean isBaseMatch, Set<String> requiredClassAnnotations, Set<String> requiredMethodAnnotations, ClassNode errorHandlerClassNode, ClassNode extensionTemplate, ClassCache contextCache) throws IOException {
    // match original and weave only if we haven't already done so
    PreparedMatch preparedMatch = MATCHES_ADDED_TO_CLASSLOADER.get(originalClass.name, weaveClass.name);
    if (preparedMatch == null) {
        WeaveClassInfo weaveClassInfo = new WeaveClassInfo(weaveClass);
        // preprocess weave class if original is an interface
        if ((originalClass.access & Opcodes.ACC_INTERFACE) != 0) {
            ClassNode preprocessed = new ClassNode(WeaveUtils.ASM_API_LEVEL);
            Map<String, MatchType> weaveMatches = new HashMap<>();
            weaveMatches.put(weaveClassInfo.getOriginalName(), MatchType.Interface);
            weaveMatches.put(weaveClass.name, MatchType.Interface);
            ClassVisitor preprocessor = MethodProcessors.fixInvocationInstructions(preprocessed, weaveMatches);
            weaveClass.accept(preprocessor);
            weaveClass = preprocessed;
        }
        ClassMatch match = ClassMatch.match(originalClass, weaveClass, isBaseMatch, requiredClassAnnotations, requiredMethodAnnotations, contextCache);
        // weave should not proceed in case of match errors
        for (String newInnerClassName : match.getNewInnerClasses()) {
            match.validateNewInnerClass(readClass(newInnerClassName));
        }
        Collection<WeaveViolation> violations = match.getViolations();
        String assertMsg = String.format("Encountered %d match violations: %s", violations.size(), Iterables.toString(violations));
        assertTrue(assertMsg, violations.isEmpty());
        preparedMatch = PreparedMatch.prepare(match, errorHandlerClassNode, extensionTemplate, true);
        MATCHES_ADDED_TO_CLASSLOADER.put(originalClass.name, weaveClass.name, preparedMatch);
    }
    // weave target using the specified match and add composite class to classloader
    return ClassWeave.weave(preparedMatch, target, null, Collections.emptyMap());
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode) MatchType(com.newrelic.api.agent.weaver.MatchType) HashMap(java.util.HashMap) WeaveClassInfo(com.newrelic.weave.utils.WeaveClassInfo) WeaveViolation(com.newrelic.weave.violation.WeaveViolation) ClassVisitor(org.objectweb.asm.ClassVisitor) TraceClassVisitor(org.objectweb.asm.util.TraceClassVisitor)

Aggregations

WeaveClassInfo (com.newrelic.weave.utils.WeaveClassInfo)2 WeaveViolation (com.newrelic.weave.violation.WeaveViolation)2 ClassNode (org.objectweb.asm.tree.ClassNode)2 MatchType (com.newrelic.api.agent.weaver.MatchType)1 SynchronizedClassNode (com.newrelic.weave.utils.SynchronizedClassNode)1 LanguageAdapter (com.newrelic.weave.weavepackage.language.LanguageAdapter)1 LanguageAdapterResult (com.newrelic.weave.weavepackage.language.LanguageAdapterResult)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 ClassVisitor (org.objectweb.asm.ClassVisitor)1 TraceClassVisitor (org.objectweb.asm.util.TraceClassVisitor)1