dd-trace-java
dd-trace-java copied to clipboard
muzzle.mismatch="datadog.trace.instrumentation.springweb.DatadogByteArrayOutputStream:36 Missing class B"
I have created a custom class that inherits from the OutputStream class, and when the application starts and loads, a Missing class B exception occurs. I am not sure what class B is, could you help me take a look?
[dd.trace 2024-10-28 18:15:26:999 +0800] [main] DEBUG datadog.trace.agent.tooling.muzzle.MuzzleCheck - Muzzled mismatch - instrumentation.names=[spring-web] instrumentation.class=datadog.trace.instrumentation.springweb.DispatcherServletInstrumentation instrumentation.target.classloader=jdk.internal.loader.ClassLoaders$AppClassLoader@512ddf17 muzzle.mismatch="datadog.trace.instrumentation.springweb.DatadogByteArrayOutputStream:36 Missing class B"
line 36
if (this.buffers.peekLast() == null || (this.buffers.getLast()).length == this.index) {
code DatadogByteArrayOutputStream
package datadog.trace.instrumentation.springweb;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Iterator;
public class DatadogByteArrayOutputStream extends OutputStream {
private static final int DEFAULT_BLOCK_SIZE = 256;
private final Deque<byte[]> buffers = new ArrayDeque();
private final int initialBlockSize;
private int nextBlockSize;
private int alreadyBufferedSize;
private int index;
private boolean closed;
public DatadogByteArrayOutputStream() {
this(256);
}
public DatadogByteArrayOutputStream(int initialBlockSize) {
this.nextBlockSize = 0;
this.alreadyBufferedSize = 0;
this.index = 0;
this.closed = false;
this.initialBlockSize = initialBlockSize;
this.nextBlockSize = initialBlockSize;
}
public void write(int datum) throws IOException {
if (this.closed) {
throw new IOException("Stream closed");
} else {
if (this.buffers.peekLast() == null || (this.buffers.getLast()).length == this.index) {
this.addBuffer(1);
}
(this.buffers.getLast())[this.index++] = (byte)datum;
}
}
public void write(byte[] data, int offset, int length) throws IOException {
if (offset >= 0 && offset + length <= data.length && length >= 0) {
if (this.closed) {
throw new IOException("Stream closed");
} else {
if (this.buffers.peekLast() == null || ((byte[])this.buffers.getLast()).length == this.index) {
this.addBuffer(length);
}
if (this.index + length > ((byte[])this.buffers.getLast()).length) {
int pos = offset;
do {
if (this.index == ((byte[])this.buffers.getLast()).length) {
this.addBuffer(length);
}
int copyLength = ((byte[])this.buffers.getLast()).length - this.index;
if (length < copyLength) {
copyLength = length;
}
System.arraycopy(data, pos, this.buffers.getLast(), this.index, copyLength);
pos += copyLength;
this.index += copyLength;
length -= copyLength;
} while(length > 0);
} else {
System.arraycopy(data, offset, this.buffers.getLast(), this.index, length);
this.index += length;
}
}
} else {
throw new IndexOutOfBoundsException();
}
}
public void close() {
this.closed = true;
}
public String toString() {
return new String(this.toByteArrayUnsafe());
}
public int size() {
return this.alreadyBufferedSize + this.index;
}
public byte[] toByteArrayUnsafe() {
int totalSize = this.size();
if (totalSize == 0) {
return new byte[0];
} else {
this.resize(totalSize);
return (byte[])this.buffers.getFirst();
}
}
public byte[] toByteArray() {
byte[] bytesUnsafe = this.toByteArrayUnsafe();
return (byte[])bytesUnsafe.clone();
}
public void reset() {
this.buffers.clear();
this.nextBlockSize = this.initialBlockSize;
this.closed = false;
this.index = 0;
this.alreadyBufferedSize = 0;
}
public void writeTo(OutputStream out) throws IOException {
Iterator<byte[]> it = this.buffers.iterator();
while(it.hasNext()) {
byte[] bytes = (byte[])it.next();
if (it.hasNext()) {
out.write(bytes, 0, bytes.length);
} else {
out.write(bytes, 0, this.index);
}
}
}
public void resize(int targetCapacity) {
if (this.buffers.peekFirst() == null) {
this.nextBlockSize = targetCapacity - this.size();
} else if (this.size() != targetCapacity || ((byte[])this.buffers.getFirst()).length != targetCapacity) {
int totalSize = this.size();
byte[] data = new byte[targetCapacity];
int pos = 0;
Iterator<byte[]> it = this.buffers.iterator();
while(it.hasNext()) {
byte[] bytes = (byte[])it.next();
if (it.hasNext()) {
System.arraycopy(bytes, 0, data, pos, bytes.length);
pos += bytes.length;
} else {
System.arraycopy(bytes, 0, data, pos, this.index);
}
}
this.buffers.clear();
this.buffers.add(data);
this.index = totalSize;
this.alreadyBufferedSize = 0;
}
}
private void addBuffer(int minCapacity) {
if (this.buffers.peekLast() != null) {
this.alreadyBufferedSize += this.index;
this.index = 0;
}
if (this.nextBlockSize < minCapacity) {
this.nextBlockSize = nextPowerOf2(minCapacity);
}
this.buffers.add(new byte[this.nextBlockSize]);
this.nextBlockSize *= 2;
}
private static int nextPowerOf2(int val) {
--val;
val |= val >> 1;
val |= val >> 2;
val |= val >> 4;
val |= val >> 8;
val |= val >> 16;
++val;
return val;
}
}
DispatcherServletInstrumentation class add helperClassNames
@AutoService(InstrumenterModule.class)
public final class DispatcherServletInstrumentation extends InstrumenterModule.Tracing
implements Instrumenter.ForSingleType {
public DispatcherServletInstrumentation() {
super("spring-web");
}
@Override
public String instrumentedType() {
return "org.springframework.web.servlet.DispatcherServlet";
}
@Override
public String[] helperClassNames() {
return new String[] {
packageName + ".SpringWebHttpServerDecorator",
packageName + ".ServletRequestURIAdapter",
packageName + ".HandlerMappingResourceNameFilter",
packageName + ".PathMatchingHttpServletRequestWrapper",
packageName + ".DataDogHttpServletResponseWrapper",
//packageName + ".DataDogHttpServletResponseWrapper$WrapperOutputStream"
packageName + ".DataDogHttpServletResponseWrapper$CustomServletOutputStream",
packageName+".ContentCachingResponseWrapper",
packageName+".ContentCachingResponseWrapper$ResponseServletOutputStream",
packageName+".ContentCachingResponseWrapper$ResponsePrintWriter",
packageName+".DatadogByteArrayOutputStream",
};
}
...