Skip to content

Commit b2eab28

Browse files
Migrate profiling to use common native-loader component.
1 parent fb31324 commit b2eab28

File tree

2 files changed

+23
-53
lines changed

2 files changed

+23
-53
lines changed

dd-java-agent/agent-profiling/profiling-controller/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ dependencies {
2020
api libs.slf4j
2121
api project(':internal-api')
2222
api project(':components:environment')
23+
api project(':components:native-loader')
2324
api project(':dd-java-agent:agent-profiling:profiling-utils')
2425

25-
testImplementation libs.bundles.junit5
2626
testImplementation libs.guava
27+
testImplementation libs.bundles.junit5
2728
testImplementation libs.bundles.mockito
2829
testImplementation group: 'org.awaitility', name: 'awaitility', version: '4.0.1'
2930
}
30-

dd-java-agent/agent-profiling/profiling-controller/src/main/java/com/datadog/profiling/controller/EnvironmentChecker.java

Lines changed: 21 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
package com.datadog.profiling.controller;
22

3-
import static datadog.environment.OperatingSystem.Architecture.ARM64;
4-
53
import datadog.environment.JavaVirtualMachine;
64
import datadog.environment.OperatingSystem;
75
import datadog.environment.SystemProperties;
6+
import datadog.nativeloader.LibFile;
7+
import datadog.nativeloader.NativeLoader;
88
import de.thetaphi.forbiddenapis.SuppressForbidden;
9-
import java.io.File;
109
import java.io.IOException;
1110
import java.net.URL;
11+
import java.net.URLClassLoader;
1212
import java.nio.file.FileSystems;
1313
import java.nio.file.FileVisitResult;
1414
import java.nio.file.FileVisitor;
@@ -19,9 +19,18 @@
1919
import java.nio.file.attribute.PosixFilePermissions;
2020
import java.util.Set;
2121
import java.util.function.Supplier;
22-
import java.util.jar.JarFile;
2322

2423
public final class EnvironmentChecker {
24+
// Loader for native libraries. This should eventually be consolidated into a single shared
25+
// instance, but for now, each module maintains its own instance to simplify the migration.
26+
private static final URL JAR_URL =
27+
EnvironmentChecker.class.getProtectionDomain().getCodeSource().getLocation();
28+
private static final NativeLoader NATIVE_LOADER =
29+
NativeLoader.builder()
30+
.nestedLayout()
31+
.fromClassLoader(new URLClassLoader(new URL[] {JAR_URL}))
32+
.build();
33+
2534
private static void appendLine(String line, StringBuilder sb) {
2635
sb.append(line).append(System.lineSeparator());
2736
}
@@ -50,7 +59,7 @@ public static boolean checkEnvironment(String temp, StringBuilder sb) {
5059
boolean result = false;
5160
result |= checkJFR(sb);
5261
result |= checkDdprof(sb);
53-
if (!result) {;
62+
if (!result) {
5463
appendLine("Profiler is not supported on this JVM.", sb);
5564
return false;
5665
} else {
@@ -153,8 +162,7 @@ private static boolean checkTempLocation(String temp, StringBuilder sb) {
153162
target,
154163
new FileVisitor<Path>() {
155164
@Override
156-
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
157-
throws IOException {
165+
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
158166
return FileVisitResult.CONTINUE;
159167
}
160168

@@ -166,8 +174,7 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
166174
}
167175

168176
@Override
169-
public FileVisitResult visitFileFailed(Path file, IOException exc)
170-
throws IOException {
177+
public FileVisitResult visitFileFailed(Path file, IOException exc) {
171178
return FileVisitResult.CONTINUE;
172179
}
173180

@@ -217,15 +224,11 @@ private static boolean checkLoadLibrary(Path target, StringBuilder sb) {
217224
appendLine("Skipping native library check on non-linux platform", sb);
218225
return true;
219226
}
220-
boolean rslt = true;
221-
try {
222-
rslt &= extractSoFromJar(target, sb);
223-
if (rslt) {
224-
Path libFile = target.resolve("libjavaProfiler.so");
225-
appendLine(() -> sb.append("Attempting to load native library from: ").append(libFile));
226-
System.load(libFile.toString());
227-
appendLine("Native library loaded successfully", sb);
228-
}
227+
appendLine(
228+
() -> sb.append("Attempting to load native library from: ").append("libjavaProfiler.so"));
229+
try (LibFile lib = NATIVE_LOADER.resolveDynamic("libjavaProfiler.so")) {
230+
lib.load();
231+
appendLine("Native library loaded successfully", sb);
229232
return true;
230233
} catch (Throwable t) {
231234
appendLine(
@@ -234,37 +237,4 @@ private static boolean checkLoadLibrary(Path target, StringBuilder sb) {
234237
return false;
235238
}
236239
}
237-
238-
@SuppressForbidden
239-
private static boolean extractSoFromJar(Path target, StringBuilder sb) throws Exception {
240-
URL jarUrl = EnvironmentChecker.class.getProtectionDomain().getCodeSource().getLocation();
241-
try (JarFile jarFile = new JarFile(new File(jarUrl.toURI()))) {
242-
return jarFile.stream()
243-
.filter(e -> e.getName().contains("libjavaProfiler.so"))
244-
.filter(
245-
e ->
246-
e.getName()
247-
.contains(
248-
OperatingSystem.architecture() == ARM64
249-
? "/linux-arm64/"
250-
: "/linux-x64/")
251-
&& (!OperatingSystem.isMusl() || e.getName().contains("-musl")))
252-
.findFirst()
253-
.map(
254-
e -> {
255-
try {
256-
Path soFile = target.resolve("libjavaProfiler.so");
257-
Files.createDirectories(soFile.getParent());
258-
Files.copy(jarFile.getInputStream(e), soFile);
259-
appendLine(() -> sb.append("Native library extracted to: ").append(soFile));
260-
return true;
261-
} catch (Throwable t) {
262-
appendLine("Failed to extract or load native library", sb);
263-
appendLine(() -> sb.append("Error: ").append(t));
264-
}
265-
return false;
266-
})
267-
.orElse(Boolean.FALSE);
268-
}
269-
}
270240
}

0 commit comments

Comments
 (0)