Merge pull request #968 from DataDog/landerson/better-internal-jar

Change packaging of internal jars
This commit is contained in:
Laplie Anderson 2019-08-30 15:09:41 -04:00 committed by GitHub
commit d94f5df00e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 42 additions and 38 deletions

View File

@ -51,7 +51,7 @@ public class DatadogClassLoader extends URLClassLoader {
null, null,
0, 0,
"/", "/",
new InternalJarURLHandler(internalJarFileName, bootstrapProxy)); new InternalJarURLHandler(internalJarFileName, bootstrapJarLocation));
addURL(internalJarURL); addURL(internalJarURL);
} catch (final MalformedURLException e) { } catch (final MalformedURLException e) {

View File

@ -2,58 +2,63 @@ package datadog.trace.bootstrap;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
import java.net.URLConnection; import java.net.URLConnection;
import java.net.URLStreamHandler; import java.net.URLStreamHandler;
import java.nio.file.NoSuchFileException; import java.nio.file.NoSuchFileException;
import java.security.Permission; import java.security.Permission;
import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.jar.JarEntry; import java.util.jar.JarEntry;
import java.util.jar.JarInputStream; import java.util.jar.JarFile;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
public class InternalJarURLHandler extends URLStreamHandler { public class InternalJarURLHandler extends URLStreamHandler {
private final Map<String, byte[]> filenameToBytes = new HashMap<>(); private final Map<String, JarEntry> filenameToEntry = new HashMap<>();
private JarFile bootstrapJarFile;
InternalJarURLHandler( InternalJarURLHandler(final String internalJarFileName, final URL bootstrapJarLocation) {
final String internalJarFileName, final ClassLoader classloaderForJarResource) { try {
if (bootstrapJarLocation != null) {
bootstrapJarFile = new JarFile(new File(bootstrapJarLocation.toURI()));
final Enumeration<JarEntry> entries = bootstrapJarFile.entries();
while (entries.hasMoreElements()) {
final JarEntry entry = entries.nextElement();
// "/" is used as the default url of the jar if (!entry.isDirectory() && entry.getName().startsWith(internalJarFileName + "/")) {
// This is called by the SecureClassLoader trying to obtain permissions filenameToEntry.put(entry.getName().substring(internalJarFileName.length()), entry);
filenameToBytes.put("/", new byte[] {});
final InputStream jarStream =
internalJarFileName == null
? null
: classloaderForJarResource.getResourceAsStream(internalJarFileName);
if (jarStream != null) {
try (final JarInputStream inputStream = new JarInputStream(jarStream)) {
JarEntry entry = inputStream.getNextJarEntry();
while (entry != null) {
filenameToBytes.put("/" + entry.getName(), getBytes(inputStream));
entry = inputStream.getNextJarEntry();
} }
}
} catch (final IOException e) { }
} catch (final URISyntaxException | IOException e) {
log.error("Unable to read internal jar", e); log.error("Unable to read internal jar", e);
} }
} else {
log.error("Internal jar not found"); if (filenameToEntry.isEmpty()) {
log.warn("Internal jar entries found");
} }
} }
@Override @Override
protected URLConnection openConnection(final URL url) throws IOException { protected URLConnection openConnection(final URL url) throws IOException {
final byte[] bytes = filenameToBytes.get(url.getFile());
if (bytes == null) { final byte[] bytes;
final String filename = url.getFile().replaceAll("\\.class$", ".classdata");
if ("/".equals(filename)) {
// "/" is used as the default url of the jar
// This is called by the SecureClassLoader trying to obtain permissions
bytes = new byte[0];
} else if (filenameToEntry.containsKey(filename)) {
final JarEntry entry = filenameToEntry.get(filename);
bytes = getBytes(bootstrapJarFile.getInputStream(entry));
} else {
throw new NoSuchFileException(url.getFile(), null, url.getFile() + " not in internal jar"); throw new NoSuchFileException(url.getFile(), null, url.getFile() + " not in internal jar");
} }

View File

@ -26,13 +26,12 @@ def includeShadowJar(subproject, jarname) {
def agent_project = project def agent_project = project
subproject.afterEvaluate { subproject.afterEvaluate {
agent_project.processResources { agent_project.processResources {
from(subproject.tasks.shadowJar) from(zipTree(subproject.tasks.shadowJar.archivePath)) {
rename { into jarname
it.equals(subproject.shadowJar.archivePath.getName()) ? rename '(^.*)\\.class$', '$1.classdata'
jarname :
it
} }
} }
agent_project.processResources.dependsOn subproject.tasks.shadowJar agent_project.processResources.dependsOn subproject.tasks.shadowJar
subproject.shadowJar { subproject.shadowJar {
classifier null classifier null
@ -59,8 +58,8 @@ def includeShadowJar(subproject, jarname) {
} }
} }
includeShadowJar(project(':dd-java-agent:instrumentation'), 'agent-tooling-and-instrumentation.jar.zip') includeShadowJar(project(':dd-java-agent:instrumentation'), 'agent-tooling-and-instrumentation.isolated')
includeShadowJar(project(':dd-java-agent:agent-jmxfetch'), 'agent-jmxfetch.jar.zip') includeShadowJar(project(':dd-java-agent:agent-jmxfetch'), 'agent-jmxfetch.isolated')
jar { jar {
classifier = 'unbundled' classifier = 'unbundled'

View File

@ -94,7 +94,7 @@ public class TracingAgent {
if (AGENT_CLASSLOADER == null) { if (AGENT_CLASSLOADER == null) {
final ClassLoader agentClassLoader = final ClassLoader agentClassLoader =
createDatadogClassLoader("agent-tooling-and-instrumentation.jar.zip", bootstrapURL); createDatadogClassLoader("agent-tooling-and-instrumentation.isolated", bootstrapURL);
final ClassLoader contextLoader = Thread.currentThread().getContextClassLoader(); final ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
try { try {
Thread.currentThread().setContextClassLoader(agentClassLoader); Thread.currentThread().setContextClassLoader(agentClassLoader);
@ -126,7 +126,7 @@ public class TracingAgent {
throws Exception { throws Exception {
if (JMXFETCH_CLASSLOADER == null) { if (JMXFETCH_CLASSLOADER == null) {
final ClassLoader jmxFetchClassLoader = final ClassLoader jmxFetchClassLoader =
createDatadogClassLoader("agent-jmxfetch.jar.zip", bootstrapURL); createDatadogClassLoader("agent-jmxfetch.isolated", bootstrapURL);
final ClassLoader contextLoader = Thread.currentThread().getContextClassLoader(); final ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
try { try {
Thread.currentThread().setContextClassLoader(jmxFetchClassLoader); Thread.currentThread().setContextClassLoader(jmxFetchClassLoader);