Merge pull request #259 from DataDog/ark/type_hunting
Check parent classloaders when resource location fails.
This commit is contained in:
commit
216cf688a3
|
@ -41,6 +41,7 @@ public class AgentInstaller {
|
|||
.disableClassFormatChanges()
|
||||
.with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
|
||||
.with(new LoggingListener())
|
||||
.with(new DDLocationStrategy())
|
||||
.ignore(nameStartsWith("datadog.trace."))
|
||||
.or(nameStartsWith("datadog.opentracing."))
|
||||
.or(nameStartsWith("datadog.slf4j."))
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
package datadog.trace.agent.tooling;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import net.bytebuddy.dynamic.ClassFileLocator;
|
||||
import net.bytebuddy.utility.JavaModule;
|
||||
|
||||
/**
|
||||
* Locate resources with the loading classloader. If the loading classloader cannot find the desired
|
||||
* resource, check up the classloader hierarchy until a resource is found or the bootstrap loader is
|
||||
* reached.
|
||||
*/
|
||||
public class DDLocationStrategy implements AgentBuilder.LocationStrategy {
|
||||
private static final ClassLoader BOOTSTRAP_RESOURCE_LOCATOR = new ClassLoader(null) {};
|
||||
|
||||
@Override
|
||||
public ClassFileLocator classFileLocator(ClassLoader classLoader, JavaModule javaModule) {
|
||||
List<ClassFileLocator> locators = new ArrayList<ClassFileLocator>();
|
||||
while (classLoader != null) {
|
||||
locators.add(ClassFileLocator.ForClassLoader.of(classLoader));
|
||||
classLoader = classLoader.getParent();
|
||||
}
|
||||
locators.add(ClassFileLocator.ForClassLoader.of(BOOTSTRAP_RESOURCE_LOCATOR));
|
||||
return new ClassFileLocator.Compound(locators.toArray(new ClassFileLocator[0]));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package datadog.trace.agent.test
|
||||
|
||||
import datadog.trace.agent.tooling.DDLocationStrategy
|
||||
import net.bytebuddy.agent.builder.AgentBuilder
|
||||
import net.bytebuddy.dynamic.ClassFileLocator
|
||||
import spock.lang.Specification
|
||||
|
||||
class ResourceLocatingTest extends Specification {
|
||||
def "finds resources from parent classloader"() {
|
||||
setup:
|
||||
final String[] lastLookup = new String[1]
|
||||
ClassLoader childLoader = new ClassLoader(this.getClass().getClassLoader()) {
|
||||
@Override
|
||||
URL getResource(String name) {
|
||||
lastLookup[0] = name
|
||||
// do not delegate resource lookup
|
||||
return findResource(name)
|
||||
}
|
||||
}
|
||||
ClassFileLocator locator = new DDLocationStrategy().classFileLocator(childLoader, null)
|
||||
ClassFileLocator defaultLocator = AgentBuilder.LocationStrategy.ForClassLoader.STRONG.classFileLocator(childLoader, null)
|
||||
|
||||
expect:
|
||||
locator.locate("java/lang/Object").isResolved()
|
||||
// lastLookup ensures childLoader was checked before parent for the resource
|
||||
lastLookup[0] == "java/lang/Object.class"
|
||||
(lastLookup[0] = null) == null
|
||||
|
||||
!defaultLocator.locate("java/lang/Object").isResolved()
|
||||
lastLookup[0] == "java/lang/Object.class"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue