Search in sources :

Example 1 with MatchType

use of com.newrelic.api.agent.weaver.MatchType in project newrelic-java-agent by newrelic.

the class MethodProcessors method fixInvocationInstructions.

/**
 * Because we create classes that are weaved into interfaces, the invoke instructions in our bytecode can get a
 * little messed up. This goes through the given bytecode and converts INVOKEVIRTUAL instructions to INVOKEINTERFACE
 * if the target of the invocation is a weaved interface.
 *
 * @param cv delegate visitor
 * @return visitor that will update instructions to INVOKEINTERFACE is needed when visited
 */
public static ClassVisitor fixInvocationInstructions(ClassVisitor cv, final Map<String, MatchType> weaveMatches) {
    return new ClassVisitor(WeaveUtils.ASM_API_LEVEL, cv) {

        @Override
        public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
            MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
            return new MethodVisitor(WeaveUtils.ASM_API_LEVEL, mv) {

                @Override
                public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
                    if (opcode == Opcodes.INVOKEVIRTUAL) {
                        MatchType matchType = weaveMatches.get(owner);
                        if (matchType == MatchType.Interface) {
                            itf = true;
                            opcode = Opcodes.INVOKEINTERFACE;
                        }
                    }
                    super.visitMethodInsn(opcode, owner, name, desc, itf);
                }
            };
        }
    };
}
Also used : MatchType(com.newrelic.api.agent.weaver.MatchType) ClassVisitor(org.objectweb.asm.ClassVisitor) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 2 with MatchType

use of com.newrelic.api.agent.weaver.MatchType 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)

Example 3 with MatchType

use of com.newrelic.api.agent.weaver.MatchType in project newrelic-java-agent by newrelic.

the class AgentWeaverListener method validated.

@Override
public void validated(PackageValidationResult packageResult, ClassLoader classloader) {
    final String weavePackageName = packageResult.getWeavePackage().getName();
    final float weavePackageVersion = packageResult.getWeavePackage().getVersion();
    if (packageResult.succeeded()) {
        String supportabilityLoadedMetric;
        if (packageResult.getWeavePackage().getConfig().isCustom()) {
            supportabilityLoadedMetric = MetricNames.SUPPORTABILITY_WEAVE_CUSTOM_LOADED;
        } else {
            supportabilityLoadedMetric = MetricNames.SUPPORTABILITY_WEAVE_LOADED;
        }
        ServiceFactory.getStatsService().doStatsWork(StatsWorks.getRecordMetricWork(MessageFormat.format(supportabilityLoadedMetric, weavePackageName, weavePackageVersion), 1), supportabilityLoadedMetric);
        Agent.LOG.log(Level.FINE, "{0} - validated classloader {1}", weavePackageName, classloader);
    } else {
        WeavePackage weavePackage = packageResult.getWeavePackage();
        if (Agent.LOG.isFinestEnabled() && weavePackage.weavesBootstrap()) {
            Map<String, MatchType> matchTypes = weavePackage.getMatchTypes();
            for (Map.Entry<String, MatchType> entry : matchTypes.entrySet()) {
                if (entry.getValue() != null) {
                    Agent.LOG.log(Level.FINEST, "Bootstrap class {0} : {1}", entry.getKey(), weavePackage.isBootstrapClassName(Collections.singleton(entry.getKey())));
                }
            }
        }
        boolean isCustom = weavePackage.getConfig().isCustom();
        String supportabilitySkippedMetric = isCustom ? MetricNames.SUPPORTABILITY_WEAVE_CUSTOM_SKIPPED : MetricNames.SUPPORTABILITY_WEAVE_SKIPPED;
        ServiceFactory.getStatsService().doStatsWork(StatsWorks.getRecordMetricWork(MessageFormat.format(supportabilitySkippedMetric, weavePackageName, weavePackageVersion), 1), supportabilitySkippedMetric);
        weaveViolationLogger.logWeaveViolations(packageResult, classloader, isCustom);
    }
}
Also used : MatchType(com.newrelic.api.agent.weaver.MatchType) WeavePackage(com.newrelic.weave.weavepackage.WeavePackage) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap) Map(java.util.Map)

Aggregations

MatchType (com.newrelic.api.agent.weaver.MatchType)3 ClassVisitor (org.objectweb.asm.ClassVisitor)2 WeaveClassInfo (com.newrelic.weave.utils.WeaveClassInfo)1 WeaveViolation (com.newrelic.weave.violation.WeaveViolation)1 WeavePackage (com.newrelic.weave.weavepackage.WeavePackage)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 ConcurrentMap (java.util.concurrent.ConcurrentMap)1 MethodVisitor (org.objectweb.asm.MethodVisitor)1 ClassNode (org.objectweb.asm.tree.ClassNode)1 TraceClassVisitor (org.objectweb.asm.util.TraceClassVisitor)1