Skip to content

Commit 16c6b52

Browse files
committed
Mule: do not crash with JPMS
1 parent 22458b3 commit 16c6b52

File tree

4 files changed

+104
-1
lines changed

4 files changed

+104
-1
lines changed

dd-java-agent/instrumentation/mule-4/build.gradle

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ muzzle {
4343
}
4444

4545
apply from: "$rootDir/gradle/java.gradle"
46+
apply plugin: "idea"
4647

4748
addTestSuiteForDir('mule46ForkedTest', 'test')
4849
addTestSuiteForDir('latestDepForkedTest', 'test')
@@ -81,6 +82,9 @@ configurations.all {
8182
}
8283

8384
sourceSets {
85+
main_java11 {
86+
java.srcDirs "${project.projectDir}/src/main/java11"
87+
}
8488
test {
8589
output.dir("$buildDir/generated-resources/test", builtBy: 'generateAppResources')
8690
}
@@ -92,6 +96,20 @@ sourceSets {
9296
}
9397
}
9498

99+
compileMain_java11Java.configure {
100+
setJavaVersion(it, 11)
101+
sourceCompatibility = JavaVersion.VERSION_1_8
102+
targetCompatibility = JavaVersion.VERSION_1_8
103+
}
104+
105+
jar {
106+
from sourceSets.main_java11.output
107+
}
108+
109+
forbiddenApisMain_java11 {
110+
failOnMissingClasses = false
111+
}
112+
95113
tasks.named("compileTestGroovy").configure {
96114
dependsOn 'mvnPackage', 'extractMuleServices'
97115
}
@@ -112,7 +130,10 @@ tasks.named("compileLatestDepForkedTestJava").configure {
112130
dependencies {
113131
compileOnly group: 'org.mule.runtime', name: 'mule-core', version: muleVersion
114132
compileOnly group: 'org.mule.runtime', name: 'mule-tracer-customization-impl', version: muleVersion
115-
133+
main_java11CompileOnly project(':internal-api')
134+
main_java11CompileOnly project(':dd-java-agent:agent-tooling')
135+
main_java11CompileOnly project(':dd-java-agent:agent-bootstrap')
136+
main_java11CompileOnly sourceSets.main.output
116137
testImplementation project(':dd-java-agent:instrumentation:aws-common')
117138
testImplementation project(':dd-java-agent:instrumentation:reactor-core-3.1')
118139
testImplementation project(':dd-java-agent:instrumentation:reactive-streams')
@@ -234,3 +255,9 @@ spotless {
234255
target "**/*.java"
235256
}
236257
}
258+
259+
idea {
260+
module {
261+
jdkName = '11'
262+
}
263+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package datadog.trace.instrumentation.mule4;
2+
3+
import static net.bytebuddy.matcher.ElementMatchers.isConstructor;
4+
5+
import com.google.auto.service.AutoService;
6+
import datadog.trace.agent.tooling.Instrumenter;
7+
import datadog.trace.agent.tooling.InstrumenterModule;
8+
import datadog.trace.api.Platform;
9+
10+
@AutoService(InstrumenterModule.class)
11+
public class JpmsMuleInstrumentation extends InstrumenterModule.Tracing
12+
implements Instrumenter.HasMethodAdvice, Instrumenter.ForKnownTypes {
13+
public JpmsMuleInstrumentation() {
14+
super("mule", "mule-jpms");
15+
}
16+
17+
@Override
18+
public boolean isEnabled() {
19+
return super.isEnabled() && Platform.isJavaVersionAtLeast(9);
20+
}
21+
22+
@Override
23+
public String[] knownMatchingTypes() {
24+
return new String[] {
25+
// same module but they can be initialized in any order
26+
"org.mule.runtime.tracer.customization.impl.info.ExecutionInitialSpanInfo",
27+
"org.mule.runtime.tracer.customization.impl.provider.LazyInitialSpanInfo",
28+
};
29+
}
30+
31+
@Override
32+
public String[] helperClassNames() {
33+
return new String[] {
34+
packageName + ".JpmsAdvisingHelper",
35+
};
36+
}
37+
38+
@Override
39+
public void methodAdvice(MethodTransformer transformer) {
40+
// it does not work with typeInitializer()
41+
transformer.applyAdvice(isConstructor(), packageName + ".JpmsClearanceAdvice");
42+
}
43+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package datadog.trace.instrumentation.mule4;
2+
3+
import java.util.WeakHashMap;
4+
5+
public class JpmsAdvisingHelper {
6+
private static final WeakHashMap<Module, Boolean> ALREADY_PROCESSED_CACHE = new WeakHashMap<>();
7+
8+
public static boolean isModuleAlreadyProcessed(final Module module) {
9+
return Boolean.TRUE.equals(ALREADY_PROCESSED_CACHE.putIfAbsent(module, Boolean.TRUE));
10+
}
11+
12+
private JpmsAdvisingHelper() {}
13+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package datadog.trace.instrumentation.mule4;
2+
3+
import net.bytebuddy.asm.Advice;
4+
import net.bytebuddy.implementation.bytecode.assign.Assigner;
5+
6+
public class JpmsClearanceAdvice {
7+
@Advice.OnMethodExit(suppress = Throwable.class)
8+
public static void openOnReturn(@Advice.This(typing = Assigner.Typing.DYNAMIC) Object self) {
9+
final Module module = self.getClass().getModule();
10+
if (module == null || JpmsAdvisingHelper.isModuleAlreadyProcessed(module)) {
11+
return;
12+
}
13+
for (String pn : module.getPackages()) {
14+
try {
15+
module.addExports(pn, module.getClassLoader().getUnnamedModule());
16+
} catch (Throwable ignored) {
17+
}
18+
}
19+
}
20+
}

0 commit comments

Comments
 (0)