Skip to content

Commit

Permalink
Add Muzzle reference creation for interfaces
Browse files Browse the repository at this point in the history
This will allow muzzle to fail if an implemented interface is missing.
  • Loading branch information
tylerbenson committed Dec 2, 2020
1 parent cb2cca9 commit 8ce7658
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ public class ReferenceCreator extends ClassVisitor {
*/
private static final String REFERENCE_CREATION_PACKAGE = "datadog.trace.instrumentation.";

private static final int UNDEFINED_LINE = -1;

/**
* Generate all references reachable from a given class.
*
Expand Down Expand Up @@ -180,9 +182,18 @@ public void visit(
refSourceClassName = Utils.getClassName(name);
refSourceType = Type.getType("L" + name + ";");
refSourceTypeInternalName = refSourceType.getInternalName();
// Additional references we could check
// - supertype of class and visible from this package
// - interfaces of class and visible from this package

// Add references to each of the interfaces.
for (String iface : interfaces) {
addReference(
new Reference.Builder(iface)
.withSource(
refSourceClassName,
UNDEFINED_LINE) // We don't have a specific line number to use.
.withFlag(Reference.Flag.PUBLIC)
.build());
}
// the super type is handled by the method visitor to the constructor.
super.visit(version, access, name, signature, superName, interfaces);
}

Expand Down Expand Up @@ -215,7 +226,7 @@ public MethodVisitor visitMethod(
}

private class AdviceReferenceMethodVisitor extends MethodVisitor {
private int currentLineNumber = -1;
private int currentLineNumber = UNDEFINED_LINE;

public AdviceReferenceMethodVisitor(final MethodVisitor methodVisitor) {
super(Opcodes.ASM7, methodVisitor);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,24 @@ class ReferenceCreatorTest extends AgentTestRunner {
references.get('muzzle.TestClasses$MethodBodyAdvice$A') != null
}

def "interface impl creates references"() {
setup:
Map<String, Reference> references = ReferenceCreator.createReferencesFrom(MethodBodyAdvice.SomeImplementation.getName(), this.getClass().getClassLoader())

expect:
references.get('muzzle.TestClasses$MethodBodyAdvice$SomeInterface') != null
references.size() == 1
}

def "child class creates references"() {
setup:
Map<String, Reference> references = ReferenceCreator.createReferencesFrom(MethodBodyAdvice.A2.getName(), this.getClass().getClassLoader())

expect:
references.get('muzzle.TestClasses$MethodBodyAdvice$A') != null
references.size() == 1
}

def "instanceof creates references"() {
setup:
Map<String, Reference> references = ReferenceCreator.createReferencesFrom(InstanceofAdvice.getName(), this.getClass().getClassLoader())
Expand All @@ -82,7 +100,7 @@ class ReferenceCreatorTest extends AgentTestRunner {
Map<String, Reference> references = ReferenceCreator.createReferencesFrom(TestClasses.InDyAdvice.getName(), this.getClass().getClassLoader())

expect:
references.get('muzzle.TestClasses$MethodBodyAdvice$SomeImplementation') != null
references.get('muzzle.TestClasses$MethodBodyAdvice$HasMethod') != null
references.get('muzzle.TestClasses$MethodBodyAdvice$B') != null
}

Expand Down
5 changes: 2 additions & 3 deletions dd-java-agent/testing/src/test/java/muzzle/TestClasses.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,9 @@ public static boolean instanceofMethod(final Object a) {

// Can't test this until java 7 is dropped.
public static class InDyAdvice {
// public static MethodBodyAdvice.SomeInterface indyMethod(
// final MethodBodyAdvice.SomeImplementation a) {
// public static MethodBodyAdvice.HasMethod indyMethod(final MethodBodyAdvice.HasMethod a) {
// Runnable aStaticMethod = MethodBodyAdvice.B::aStaticMethod;
// return a::someMethod;
// return a::requiredMethod;
// }
}
}

0 comments on commit 8ce7658

Please sign in to comment.