Skip to content

Commit df07d4f

Browse files
bric3mcculls
andauthored
Adds a test for JDK-827271 (#9650)
* Ignore java.lang.Object methods (identified by method name plus method descriptor) when creating muzzle references. This helps when compiling with Java 18+ because javac will now use INVOKEINTERFACE with the interface name to call java.lang.Object methods (so the 'owner' is now seen as the interface) whereas before it was using INVOKEVIRTUAL with java.lang.Object as the method 'owner'. the key change is described in https://bugs.openjdk.org/browse/JDK-8272715: "invocations of java.lang.Object methods on interfaces in the classfile will use invokeinterface referring to the interface, which is consistent with JLS 9.2. This will be done regardless of whether the interface declares the method explicitly or not." * chore: Adds a test for JDK-827271 After JDK 18/19 javac compiles differently `Object` methods, while there is a ignore mechanism on java.* packages after the key change is described in https://bugs.openjdk.org/browse/JDK-827271, `Object`'s methods are applied to interfaces which may belong to another package. Key change of JDK-827271 "invocations of `java.lang.Object` methods on interfaces in the classfile will use `invokeinterface` referring to the interface, which is consistent with JLS 9.2. This will be done regardless of whether the interface declares the method explicitly or not." --------- Co-authored-by: Stuart McCulloch <stuart.mcculloch@datadoghq.com>
1 parent af7ff80 commit df07d4f

File tree

3 files changed

+56
-18
lines changed

3 files changed

+56
-18
lines changed

dd-java-agent/agent-tooling/build.gradle

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,34 +9,36 @@ minimumBranchCoverage = 0.6
99
excludedClassesCoverage += ['datadog.trace.agent.tooling.*']
1010

1111
sourceSets {
12-
test_java11 {
12+
register("test_java11") {
1313
java {
1414
srcDirs = [file('src/test/java11')]
1515
}
1616
}
17-
test {
18-
groovy {
19-
compileClasspath += sourceSets.test_java11.output
20-
runtimeClasspath += sourceSets.test_java11.output
17+
register("test_java21") {
18+
java {
19+
srcDirs = [file('src/test/java21')]
2120
}
2221
}
22+
named("test") {
23+
compileClasspath += sourceSets.test_java11.output
24+
runtimeClasspath += sourceSets.test_java11.output
25+
compileClasspath += sourceSets.test_java21.output
26+
runtimeClasspath += sourceSets.test_java21.output
27+
}
2328
}
2429

2530
configurations {
26-
instrumentPluginClasspath {
31+
register("instrumentPluginClasspath") {
2732
canBeConsumed = true
2833
canBeResolved = false
2934
extendsFrom runtimeElements
3035
}
3136

32-
test_java11Implementation {
37+
named("test_java11Implementation") {
3338
extendsFrom testImplementation
3439
}
3540
}
3641

37-
compileJava.dependsOn 'generateClassNameTries'
38-
sourcesJar.dependsOn 'generateClassNameTries'
39-
4042
dependencies {
4143
api(project(':dd-java-agent:agent-bootstrap')) {
4244
exclude group: 'com.datadoghq', module: 'agent-logging'
@@ -67,8 +69,11 @@ jmh {
6769
jmhVersion = libs.versions.jmh.get()
6870
includeTests = true
6971
}
70-
compileJmhJava.dependsOn compileTestJava
71-
compileTestJava.dependsOn 'generateTestClassNameTries'
72+
73+
tasks.named("compileJava") { dependsOn 'generateClassNameTries' }
74+
tasks.named("sourcesJar") { dependsOn 'generateClassNameTries' }
75+
76+
tasks.named("compileJmhJava") { dependsOn tasks.named("compileTestJava") }
7277

7378
tasks.named("forbiddenApisJmh") {
7479
ignoreFailures = true
@@ -80,17 +85,22 @@ tasks.named("forbiddenApisTest_java11") {
8085
failOnMissingClasses = false
8186
}
8287

83-
project.tasks.compileTestJava.dependsOn(project.tasks.generateTestClassNameTries)
84-
project.tasks.compileTestGroovy.dependsOn(project.tasks.compileTest_java11Java)
85-
project.tasks.compileTest_java11Java.configure {
88+
tasks.named("compileTestJava") { dependsOn('generateTestClassNameTries') }
89+
tasks.named("compileTest_java11Java") {
8690
sourceCompatibility = JavaVersion.VERSION_11
8791
targetCompatibility = JavaVersion.VERSION_11
8892
setJavaVersion(it, 11)
8993
}
94+
tasks.named("compileTest_java21Java") {
95+
sourceCompatibility = JavaVersion.VERSION_1_8
96+
targetCompatibility = JavaVersion.VERSION_1_8
97+
setJavaVersion(it, 21)
98+
}
9099

91-
final jmh = project.tasks.jmh
92-
jmh.outputs.upToDateWhen { false }
93-
jmh.dependsOn(compileTestJava)
100+
tasks.named("jmh") {
101+
dependsOn(tasks.named("compileTestJava"))
102+
outputs.upToDateWhen { false }
103+
}
94104

95105
tasks.withType(Test).configureEach {
96106
// same setting as AgentInstaller to avoid spurious agent-tooling test failures

dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/tooling/muzzle/ReferenceCreatorTest.groovy

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,23 @@ class ReferenceCreatorTest extends DDSpecification {
5353
aFieldRefs.size() == 2
5454
}
5555

56+
def "ignore invocation of object methods on interface after JDK-8272715"() {
57+
// After JDK 18/19 javac compiles differently Object methods, while there is a ignore mechanism on java.* packages
58+
// after the key change is described in https://bugs.openjdk.org/browse/JDK-827271, object's methods
59+
// are applied to interfaces which may belong to another package.
60+
//
61+
// Key change
62+
// "invocations of java.lang.Object methods on interfaces in the classfile will use invokeinterface referring
63+
// to the interface, which is consistent with JLS 9.2. This will be done regardless of whether the interface
64+
// declares the method explicitly or not."
65+
66+
setup:
67+
Map<String, Reference> references = ReferenceCreator.createReferencesFrom(CompiledWithInvokeinterfaceForObjectMethods.name, this.class.classLoader)
68+
69+
expect:
70+
references.get(CompiledWithInvokeinterfaceForObjectMethods.DatadogInterface.name) == null
71+
}
72+
5673
def "protected ref test"() {
5774
setup:
5875
Map<String, Reference> references = ReferenceCreator.createReferencesFrom(MethodBodyAdvice.B2.name, this.class.classLoader)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package datadog.trace.agent.tooling.muzzle;
2+
3+
public class CompiledWithInvokeinterfaceForObjectMethods {
4+
interface DatadogInterface {}
5+
6+
public void doSomething(DatadogInterface itf) {
7+
itf.hashCode();
8+
itf.equals(new Object());
9+
itf.getClass();
10+
}
11+
}

0 commit comments

Comments
 (0)