use of com.newrelic.weave.violation.WeaveViolation in project newrelic-java-agent by newrelic.
the class PackageValidationResult method processMatches.
/**
* Process the weave classes and add them to the result map.
*/
private void processMatches(ClassCache classCache, Map<String, ClassNode> classNameToWeaveNode, Map<String, PreparedMatch> results, boolean isBaseMatch, ClassNode errorHandler) throws IOException {
for (String weaveClassName : classNameToWeaveNode.keySet()) {
byte[] originalBytes = classCache.getClassResource(weaveClassName);
if (null == originalBytes) {
violations.add(new WeaveViolation(WeaveViolationType.MISSING_ORIGINAL_BYTECODE, weaveClassName));
} else {
final ClassNode originalClassNode = WeaveUtils.convertToClassNode(originalBytes);
final ClassNode weaveNode = classNameToWeaveNode.get(weaveClassName);
final Set<String> requiredClassAnnotations = weavePackage.getRequiredAnnotationClassesForMethodAnnotationWeave(weaveClassName);
final Set<String> requiredMethodAnnotations = weavePackage.getRequiredAnnotationClassesForMethodAnnotationWeave(weaveClassName);
buildResults(classCache, originalClassNode, weaveClassName, weaveNode, results, isBaseMatch, requiredClassAnnotations, requiredMethodAnnotations, errorHandler, Collections.<String, byte[]>emptyMap());
}
}
}
use of com.newrelic.weave.violation.WeaveViolation in project newrelic-java-agent by newrelic.
the class Reference method validateClassNode.
/**
* Validate this reference against a class node and return a list of violations indicating what does not match.
*
* @param classCache the classloader used to load the original class.
* @param classNode the original class to match against.
* @return list of {@link ReferenceViolation}s
* @throws IOException
*/
List<WeaveViolation> validateClassNode(ClassCache classCache, ClassNode classNode) throws IOException {
List<WeaveViolation> violations = new ArrayList<>();
if (!this.className.equals(classNode.name)) {
violations.add(new ReferenceViolation(WeaveViolationType.INVALID_REFERENCE, referenceOrigin, classNode.name, "class name mismatch"));
}
// first check the class accessors
if (this.requiredAccess.length > 0) {
int total = 0;
for (int requiredAcces : requiredAccess) {
total += requiredAcces;
}
if (!WeaveUtils.flagsMatch(total, classNode.access, requiredAccess)) {
violations.add(new ReferenceViolation(WeaveViolationType.INVALID_REFERENCE, referenceOrigin, classNode.name, "required class access mismatch. weave expects: " + WeaveUtils.humanReadableAccessFlags(total) + " original has: " + WeaveUtils.humanReadableAccessFlags(classNode.access)));
}
}
if (this.illegalAccess.length > 0) {
if (!WeaveUtils.flagsMatch(0, classNode.access, illegalAccess)) {
violations.add(new ReferenceViolation(WeaveViolationType.INVALID_REFERENCE, referenceOrigin, classNode.name, "illegal class access mismatch. Original has: " + WeaveUtils.humanReadableAccessFlags(classNode.access)));
}
}
List<MethodNode> originalMethods = new ArrayList<>();
List<FieldNode> originalFields = new ArrayList<>();
addMethodsAndFields(classCache, classNode, originalMethods, originalFields);
// now check the fields and methods
violations.addAll(validateFieldsAndMethods(classNode.name, originalMethods, originalFields));
return violations;
}
use of com.newrelic.weave.violation.WeaveViolation 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.violation.WeaveViolation 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.weave.violation.WeaveViolation in project newrelic-java-agent by newrelic.
the class WeaveTestUtils method expectViolations.
/**
* Validate the WeavePackage against a ClassLoader and assert that exactly the expected violations occur.
*
* @param weavePackage package to validate
* @param classloader classloader to validate against
* @param expected exepcted violations
* @throws IOException
*/
public static void expectViolations(WeavePackage weavePackage, ClassLoader classloader, WeaveViolation... expected) throws IOException {
List<WeaveViolation> actual = weavePackage.validate(new ClassCache(new ClassLoaderFinder(classloader))).getViolations();
expectViolations(actual, expected);
}
Aggregations