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);
}
};
}
};
}
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());
}
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);
}
}
Aggregations