diff --git a/dd-java-agent/agent-profiling/profiling-async/src/main/java/com/datadog/profiling/async/AsyncProfiler.java b/dd-java-agent/agent-profiling/profiling-async/src/main/java/com/datadog/profiling/async/AsyncProfiler.java index 475ed69e102..cbc9796b036 100644 --- a/dd-java-agent/agent-profiling/profiling-async/src/main/java/com/datadog/profiling/async/AsyncProfiler.java +++ b/dd-java-agent/agent-profiling/profiling-async/src/main/java/com/datadog/profiling/async/AsyncProfiler.java @@ -29,15 +29,27 @@ public final class AsyncProfiler { public static final String TYPE = "async"; private static final class Singleton { - private static final AsyncProfiler INSTANCE; + private static final AsyncProfiler INSTANCE = newInstance(); + } - static { - try { - INSTANCE = new AsyncProfiler(); - } catch (Throwable t) { - throw new RuntimeException(t); - } + static AsyncProfiler newInstance() { + AsyncProfiler instance = null; + try { + instance = new AsyncProfiler(); + } catch (Throwable t) { + instance = new AsyncProfiler((Void) null); + } + return instance; + } + + static AsyncProfiler newInstance(ConfigProvider configProvider) { + AsyncProfiler instance = null; + try { + instance = new AsyncProfiler(configProvider); + } catch (Throwable t) { + instance = new AsyncProfiler((Void) null); } + return instance; } private final long memleakIntervalDefault; @@ -51,7 +63,13 @@ private AsyncProfiler() throws UnsupportedEnvironmentException { this(ConfigProvider.getInstance()); } - AsyncProfiler(ConfigProvider configProvider) throws UnsupportedEnvironmentException { + private AsyncProfiler(Void dummy) { + this.configProvider = null; + this.asyncProfiler = null; + this.memleakIntervalDefault = 0L; + } + + private AsyncProfiler(ConfigProvider configProvider) throws UnsupportedEnvironmentException { this.configProvider = configProvider; String libDir = configProvider.getString(ProfilingConfig.PROFILING_ASYNC_LIBPATH); if (libDir != null && Files.exists(Paths.get(libDir))) { diff --git a/dd-java-agent/agent-profiling/profiling-async/src/test/java/com/datadog/profiling/async/AsyncProfilerRecordingTest.java b/dd-java-agent/agent-profiling/profiling-async/src/test/java/com/datadog/profiling/async/AsyncProfilerRecordingTest.java index e69cbb2dbc6..139d79916b5 100644 --- a/dd-java-agent/agent-profiling/profiling-async/src/test/java/com/datadog/profiling/async/AsyncProfilerRecordingTest.java +++ b/dd-java-agent/agent-profiling/profiling-async/src/test/java/com/datadog/profiling/async/AsyncProfilerRecordingTest.java @@ -22,14 +22,17 @@ class AsyncProfilerRecordingTest { @BeforeEach void setup() throws Exception { - profiler = new AsyncProfiler(ConfigProvider.getInstance()); + profiler = AsyncProfiler.newInstance(ConfigProvider.getInstance()); log.info( "Async Profiler: available={}, active={}", profiler.isAvailable(), profiler.isActive()); - Assume.assumeTrue(profiler.isAvailable()); - Assume.assumeFalse(profiler.isActive()); + if (profiler.isAvailable()) { + Assume.assumeFalse(profiler.isActive()); - recording = (AsyncProfilerRecording) profiler.start(); - Assume.assumeTrue(recording != null); + recording = (AsyncProfilerRecording) profiler.start(); + Assume.assumeTrue(recording != null); + } else { + // async profiler not available + } } @AfterEach @@ -43,6 +46,10 @@ void shutdown() throws Exception { @Test void testClose() throws Exception { + if (!profiler.isAvailable()) { + log.warn("Async Profiler not available. Skipping test."); + return; + } assertTrue(Files.exists(recording.getRecordingFile())); recording.close(); assertFalse(Files.exists(recording.getRecordingFile())); @@ -50,6 +57,10 @@ void testClose() throws Exception { @Test void testStop() throws Exception { + if (!profiler.isAvailable()) { + log.warn("Async Profiler not available. Skipping test."); + return; + } RecordingData data = recording.stop(); assertNotNull(data); assertTrue(Files.exists(recording.getRecordingFile())); @@ -57,6 +68,10 @@ void testStop() throws Exception { @Test void testSnapshot() throws Exception { + if (!profiler.isAvailable()) { + log.warn("Async Profiler not available. Skipping test."); + return; + } RecordingData data = recording.snapshot(Instant.now()); assertNotNull(data); assertTrue(Files.exists(recording.getRecordingFile())); diff --git a/dd-java-agent/agent-profiling/profiling-async/src/test/java/com/datadog/profiling/async/AsyncProfilerTest.java b/dd-java-agent/agent-profiling/profiling-async/src/test/java/com/datadog/profiling/async/AsyncProfilerTest.java index 024ebf9db7f..8e6fd7db46c 100644 --- a/dd-java-agent/agent-profiling/profiling-async/src/test/java/com/datadog/profiling/async/AsyncProfilerTest.java +++ b/dd-java-agent/agent-profiling/profiling-async/src/test/java/com/datadog/profiling/async/AsyncProfilerTest.java @@ -27,7 +27,7 @@ class AsyncProfilerTest { @Test void test() throws Exception { - AsyncProfiler profiler = new AsyncProfiler(ConfigProvider.getInstance()); + AsyncProfiler profiler = AsyncProfiler.newInstance(ConfigProvider.getInstance()); if (!profiler.isAvailable()) { log.warn("Async Profiler not available. Skipping test."); return; @@ -69,7 +69,12 @@ void testStartCmd(boolean cpu, boolean wall, boolean alloc, boolean memleak) thr props.put(ProfilingConfig.PROFILING_ASYNC_ALLOC_ENABLED, Boolean.toString(alloc)); props.put(ProfilingConfig.PROFILING_ASYNC_MEMLEAK_ENABLED, Boolean.toString(memleak)); - AsyncProfiler profiler = new AsyncProfiler(ConfigProvider.withPropertiesOverride(props)); + AsyncProfiler profiler = + AsyncProfiler.newInstance(ConfigProvider.withPropertiesOverride(props)); + if (!profiler.isAvailable()) { + log.warn("Async Profiler not available. Skipping test."); + return; + } Path targetFile = Paths.get("/tmp/target.jfr"); String cmd = profiler.cmdStartProfiling(targetFile);