Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions dd-java-agent/agent-ci-visibility/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,6 @@ tasks.named("jar", Jar) {
archiveClassifier = 'unbundled'
}

tasks.named("compileTestGroovy") {
configureCompiler(
it,
8,
JavaVersion.VERSION_1_8,
"Groovy generates synthetic accessors methods from superclass, we don't want that for `MisbehavingClassLoader`," +
" otherwise anonymous class has one `loadClass` accessor's signature has `java.lang.Module`"
)
}

kotlin {
compilerOptions {
jvmTarget = JvmTarget.JVM_1_8
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,28 +81,5 @@ class ByteCodeLinesResolverTest extends Specification {

abstract void abstractMethod()
}

private static final class MisbehavingClassLoader extends ClassLoader {

private final Map<String, byte[]> classes = new HashMap<>()

@Override
InputStream getResourceAsStream(String name) {
throw new RuntimeException("Something went wrong")
}

@Override
Class<?> loadClass(String name) throws ClassNotFoundException {
def bytes = classes.get(name)
if (bytes != null) {
return defineClass(name, bytes, 0, bytes.length)
}
return super.loadClass(name)
}

void putClass(String name, byte[] bytes) {
classes.put(name, bytes)
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package datadog.trace.civisibility.source;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

/**
* A {@link ClassLoader} that defines classes from an in-memory map and fails resource lookups, used
* to exercise {@code ByteCodeLinesResolver} when a class cannot be loaded.
*
* <p>Kept in Java rather than the Groovy test on purpose: Groovy synthesizes super-accessors for
* every {@code ClassLoader} overload, including {@code loadClass(java.lang.Module, String)}, which
* references {@code java.lang.Module} and would break this Java 8 test suite.
*/
final class MisbehavingClassLoader extends ClassLoader {

private final Map<String, byte[]> classes = new HashMap<>();

@Override
public InputStream getResourceAsStream(String name) {
throw new RuntimeException("Something went wrong");
}

@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
byte[] bytes = classes.get(name);
if (bytes != null) {
return defineClass(name, bytes, 0, bytes.length);
}
return super.loadClass(name);
}

void putClass(String name, byte[] bytes) {
classes.put(name, bytes);
}
}
21 changes: 5 additions & 16 deletions dd-java-agent/agent-tooling/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -60,28 +60,17 @@ jmh {
}

tasks.named("compileJava") { dependsOn 'generateClassNameTries' }
tasks.named("sourcesJar") { dependsOn 'generateClassNameTries' }

tasks.named("compileJmhJava") { dependsOn tasks.named("compileTestJava") }
tasks.named("compileTestJava") { dependsOn('generateTestClassNameTries') }

tasks.named("forbiddenApisJmh") {
ignoreFailures = true
}
tasks.named("sourcesJar") { dependsOn 'generateClassNameTries' }

tasks.named("forbiddenApisJmh") { ignoreFailures = true }

tasks.named("compileTestJava") {
dependsOn('generateTestClassNameTries')
}
tasks.named("compileTestGroovy") {
configureCompiler(it,
8,
JavaVersion.VERSION_1_8,
"Groovy generates synthetic accessors methods from superclass, we don't want that for `URLClassLoader`," +
" otherwise anonymous class has one `loadClass` accessor's signature has `java.lang.Module`"
)
}
tasks.named("compileTest_java11Java") {
configureCompiler(it, 11, JavaVersion.VERSION_11)
}

tasks.named("compileTest_java21Java") {
configureCompiler(
it,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import datadog.environment.JavaVirtualMachine
import datadog.trace.agent.tooling.bytebuddy.ExceptionHandlers
import datadog.trace.bootstrap.ExceptionLogger
import datadog.trace.bootstrap.InstrumentationErrors
import datadog.trace.bootstrap.blocking.BlockingExceptionHandler
import datadog.trace.test.util.DDSpecification
import net.bytebuddy.agent.ByteBuddyAgent
import net.bytebuddy.agent.builder.AgentBuilder
Expand Down Expand Up @@ -128,18 +127,7 @@ abstract class BaseExceptionHandlerTest extends DDSpecification {
SomeClass.getProtectionDomain().getCodeSource().getLocation(),
GroovyObject.getProtectionDomain().getCodeSource().getLocation(),
]
URLClassLoader loader = new URLClassLoader(classpath, null, null) {
@Override
Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
if (name == BlockingExceptionHandler.name) {
return BlockingExceptionHandler
}
if (name == BlockingException.name) {
return BlockingException
}
return super.loadClass(name, resolve)
}
}
URLClassLoader loader = new NonDelegatingExceptionClassLoader(classpath)

when:
loader.loadClass(InstrumentationErrors.getName())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package datadog.trace.agent.test;

import datadog.appsec.api.blocking.BlockingException;
import datadog.trace.bootstrap.blocking.BlockingExceptionHandler;
import java.net.URL;
import java.net.URLClassLoader;

/**
* A {@link URLClassLoader} that resolves the blocking helper classes directly and delegates
* everything else to the supplied classpath only (no parent).
*
* <p>Kept in Java rather than the Groovy test on purpose: Groovy synthesizes a {@code
* super$N$loadClass(java.lang.Module, String)} accessor for {@code ClassLoader} subclasses, which
* references {@code java.lang.Module} and would break this Java 8 test suite.
*/
final class NonDelegatingExceptionClassLoader extends URLClassLoader {

NonDelegatingExceptionClassLoader(URL[] classpath) {
super(classpath, null, null);
}

@Override
public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
if (name.equals(BlockingExceptionHandler.class.getName())) {
return BlockingExceptionHandler.class;
}
if (name.equals(BlockingException.class.getName())) {
return BlockingException.class;
}
return super.loadClass(name, resolve);
}
}
Loading