ClassNotFoundException : com.fasterxml.jackson.core.type.TypeReference

APM Server version:
1.28.4

** Attaching APM agent **:
By VM option:
-javaagent:lib/elastic-apm-agent.jar

** Java **:
1.8

Hello,

In our application we create view where admin can check current APM agent configuration. Admin can easy change for example configuration for sanitize_field_names property.

We show all available properties. To achieve this we use reflection. We use ElasticApmTracer.getConfigurationRegistry() which return ConfigurationRegistry object from Stagemonitor library.

This view stop working after move APM agent to isolated class loader.

Of course our view broke down. Application class loader can not find class from APM.

I try to figured out how to fix this view. For some internal reason we maintain own APM agent with custom changes. For test I simply add to co.elastic.apm.agent.premain.AgentMain

public static URLClassLoader getAgentClassLoader() {
        return agentClassLoader;
}

I use this dirty "hack" in our application with reflection and APM class loader. For example:

 var clazz = Class.forName("co.elastic.apm.agent.impl.ElasticApmTracer", false, AgentMain.getAgentClassLoader)

When I call (by reflection) code from ConfigurationRegistry.getConfigurationOptionsByKey() which return ConfigurationOption object I get exception:

ClassNotFoundException : com.fasterxml.jackson.core.type.TypeReference

ConfigurationOption from Stagemonitor has dependency to jackson library and ConfigurationOption import some packages from that library. Exception occure because there is no jackson class in class patch. I check original APM jar "apm-agent-attach-1.28.4.jar" from maven repo. In patch "agent/com" I can't find classes from jackson lib.

This is expected behavior ? How class ElasticApmAgent use ConfigurationOption without this class on class patch ?

I'm aware that reflection and custom changes can be problematic, error can back in any agent update and is not good practice.

Thank you

Why aren't you using the central configuration feature in Kibana?

As you mentioned, you're pretty deep in unsupported territory. But it could help to see the full stack trace. Normally, the ConfigurationOption should get linked lazily so that unless you're invoking org.stagemonitor.configuration.ConfigurationOption#jsonOption, the missing type doesn't cause an issue. Maybe you're calling ConfigurationOption.class.getMethods() or similar which causes the Jackson classes to be linked?

You might be interested in external plugins

Hi @sadu !

Most of the agent is now loaded in a separate classloader that is not accessible from the application, this is intentional and now part of the agent architecture as it provides many benefits:

  • avoids having agent classes visible from the application, which helps to prevent side-effects when runtime classpath-scanning is used.
  • avoids requirement to shade agent classes and dependencies (simpler packaging and debugging)

Before this change the agent was accessible directly from the application, but it was an implementation detail, and it was never meant to be a supported way to handle configuration.

However, one better and simpler alternative would be to store configuration in a properties file (external to the application, not in classpath resources) then allow modifications to this file through your application.

Not all options can be change from this view.

Yes I call ConfigurationOption.class.getMethods() to invoke for example "getKey" or "valueAsString".

So, this is expected behavior. Add jackson to classpatch in our own plugin solves problem, but maybe you have a better idea ?

This is what we do, but we want to show user all possible properties that could be set/change. That's why we need all possible keys. When user set something we save this to external properties file.

Use Class::getMethod instead.

Hi @felixbarny ,
Thank for tip. I'm afraid I can't do that, because I can't access the definition of APM class and use method reference operator like you suggest. I can use only reflection.

This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.