Search in sources :

Example 1 with InstrumentationContext

use of com.newrelic.agent.instrumentation.context.InstrumentationContext in project newrelic-java-agent by newrelic.

the class InstrumentingClassLoader method transform.

@Override
protected byte[] transform(String className) throws Exception {
    byte[] classBytes = WeaveUtils.getClassBytesFromClassLoaderResource(className, this);
    if (classBytes == null) {
        return null;
    }
    final InstrumentationContext context = new InstrumentationContext(classBytes, null, null);
    new ClassReader(classBytes).accept(new ScalaTraitMatcher().newClassMatchVisitor(null, null, null, null, context), ClassReader.SKIP_FRAMES);
    // weave
    byte[] weaved = weave(className, classBytes, context.getSkipMethods(), new ClassWeavedListener() {

        @Override
        public void classWeaved(PackageWeaveResult weaveResult, ClassLoader classloader, ClassCache cache) {
            if (weaveResult.weavedClass()) {
                final String packageName = weaveResult.getValidationResult().getWeavePackage().getName();
                for (String originalName : weaveResult.getWeavedMethods().keySet()) {
                    for (Method method : weaveResult.getWeavedMethods().get(originalName)) {
                        context.addWeavedMethod(method, packageName);
                    }
                    ClassWeaverService.addTraceInformation(InstrumentingClassLoader.this.tracedWeaveInstrumentationDetails, packageName, context, weaveResult.getComposite(), originalName);
                }
                try {
                    Map<String, byte[]> annotationProxyClasses = weaveResult.getAnnotationProxyClasses();
                    if (!annotationProxyClasses.isEmpty()) {
                        // Special case for annotation weaving in order to support dynamic annotation proxies. We
                        // need to add the dynamic proxy classes that we created to the current classloader here
                        NewClassAppender.appendClasses(classloader, annotationProxyClasses);
                    }
                } catch (Exception e) {
                    Agent.LOG.log(Level.FINE, e, "Unable to add annotation proxy classes");
                }
            }
        }
    });
    // trace
    if (weaved != null) {
        classBytes = weaved;
    }
    ClassReader reader = new ClassReader(classBytes);
    if (weaved == null) {
        // process trace annotations for non-weaved code
        reader.accept(new SimpleTraceMatchVisitor(null, context), ClassReader.EXPAND_FRAMES);
    }
    if (!context.isTracerMatch()) {
        if (weaved != null) {
            // printClass(className, weaved);
            return weaved;
        }
        return null;
    }
    NoticeSqlVisitor noticeSqlVisitor = new NoticeSqlVisitor(WeaveUtils.ASM_API_LEVEL);
    // find the noticeSql calls
    reader.accept(noticeSqlVisitor, ClassReader.SKIP_FRAMES);
    String internalClassName = className.replace('.', '/');
    ClassWriter writer = new PatchedClassWriter(ClassWriter.COMPUTE_FRAMES, context.getClassResolver(this));
    ClassVisitor cv = writer;
    cv = new TraceClassVisitor(cv, internalClassName, context, noticeSqlVisitor.getNoticeSqlMethods());
    cv = new ClassVisitor(WeaveUtils.ASM_API_LEVEL, cv) {

        @Override
        public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
            if (version < 49 || version > 100) {
                // Some weird Apache classes have really large versions.
                version = WeaveUtils.RUNTIME_MAX_SUPPORTED_CLASS_VERSION;
            }
            super.visit(version, access, name, signature, superName, interfaces);
        }
    };
    reader.accept(cv, ClassReader.EXPAND_FRAMES);
    byte[] result = writer.toByteArray();
    return result;
}
Also used : InstrumentationContext(com.newrelic.agent.instrumentation.context.InstrumentationContext) ClassWeavedListener(com.newrelic.weave.weavepackage.ClassWeavedListener) PackageWeaveResult(com.newrelic.weave.weavepackage.PackageWeaveResult) Method(com.newrelic.agent.deps.org.objectweb.asm.commons.Method) ClassVisitor(com.newrelic.agent.deps.org.objectweb.asm.ClassVisitor) TraceClassVisitor(com.newrelic.agent.instrumentation.tracing.TraceClassVisitor) IOException(java.io.IOException) PatchedClassWriter(com.newrelic.agent.util.asm.PatchedClassWriter) ClassWriter(com.newrelic.agent.deps.org.objectweb.asm.ClassWriter) TraceClassVisitor(com.newrelic.agent.instrumentation.tracing.TraceClassVisitor) NoticeSqlVisitor(com.newrelic.agent.instrumentation.tracing.NoticeSqlVisitor) ScalaTraitMatcher(com.newrelic.agent.instrumentation.classmatchers.ScalaTraitMatcher) PatchedClassWriter(com.newrelic.agent.util.asm.PatchedClassWriter) ClassReader(com.newrelic.agent.deps.org.objectweb.asm.ClassReader) URLClassLoader(java.net.URLClassLoader) ClassCache(com.newrelic.weave.utils.ClassCache) ConcurrentMap(java.util.concurrent.ConcurrentMap) Map(java.util.Map)

