Compatible with other javaagent bytecode processing

Problem

  1. When use skywalking agent, some other agent, such as Arthas, can't work well https://github.com/apache/skywalking/pull/4858

  2. Java agent retransforming class fails with Skywalking agent, such as in this demo

Reason

SkyWalking agent uses ByteBuddy to transform classes when the Java application starts. ByteBuddy generates auxiliary classes with different random names every time.

When another java agent retransforms the same class, it triggers the SkyWalking agent to enhance the class again. The bytecode regenerated by ByteBuddy is changed, the fields and imported class names are modified, the JVM verifications about class bytecode fail, causing the retransform fails.

Resolve

1.Enable the class cache feature

Add JVM parameters:
-Dskywalking.agent.is_cache_enhanced_class=true -Dskywalking.agent.class_cache_mode=MEMORY

Or uncomment options in agent.conf:

# If true, SkyWalking agent will cache all instrumented classes files to memory or disk files (decided by class cache mode),
# allow other javaagent to enhance those classes that enhanced by SkyWalking agent.
agent.is_cache_enhanced_class = ${SW_AGENT_CACHE_CLASS:false}

# The instrumented classes cache mode: MEMORY or FILE
# MEMORY: cache class bytes to memory, if instrumented classes is too many or too large, it may take up more memory
# FILE: cache class bytes to user temp folder starts with 'class-cache', automatically clean up cached class files when the application exits
agent.class_cache_mode = ${SW_AGENT_CLASS_CACHE_MODE:MEMORY}

If the class cache feature is enabled, save the instrumented class bytecode to memory or a temporary file. When other java agents retransform the same class, SkyWalking agent first attempts to load from the cache.

If the cached class is found, it will be used directly without regenerating a new random name auxiliary class, which will not affect the processing of the subsequent java agent.

2.Class cache save mode
It is recommended to put the cache class in memory, meanwhile if it costs more memory resources. Another option is using the local file system. Set the class cache mode through the following options:
-Dskywalking.agent.class_cache_mode=MEMORY : save cache classes to java memory.
-Dskywalking.agent.class_cache_mode=FILE : save cache classes to SkyWalking agent path ‘/class-cache’.

Or modify the option in agent.conf:

agent.class_cache_mode = ${SW_AGENT_CLASS_CACHE_MODE:MEMORY}
agent.class_cache_mode = ${SW_AGENT_CLASS_CACHE_MODE:FILE}