diff --git a/javaagent-bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/AgentInitializer.java b/javaagent-bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/AgentInitializer.java index 5410c883c722..adb7668fa79b 100644 --- a/javaagent-bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/AgentInitializer.java +++ b/javaagent-bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/AgentInitializer.java @@ -26,6 +26,7 @@ public final class AgentInitializer { @Nullable private static ClassLoader agentClassLoader = null; @Nullable private static AgentStarter agentStarter = null; private static boolean isSecurityManagerSupportEnabled = false; + private static volatile boolean agentStarted = false; public static void initialize(Instrumentation inst, File javaagentFile, boolean fromPremain) throws Exception { @@ -51,6 +52,7 @@ public Void run() throws Exception { agentStarter = createAgentStarter(agentClassLoader, inst, javaagentFile); if (!fromPremain || !delayAgentStart()) { agentStarter.start(); + agentStarted = true; } return null; } @@ -149,11 +151,27 @@ public static void delayedStartHook() throws Exception { @Override public Void run() { agentStarter.start(); + agentStarted = true; return null; } }); } + /** + * Check whether agent has started or not along with VM. + * + *
This method is used by
+ * io.opentelemetry.javaagent.tooling.AgentStarterImpl#InetAddressClassFileTransformer internally
+ * to check whether agent has started.
+ *
+ * @param vmStarted flag about whether VM has started or not.
+ * @return {@code true} if agent has started or not along with VM, {@code false} otherwise.
+ */
+ @SuppressWarnings("unused")
+ public static boolean isAgentStarted(boolean vmStarted) {
+ return vmStarted && agentStarted;
+ }
+
public static ClassLoader getExtensionsClassLoader() {
// agentStarter can be null when running tests
return agentStarter != null ? agentStarter.getExtensionClassLoader() : null;
diff --git a/javaagent-tooling/jdk18-testing/build.gradle.kts b/javaagent-tooling/jdk18-testing/build.gradle.kts
new file mode 100644
index 000000000000..ab1bf712d97f
--- /dev/null
+++ b/javaagent-tooling/jdk18-testing/build.gradle.kts
@@ -0,0 +1,11 @@
+plugins {
+ id("otel.javaagent-testing")
+}
+
+dependencies {
+ compileOnly("io.opentelemetry:opentelemetry-sdk-common")
+}
+
+otelJava {
+ minJavaVersionSupported.set(JavaVersion.VERSION_18)
+}
diff --git a/javaagent-tooling/jdk18-testing/src/main/java/testing/TestResourceProvider.java b/javaagent-tooling/jdk18-testing/src/main/java/testing/TestResourceProvider.java
new file mode 100644
index 000000000000..9db4d5df5006
--- /dev/null
+++ b/javaagent-tooling/jdk18-testing/src/main/java/testing/TestResourceProvider.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package testing;
+
+import com.google.auto.service.AutoService;
+import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
+import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
+import io.opentelemetry.sdk.resources.Resource;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+@AutoService(ResourceProvider.class)
+public class TestResourceProvider implements ResourceProvider {
+
+ @Override
+ public Resource createResource(ConfigProperties config) {
+ // used in test to determine whether this method was called
+ System.setProperty("test.resource.provider.called", "true");
+ // this call trigger loading InetAddressResolverProvider SPI on jdk 18
+ try {
+ InetAddress.getLocalHost();
+ } catch (UnknownHostException e) {
+ throw new IllegalStateException(e);
+ }
+ return Resource.empty();
+ }
+}
diff --git a/javaagent-tooling/jdk18-testing/src/test/java/io/opentelemetry/javaagent/tooling/inetaddress/InetAddressResolverTest.java b/javaagent-tooling/jdk18-testing/src/test/java/io/opentelemetry/javaagent/tooling/inetaddress/InetAddressResolverTest.java
new file mode 100644
index 000000000000..f21e494b5f0a
--- /dev/null
+++ b/javaagent-tooling/jdk18-testing/src/test/java/io/opentelemetry/javaagent/tooling/inetaddress/InetAddressResolverTest.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.javaagent.tooling.inetaddress;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.net.InetAddress;
+import org.junit.jupiter.api.Test;
+
+public class InetAddressResolverTest {
+
+ @Test
+ void agentStartShouldNotTriggerLoadingCustomInetAddressResolvers() throws Exception {
+ // This system property is set in TestResourceProvider
+ assertThat(System.getProperty("test.resource.provider.called")).isEqualTo("true");
+ // Agent start should not trigger loading (and instantiating) custom InetAddress resolvers
+ assertThat(TestAddressResolver.isInstantiated()).isFalse();
+
+ // Trigger loading (and instantiating) custom InetAddress resolvers manually
+ InetAddress.getAllByName("test");
+
+ // Verify that custom InetAddress resolver loaded and instantiated
+ assertThat(TestAddressResolver.isInstantiated()).isTrue();
+ }
+}
diff --git a/javaagent-tooling/jdk18-testing/src/test/java/io/opentelemetry/javaagent/tooling/inetaddress/TestAddressResolver.java b/javaagent-tooling/jdk18-testing/src/test/java/io/opentelemetry/javaagent/tooling/inetaddress/TestAddressResolver.java
new file mode 100644
index 000000000000..9c0df5aad70b
--- /dev/null
+++ b/javaagent-tooling/jdk18-testing/src/test/java/io/opentelemetry/javaagent/tooling/inetaddress/TestAddressResolver.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.javaagent.tooling.inetaddress;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.net.spi.InetAddressResolver;
+import java.util.stream.Stream;
+
+public class TestAddressResolver implements InetAddressResolver {
+
+ private static volatile boolean instantiated = false;
+
+ @SuppressWarnings("StaticAssignmentInConstructor")
+ public TestAddressResolver() {
+ TestAddressResolver.instantiated = true;
+ }
+
+ public static boolean isInstantiated() {
+ return instantiated;
+ }
+
+ @Override
+ public Stream