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