Merge pull request #448 from DataDog/ark/parallel-dd-loader
Register Datadog classloader as parallel capable
This commit is contained in:
commit
962af76bb5
|
@ -5,6 +5,10 @@ import java.net.URLClassLoader;
|
|||
|
||||
/** Classloader used to run the core datadog agent. */
|
||||
public class DatadogClassLoader extends URLClassLoader {
|
||||
static {
|
||||
ClassLoader.registerAsParallelCapable();
|
||||
}
|
||||
|
||||
// Calling java.lang.instrument.Instrumentation#appendToBootstrapClassLoaderSearch
|
||||
// adds a jar to the bootstrap class lookup, but not to the resource lookup.
|
||||
// As a workaround, we keep a reference to the bootstrap jar
|
||||
|
@ -45,6 +49,10 @@ public class DatadogClassLoader extends URLClassLoader {
|
|||
* <p>This class is thread safe.
|
||||
*/
|
||||
public static final class BootstrapClassLoaderProxy extends URLClassLoader {
|
||||
static {
|
||||
ClassLoader.registerAsParallelCapable();
|
||||
}
|
||||
|
||||
public BootstrapClassLoaderProxy(URL[] urls, ClassLoader parent) {
|
||||
super(urls, parent);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
package datadog.trace.bootstrap
|
||||
|
||||
import spock.lang.Specification
|
||||
import spock.lang.Timeout
|
||||
|
||||
import java.util.concurrent.Phaser
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class DatadogClassLoaderTest extends Specification {
|
||||
@Timeout(value = 60, unit = TimeUnit.SECONDS)
|
||||
def "DD classloader does not lock classloading around instance" () {
|
||||
setup:
|
||||
def className1 = 'some/class/Name1'
|
||||
def className2 = 'some/class/Name2'
|
||||
final URL loc = getClass().getProtectionDomain().getCodeSource().getLocation()
|
||||
final DatadogClassLoader ddLoader = new DatadogClassLoader(loc, loc, (ClassLoader) null)
|
||||
final Phaser threadHoldLockPhase = new Phaser(2)
|
||||
final Phaser acquireLockFromMainThreadPhase = new Phaser(2)
|
||||
|
||||
when:
|
||||
final Thread thread1 = new Thread() {
|
||||
@Override
|
||||
void run() {
|
||||
synchronized (ddLoader.getClassLoadingLock(className1)) {
|
||||
threadHoldLockPhase.arrive()
|
||||
acquireLockFromMainThreadPhase.arriveAndAwaitAdvance()
|
||||
}
|
||||
}
|
||||
}
|
||||
thread1.start()
|
||||
|
||||
final Thread thread2 = new Thread() {
|
||||
@Override
|
||||
void run() {
|
||||
threadHoldLockPhase.arriveAndAwaitAdvance()
|
||||
synchronized (ddLoader.getClassLoadingLock(className2)) {
|
||||
acquireLockFromMainThreadPhase.arrive()
|
||||
}
|
||||
}
|
||||
}
|
||||
thread2.start()
|
||||
thread1.join()
|
||||
thread2.join()
|
||||
boolean applicationDidNotDeadlock = true
|
||||
|
||||
then:
|
||||
applicationDidNotDeadlock
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue