private static AgentBuilder getAgentBuilder(final ByteBuddy byteBuddy, final CoreConfigurationImpl coreConfiguration, final Logger logger,
final AgentBuilder.DescriptionStrategy descriptionStrategy, final boolean premain,
final boolean useTypePoolCache) {
AgentBuilder.LocationStrategy locationStrategy = AgentBuilder.LocationStrategy.ForClassLoader.WEAK;
if (agentJarFile != null) {
try {
locationStrategy = new AgentBuilder.LocationStrategy.Compound(
// it's important to first try loading from the agent jar and not the class loader of the instrumented class
// the latter may not have access to the agent resources:
// when adding the agent to the bootstrap CL (appendToBootstrapClassLoaderSearch)
// the bootstrap CL can load its classes but not its resources
// the application class loader may cache the fact that a resource like AbstractSpan.class can't be resolved
// and also refuse to load the class
new AgentBuilder.LocationStrategy.Simple(ClassFileLocator.ForJarFile.of(agentJarFile)),
AgentBuilder.LocationStrategy.ForClassLoader.WEAK,
new AgentBuilder.LocationStrategy.Simple(new RootPackageCustomLocator("java.", ClassFileLocator.ForClassLoader.ofBootLoader()))
);
} catch (IOException e) {
logger.warn("Failed to add ClassFileLocator for the agent jar. Some instrumentations may not work", e);
}
}
...
}
The comment here indicates that it is important to resolve types from within the Agent Jar first.
However, with the commit: c5fede1f Isolated agent classloader, all Agent class files have been shadowed and have the suffix .esclass
. This means that using the usual ClassLocator.ForJarFile
should not be able to resolve these class files, such as co.elastic.apm.agent.bci.ElasticApmAgent
and the more specific java.lang.IndyBootstrapDispatcher
.
I'm working on customizing my own Javaagent based on Elastic. For the sake of correctness, I want to know if this behavior is expected. Can anyone help?