## Compatibility with other Java agent bytecode processes

### Problem
1. When using the SkyWalking agent, some other agents, such as Arthas, can't work properly. 
https://github.com/apache/skywalking/pull/4858

2. The retransform classes in the Java agent conflict with the SkyWalking agent, as illustrated in this [demo](https://github.com/SkyAPMTest/retransform-conflict-demo)
 
### Cause
The 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. 
Since the bytecode has been regenerated by ByteBuddy, the fields and imported class names have been modified, and the JVM verifications on class bytecode have failed, the retransform classes would therefore be unsuccessful.


### Resolution

**1. Enable the class cache feature**  

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

Or uncomment the following options in `agent.conf`:
  
```
# If true, the SkyWalking agent will cache all instrumented classes files to memory or disk files (as determined by the class cache mode),
# Allow other Java agents to enhance those classes that are enhanced by the 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 there are too many instrumented classes or if their sizes are too large, it may take up more memory
# FILE: cache class bytes to user temp folder starts with 'class-cache', and 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, the SkyWalking agent first attempts to load from the cache.

If the cached class is found, it will be used directly without regenerating an auxiliary class with a new random name. 
Then, the process of the subsequent Java agent will not be affected.

**2. Class cache save mode**  
We recommend saving cache classes to memory, if it takes up more memory space. Alternatively, you can use the local file system. Set the class cache mode in one of the folliwng ways:  
`-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 these options in `agent.conf`:
  
`agent.class_cache_mode = ${SW_AGENT_CLASS_CACHE_MODE:MEMORY}`    
`agent.class_cache_mode = ${SW_AGENT_CLASS_CACHE_MODE:FILE}`    