Example 2 with InstrumentationContext

use of com.newrelic.agent.instrumentation.context.InstrumentationContext in project newrelic-java-agent by newrelic.

the class AgentPostprocessors method postprocess.

@Override
public ClassVisitor postprocess(String className, ClassVisitor cv, Set<String> utilityClassesInternalNames, WeavePackage weavePackage, boolean isUtilityClass) {
    cv = wrapApiCallsForSupportability(cv);
    if (isUtilityClass) {
        InstrumentationContext context = new InstrumentationContext(null, null, null);
        Set<TracedWeaveInstrumentationTracker> tracedWeaveInstrumentationTrackers = tracedWeaveInstrumentationDetails.get(weavePackage.getName());
        if (tracedWeaveInstrumentationTrackers != null) {
            for (TracedWeaveInstrumentationTracker tracedWeaveInstrumentationTracker : tracedWeaveInstrumentationTrackers) {
                tracedWeaveInstrumentationTracker.addToInstrumentationContext(context, tracedWeaveInstrumentationTracker.getMethod());
            }
        }
        cv = new TraceClassVisitor(cv, className, context, Collections.<Method>emptySet());
    }
    return cv;
}
Also used : InstrumentationContext(com.newrelic.agent.instrumentation.context.InstrumentationContext) TraceClassVisitor(com.newrelic.agent.instrumentation.tracing.TraceClassVisitor) Method(org.objectweb.asm.commons.Method) TracedMethod(com.newrelic.api.agent.TracedMethod)

Example 3 with InstrumentationContext

use of com.newrelic.agent.instrumentation.context.InstrumentationContext in project newrelic-java-agent by newrelic.

the class ApiImplementationUpdateTest method testMatcherMissingMethods.

@Test
public void testMatcherMissingMethods() throws Exception {
    ArgumentCaptor<ClassMatchVisitorFactory> arg = ArgumentCaptor.forClass(ClassMatchVisitorFactory.class);
    InstrumentationContext iInstrumentationContext = Mockito.mock(InstrumentationContext.class);
    // remove required methods from Request implementation class
    Class<?> clazz = RequestImpl.class;
    Set<Method> methodsToRemove = new HashSet<>();
    methodsToRemove.add(new Method("getHeaderType", "()Lcom/newrelic/api/agent/HeaderType;"));
    byte[] classBytes = removeMethods(clazz, methodsToRemove);
    // verify missing methods
    RequireMethodsAdapter adapter = getRequireMethodsAdapter(clazz, Request.class, REQUEST_METHODS);
    expectMissingMethods(adapter, classBytes);
    ApiImplementationUpdate transformer = new ApiImplementationUpdate();
    ClassMatchVisitorFactory matcher = transformer.getMatcher();
    ClassReader reader = new ClassReader(new ByteArrayInputStream(classBytes));
    ClassVisitor visitor = matcher.newClassMatchVisitor(clazz.getClassLoader(), null, reader, null, iInstrumentationContext);
    reader.accept(visitor, ClassReader.SKIP_CODE);
    Mockito.verify(iInstrumentationContext, Mockito.only()).putMatch(arg.capture(), Mockito.<Match>anyObject());
    Assert.assertSame(matcher, arg.getValue());
}
Also used : InstrumentationContext(com.newrelic.agent.instrumentation.context.InstrumentationContext) ClassMatchVisitorFactory(com.newrelic.agent.instrumentation.context.ClassMatchVisitorFactory) Method(org.objectweb.asm.commons.Method) ClassVisitor(org.objectweb.asm.ClassVisitor) ByteArrayInputStream(java.io.ByteArrayInputStream) RequireMethodsAdapter(com.newrelic.agent.instrumentation.RequireMethodsAdapter) ClassReader(org.objectweb.asm.ClassReader) HashSet(java.util.HashSet) Test(org.junit.Test) ClassMatcherTest(com.newrelic.agent.instrumentation.classmatchers.ClassMatcherTest)

Example 4 with InstrumentationContext

use of com.newrelic.agent.instrumentation.context.InstrumentationContext in project newrelic-java-agent by newrelic.

the class ApiImplementationUpdateTest method testMatcher.

