From f925f74f9d8a334f46dd79c1c55860d12b24e329 Mon Sep 17 00:00:00 2001 From: Jean Bisutti Date: Sat, 18 Jun 2022 00:34:26 +0200 Subject: [PATCH] Fix "URI is not hierarchical" during runtime attachment (#359) * Fix "java.lang.IllegalArgumentException: URI is not hierarchical" during runtime attachment * Fix build issue * Fiw file creation and deletion * Add null checks * Only delete jar file on JVM exit * Fix merge * Fix spotless * Remove null checks * Spotless Co-authored-by: Trask Stalnaker --- .../contrib/attach/AgentFileLocator.java | 38 ---------- .../contrib/attach/AgentFileProvider.java | 73 +++++++++++++++++++ .../contrib/attach/RuntimeAttach.java | 2 +- 3 files changed, 74 insertions(+), 39 deletions(-) delete mode 100644 runtime-attach/src/main/java/io/opentelemetry/contrib/attach/AgentFileLocator.java create mode 100644 runtime-attach/src/main/java/io/opentelemetry/contrib/attach/AgentFileProvider.java diff --git a/runtime-attach/src/main/java/io/opentelemetry/contrib/attach/AgentFileLocator.java b/runtime-attach/src/main/java/io/opentelemetry/contrib/attach/AgentFileLocator.java deleted file mode 100644 index b47f89e6..00000000 --- a/runtime-attach/src/main/java/io/opentelemetry/contrib/attach/AgentFileLocator.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.contrib.attach; - -import io.opentelemetry.javaagent.OpenTelemetryAgent; -import java.io.File; -import java.net.URISyntaxException; -import java.net.URL; -import java.security.CodeSource; - -final class AgentFileLocator { - - static File locateAgentFile() { - CodeSource codeSource = OpenTelemetryAgent.class.getProtectionDomain().getCodeSource(); - - if (codeSource == null) { - throw new IllegalStateException("could not get agent jar location"); - } - - URL codeSourceLocation = codeSource.getLocation(); - try { - File javaagentFile = new File(codeSourceLocation.toURI()); - if (javaagentFile.isFile()) { - return javaagentFile; - } - } catch (URISyntaxException ignored) { - // ignored - } - - throw new IllegalStateException( - "agent jar location doesn't appear to be a file: " + codeSourceLocation); - } - - private AgentFileLocator() {} -} diff --git a/runtime-attach/src/main/java/io/opentelemetry/contrib/attach/AgentFileProvider.java b/runtime-attach/src/main/java/io/opentelemetry/contrib/attach/AgentFileProvider.java new file mode 100644 index 00000000..a6af835e --- /dev/null +++ b/runtime-attach/src/main/java/io/opentelemetry/contrib/attach/AgentFileProvider.java @@ -0,0 +1,73 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.contrib.attach; + +import io.opentelemetry.javaagent.OpenTelemetryAgent; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.CodeSource; + +final class AgentFileProvider { + + static File getAgentFile() { + + verifyExistenceOfAgentJarFile(); + + Path tempDirPath = createTempDir(); + + Path tempAgentJarPath = createTempAgentJarFile(tempDirPath); + + deleteTempDirOnJvmExit(tempDirPath, tempAgentJarPath); + + return tempAgentJarPath.toFile(); + } + + private static void deleteTempDirOnJvmExit(Path tempDirPath, Path tempAgentJarPath) { + tempAgentJarPath.toFile().deleteOnExit(); + tempDirPath.toFile().deleteOnExit(); + } + + private static void verifyExistenceOfAgentJarFile() { + CodeSource codeSource = OpenTelemetryAgent.class.getProtectionDomain().getCodeSource(); + if (codeSource == null) { + throw new IllegalStateException("could not get agent jar location"); + } + } + + private static Path createTempDir() { + Path tempDir; + try { + tempDir = Files.createTempDirectory("otel-agent"); + } catch (IOException e) { + throw new IllegalStateException("Runtime attachment can't create temp directory", e); + } + return tempDir; + } + + private static Path createTempAgentJarFile(Path tempDir) { + URL url = OpenTelemetryAgent.class.getProtectionDomain().getCodeSource().getLocation(); + try { + return copyTo(url, tempDir, "agent.jar"); + } catch (IOException e) { + throw new IllegalStateException( + "Runtime attachment can't create agent jar file in temp directory", e); + } + } + + private static Path copyTo(URL url, Path tempDir, String fileName) throws IOException { + Path tempFile = tempDir.resolve(fileName); + try (InputStream in = url.openStream()) { + Files.copy(in, tempFile); + } + return tempFile; + } + + private AgentFileProvider() {} +} diff --git a/runtime-attach/src/main/java/io/opentelemetry/contrib/attach/RuntimeAttach.java b/runtime-attach/src/main/java/io/opentelemetry/contrib/attach/RuntimeAttach.java index e12285d0..0eeabf48 100644 --- a/runtime-attach/src/main/java/io/opentelemetry/contrib/attach/RuntimeAttach.java +++ b/runtime-attach/src/main/java/io/opentelemetry/contrib/attach/RuntimeAttach.java @@ -28,7 +28,7 @@ public final class RuntimeAttach { return; } - File javaagentFile = AgentFileLocator.locateAgentFile(); + File javaagentFile = AgentFileProvider.getAgentFile(); ByteBuddyAgent.attach(javaagentFile, getPid()); if (!agentIsAttached()) {