Skip to content

Commit

Permalink
Try to locate tracer JAR using class loader resource lookup when boot…
Browse files Browse the repository at this point in the history
…strapping the agent
  • Loading branch information
nikita-tkachenko-datadog committed Oct 31, 2023
1 parent 205e504 commit fa2569c
Showing 1 changed file with 53 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import java.lang.management.ManagementFactory;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
Expand Down Expand Up @@ -203,13 +204,10 @@ public static void main(final String[] args) {

private static synchronized URL installAgentJar(final Instrumentation inst)
throws IOException, URISyntaxException {
URL ddJavaAgentJarURL = null;

// First try Code Source
final CodeSource codeSource = thisClass.getProtectionDomain().getCodeSource();

if (codeSource != null) {
ddJavaAgentJarURL = codeSource.getLocation();
URL ddJavaAgentJarURL = codeSource.getLocation();
if (ddJavaAgentJarURL != null) {
final File ddJavaAgentJarPath = new File(ddJavaAgentJarURL.toURI());

Expand All @@ -222,7 +220,44 @@ private static synchronized URL installAgentJar(final Instrumentation inst)
}

System.out.println("Could not get bootstrap jar from code source, using -javaagent arg");
File javaagentFile = getAgentFileFromJavaagentArg(inst);
if (javaagentFile != null) {
URL ddJavaAgentJarURL = javaagentFile.toURI().toURL();
checkJarManifestMainClassIsThis(ddJavaAgentJarURL);
inst.appendToBootstrapClassLoaderSearch(new JarFile(javaagentFile));
return ddJavaAgentJarURL;
}

System.out.println(
"Could not get agent jar from -javaagent arg, using ClassLoader#getResource");
URL thisClassUrl;
String thisClassResourceName = thisClass.getName().replace('.', '/') + ".class";
ClassLoader classLoader = thisClass.getClassLoader();
if (classLoader == null) {
thisClassUrl = ClassLoader.getSystemResource(thisClassResourceName);
} else {
thisClassUrl = classLoader.getResource(thisClassResourceName);
}

if (thisClassUrl == null) {
throw new IllegalStateException(
"Could not locate agent bootstrap class resource, not installing tracing agent");
}

javaagentFile = new File(new URI(thisClassUrl.getFile().split("!")[0]));
if (!javaagentFile.isDirectory()) {
URL ddJavaAgentJarURL = javaagentFile.toURI().toURL();
checkJarManifestMainClassIsThis(ddJavaAgentJarURL);
inst.appendToBootstrapClassLoaderSearch(new JarFile(javaagentFile));
return ddJavaAgentJarURL;
}

throw new IllegalStateException(
"Could not determine agent jar location, not installing tracing agent");
}

private static File getAgentFileFromJavaagentArg(Instrumentation inst) throws IOException {
URL ddJavaAgentJarURL;
// ManagementFactory indirectly references java.util.logging.LogManager
// - On Oracle-based JDKs after 1.8
// - On IBM-based JDKs since at least 1.7
Expand All @@ -236,33 +271,36 @@ private static synchronized URL installAgentJar(final Instrumentation inst)
if (agentArgument == null) {
agentArgument = arg;
} else {
throw new IllegalStateException(
"Multiple javaagents specified and code source unavailable, not installing tracing agent");
System.out.println(
"Could not get bootstrap jar from -javaagent arg: multiple javaagents specified");
return null;
}
}
}

if (agentArgument == null) {
throw new IllegalStateException(
"Could not find javaagent parameter and code source unavailable, not installing tracing agent");
System.out.println("Could not get bootstrap jar from -javaagent arg: no argument specified");
return null;
}

// argument is of the form -javaagent:/path/to/dd-java-agent.jar=optionalargumentstring
final Matcher matcher = Pattern.compile("-javaagent:([^=]+).*").matcher(agentArgument);

if (!matcher.matches()) {
throw new IllegalStateException("Unable to parse javaagent parameter: " + agentArgument);
System.out.println(
"Could not get bootstrap jar from -javaagent arg: unable to parse javaagent parameter: "
+ agentArgument);
return null;
}

final File javaagentFile = new File(matcher.group(1));
if (!(javaagentFile.exists() || javaagentFile.isFile())) {
throw new IllegalStateException("Unable to find javaagent file: " + javaagentFile);
System.out.println(
"Could not get bootstrap jar from -javaagent arg: unable to find javaagent file: "
+ javaagentFile);
return null;
}
ddJavaAgentJarURL = javaagentFile.toURI().toURL();
checkJarManifestMainClassIsThis(ddJavaAgentJarURL);
inst.appendToBootstrapClassLoaderSearch(new JarFile(javaagentFile));

return ddJavaAgentJarURL;
return javaagentFile;
}

@SuppressForbidden
Expand Down

0 comments on commit fa2569c

Please sign in to comment.