@Test
public void testMatcher() throws Exception {
    InstrumentationContext iInstrumentationContext = Mockito.mock(InstrumentationContext.class);
    Class<?> clazz = RequestImpl.class;
    Set<Method> methodsToRemove = new HashSet<>();
    byte[] classBytes = removeMethods(clazz, methodsToRemove);
    // verify no missing methods
    RequireMethodsAdapter adapter = getRequireMethodsAdapter(clazz, Request.class, REQUEST_METHODS);
    expectNoMissingMethods(adapter, classBytes);
    ApiImplementationUpdate transformer = new ApiImplementationUpdate();
    ClassMatchVisitorFactory matcher = transformer.getMatcher();
    ClassReader reader = new ClassReader(new ByteArrayInputStream(classBytes));
    ClassVisitor visitor = matcher.newClassMatchVisitor(clazz.getClassLoader(), null, reader, null, iInstrumentationContext);
    reader.accept(visitor, ClassReader.SKIP_CODE);
    Mockito.verify(iInstrumentationContext, Mockito.never()).putMatch(Mockito.<ClassMatchVisitorFactory>anyObject(), Mockito.<Match>anyObject());
}
Also used : InstrumentationContext(com.newrelic.agent.instrumentation.context.InstrumentationContext) ClassMatchVisitorFactory(com.newrelic.agent.instrumentation.context.ClassMatchVisitorFactory) Method(org.objectweb.asm.commons.Method) ClassVisitor(org.objectweb.asm.ClassVisitor) ByteArrayInputStream(java.io.ByteArrayInputStream) RequireMethodsAdapter(com.newrelic.agent.instrumentation.RequireMethodsAdapter) ClassReader(org.objectweb.asm.ClassReader) HashSet(java.util.HashSet) Test(org.junit.Test) ClassMatcherTest(com.newrelic.agent.instrumentation.classmatchers.ClassMatcherTest)

Example 5 with InstrumentationContext

use of com.newrelic.agent.instrumentation.context.InstrumentationContext in project newrelic-java-agent by newrelic.

the class OptimizedClassMatcherTest method testReturnTypeMatch.

@Test
public void testReturnTypeMatch() throws IOException {
    ClassMatchVisitorFactory matcher = OptimizedClassMatcherBuilder.newBuilder().addClassMethodMatcher(new DefaultClassAndMethodMatcher(new AllClassesMatcher(), new ExactReturnTypeMethodMatcher(Type.getType(List.class)))).build();
    InstrumentationContext instrumentationContext = getInstrumentationContext(matcher, Arrays.class);
    Assert.assertFalse(instrumentationContext.getMatches().isEmpty());
    Match match = instrumentationContext.getMatches().values().iterator().next();
    Assert.assertNotNull(match);
    Assert.assertEquals(1, match.getMethods().size());
    Assert.assertTrue(match.getMethods().contains(new Method("asList", "([Ljava/lang/Object;)Ljava/util/List;")));
    Assert.assertEquals(1, match.getClassMatches().size());
}
Also used : InstrumentationContext(com.newrelic.agent.instrumentation.context.InstrumentationContext) ExactReturnTypeMethodMatcher(com.newrelic.agent.instrumentation.methodmatchers.ExactReturnTypeMethodMatcher) ClassMatchVisitorFactory(com.newrelic.agent.instrumentation.context.ClassMatchVisitorFactory) Method(org.objectweb.asm.commons.Method) Match(com.newrelic.agent.instrumentation.classmatchers.OptimizedClassMatcher.Match) Test(org.junit.Test)

Aggregations

InstrumentationContext (com.newrelic.agent.instrumentation.context.InstrumentationContext)15 Test (org.junit.Test)10 Method (org.objectweb.asm.commons.Method)9 ClassReader (org.objectweb.asm.ClassReader)7 ClassVisitor (org.objectweb.asm.ClassVisitor)4 ClassWriter (org.objectweb.asm.ClassWriter)4 Match (com.newrelic.agent.instrumentation.classmatchers.OptimizedClassMatcher.Match)3 ClassMatchVisitorFactory (com.newrelic.agent.instrumentation.context.ClassMatchVisitorFactory)3 TestLogger (com.newrelic.agent.bridge.TestLogger)2 RequireMethodsAdapter (com.newrelic.agent.instrumentation.RequireMethodsAdapter)2 ClassMatcherTest (com.newrelic.agent.instrumentation.classmatchers.ClassMatcherTest)2 TraceClassVisitor (com.newrelic.agent.instrumentation.tracing.TraceClassVisitor)2 ByteArrayInputStream (java.io.ByteArrayInputStream)2 URL (java.net.URL)2 HashSet (java.util.HashSet)2 ExecutorService (java.util.concurrent.ExecutorService)2 Future (java.util.concurrent.Future)2 ClassReader (com.newrelic.agent.deps.org.objectweb.asm.ClassReader)1 ClassVisitor (com.newrelic.agent.deps.org.objectweb.asm.ClassVisitor)1 ClassWriter (com.newrelic.agent.deps.org.objectweb.asm.ClassWriter)1