use of com.newrelic.weave.weavepackage.ClassWeavedListener 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;
}
use of com.newrelic.weave.weavepackage.ClassWeavedListener in project newrelic-java-agent by newrelic.
the class ClassWeaverService method transform.
@Override
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer, final InstrumentationContext context, Match match) throws IllegalClassFormatException {
if (!PointCutClassTransformer.isValidClassName(className)) {
return null;
}
ClassWeavedListener classWeavedCallback = new ClassWeavedListener() {
@Override
public void classWeaved(PackageWeaveResult weaveResult, ClassLoader classloader, ClassCache cache) {
List<WeaveViolation> violations = weaveResult.getValidationResult().getViolations();
if (!violations.isEmpty()) {
// This is due to the nature of annotation weaving happening at weave time instead of validation time
weaveViolationLogger.logWeaveViolations(weaveResult.getValidationResult(), classloader, false);
return;
}
final String packageName = weaveResult.getValidationResult().getWeavePackage().getName();
if (Agent.LOG.isFinerEnabled()) {
try {
if (Agent.LOG.isFinerEnabled()) {
ClassInformation weavedClass = cache.getClassInformation(weaveResult.getClassName());
Agent.LOG.log(Level.FINER, "{0} matched {1}", packageName, weavedClass.className);
for (String superName : weavedClass.getAllSuperNames(cache)) {
Agent.LOG.log(Level.FINER, "\ts: {0}", superName);
}
for (String interfaceName : weavedClass.getAllInterfaces(cache)) {
Agent.LOG.log(Level.FINER, "\ti: {0}", interfaceName);
}
}
} catch (IOException ioe) {
Agent.LOG.log(Level.FINEST, ioe, "exception while getting supertype info");
}
}
if (weaveResult.weavedClass()) {
try {
Map<String, byte[]> annotationProxyClasses = weaveResult.getAnnotationProxyClasses();
if (!annotationProxyClasses.isEmpty()) {
// the dynamic proxy classes that we created to the current classloader at this point
if (BootstrapLoader.PLACEHOLDER == classloader) {
NewClassAppender.appendClassesToBootstrapClassLoader(instrumentation, annotationProxyClasses);
} else {
NewClassAppender.appendClasses(classloader, annotationProxyClasses);
}
}
} catch (Exception e) {
Agent.LOG.log(Level.FINE, e, "Unable to add annotation proxy classes");
}
String weaveClassStat = MessageFormat.format(MetricNames.SUPPORTABILITY_WEAVE_CLASS, packageName, weaveResult.getClassName());
ServiceFactory.getStatsService().doStatsWork(StatsWorks.getRecordMetricWork(weaveClassStat, 1), weaveClassStat);
for (String originalName : weaveResult.getWeavedMethods().keySet()) {
Agent.LOG.log(Level.FINE, "{0}: weaved target {1}-{2}", packageName, classloader, weaveResult.getClassName());
for (Method method : weaveResult.getWeavedMethods().get(originalName)) {
Agent.LOG.log(Level.FINE, "\t{0}.{1}:{2}", originalName, method.getName(), method.getDescriptor());
context.addWeavedMethod(method, packageName);
}
addTraceInformation(ClassWeaverService.this.tracedWeaveInstrumentationDetails, packageName, context, weaveResult.getComposite(), originalName);
}
} else {
Agent.LOG.log(Level.FINER, "{0} matched class {1} but no methods were weaved.", packageName, weaveResult.getClassName());
}
}
};
try {
return weavePackageManager.weave(loader, getClassCache(loader), className, classfileBuffer, context.getSkipMethods(), classWeavedCallback);
} catch (IOException ioe) {
throw new RuntimeException(ioe);
}
}
Aggregations