Don't copy to byte[], return input stream directly

This commit is contained in:
Laplie Anderson 2020-01-15 13:38:44 -05:00
parent 03c9bd5db8
commit 607c8f277e
1 changed files with 13 additions and 41 deletions

View File

@ -1,7 +1,6 @@
package datadog.trace.bootstrap; package datadog.trace.bootstrap;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -24,14 +23,16 @@ public class InternalJarURLHandler extends URLStreamHandler {
private JarFile bootstrapJarFile; private JarFile bootstrapJarFile;
InternalJarURLHandler(final String internalJarFileName, final URL bootstrapJarLocation) { InternalJarURLHandler(final String internalJarFileName, final URL bootstrapJarLocation) {
final String filePrefix = internalJarFileName + "/";
try { try {
if (bootstrapJarLocation != null) { if (bootstrapJarLocation != null) {
bootstrapJarFile = new JarFile(new File(bootstrapJarLocation.toURI())); bootstrapJarFile = new JarFile(new File(bootstrapJarLocation.toURI()), false);
final Enumeration<JarEntry> entries = bootstrapJarFile.entries(); final Enumeration<JarEntry> entries = bootstrapJarFile.entries();
while (entries.hasMoreElements()) { while (entries.hasMoreElements()) {
final JarEntry entry = entries.nextElement(); final JarEntry entry = entries.nextElement();
if (!entry.isDirectory() && entry.getName().startsWith(internalJarFileName + "/")) { if (!entry.isDirectory() && entry.getName().startsWith(filePrefix)) {
filenameToEntry.put(entry.getName().substring(internalJarFileName.length()), entry); filenameToEntry.put(entry.getName().substring(internalJarFileName.length()), entry);
} }
} }
@ -41,62 +42,33 @@ public class InternalJarURLHandler extends URLStreamHandler {
} }
if (filenameToEntry.isEmpty()) { if (filenameToEntry.isEmpty()) {
log.warn("Internal jar entries found"); log.warn("No 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;
final String filename = url.getFile().replaceAll("\\.class$", ".classdata"); final String filename = url.getFile().replaceAll("\\.class$", ".classdata");
if ("/".equals(filename)) { if ("/".equals(filename)) {
// "/" is used as the default url of the jar // "/" is used as the default url of the jar
// This is called by the SecureClassLoader trying to obtain permissions // This is called by the SecureClassLoader trying to obtain permissions
bytes = new byte[0];
// nullInputStream() is not available until Java 11
return new InternalJarURLConnection(url, new ByteArrayInputStream(new byte[0]));
} else if (filenameToEntry.containsKey(filename)) { } else if (filenameToEntry.containsKey(filename)) {
final JarEntry entry = filenameToEntry.get(filename); final JarEntry entry = filenameToEntry.get(filename);
bytes = getBytes(bootstrapJarFile.getInputStream(entry)); return new InternalJarURLConnection(url, bootstrapJarFile.getInputStream(entry));
} else { } 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");
} }
return new InternalJarURLConnection(url, bytes);
}
/**
* Standard "copy InputStream to byte[]" implementation using a ByteArrayOutputStream
*
* <p>IOUtils.toByteArray() or Java 9's InputStream.readAllBytes() could be replacements if they
* were available
*
* <p>This can be optimized using the JarEntry's size(), but its not always available
*
* @param inputStream stream to read
* @return a byte[] from the inputstream
*/
private static byte[] getBytes(final InputStream inputStream) throws IOException {
final byte[] buffer = new byte[4096];
int bytesRead = inputStream.read(buffer, 0, buffer.length);
try (final ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
while (bytesRead != -1) {
outputStream.write(buffer, 0, bytesRead);
bytesRead = inputStream.read(buffer, 0, buffer.length);
}
return outputStream.toByteArray();
}
} }
private static class InternalJarURLConnection extends URLConnection { private static class InternalJarURLConnection extends URLConnection {
private final byte[] bytes; private final InputStream inputStream;
private InternalJarURLConnection(final URL url, final byte[] bytes) { private InternalJarURLConnection(final URL url, final InputStream inputStream) {
super(url); super(url);
this.bytes = bytes; this.inputStream = inputStream;
} }
@Override @Override
@ -106,7 +78,7 @@ public class InternalJarURLHandler extends URLStreamHandler {
@Override @Override
public InputStream getInputStream() throws IOException { public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(bytes); return inputStream;
} }
@Override @Override