alibaba / arthas

Alibaba Java Diagnostic Tool Arthas/Alibaba Java诊断利器Arthas
https://arthas.aliyun.com/
Apache License 2.0
35.71k stars 7.51k forks source link

Spring web war 包 classloader -t 命令打印输出不符合预期 #2926

Open RaymondLam1 opened 1 month ago

RaymondLam1 commented 1 month ago

环境信息

arthas 4.0.0

重现问题的步骤

在 tomcat 运行 spring boot war 应用

https://github.com/RaymondLam1/spring-boot-war

期望的结果

正常输出 classloer tree

实际运行的结果

[arthas@39492]$ classloader -t
+-BootstrapClassLoader
+-sun.misc.Launcher$ExtClassLoader@604ed9f0
  +-com.taobao.arthas.agent.ArthasClassloader@43f89e
  | 84
  +-sun.misc.Launcher$AppClassLoader@70dea4e
    +-java.net.URLClassLoader@e9e54c2
                  bappClassLoader
          context: spring-boot-deployment-0.0.1-SNAP

            ------> Parent Classloader:
            .net.URLClassLoader@e9e54c2

[arthas@39492]$ classloader
 name
 BootstrapClassLoader
 org.apache.catalina.loader.ParallelWebappClassLoader
 com.taobao.arthas.agent.ArthasClassloader
 java.net.URLClassLoader
 sun.reflect.DelegatingClassLoader
 sun.misc.Launcher$ExtClassLoader
 sun.misc.Launcher$AppClassLoader

classloader -t 的树型输出可能有问题,缺少了 ParallelWebappClassLoader

hengyunabc commented 1 month ago

这个应该是 tomcat 的 classloader#toString() 输出有多行,可能被截断了。试下把窗口变大点。

RaymondLam1 commented 1 month ago

研究发现,Arthas 对 classloader -t 的处理符合预期:

+-BootstrapClassLoader                                                                                                                                                                                                                                                   
+-sun.misc.Launcher$ExtClassLoader@91161c7                                                                                                                                                                                                                               
  +-com.taobao.arthas.agent.ArthasClassloader@67690ffd                                                                                                                                                                                                                   
  +-sun.misc.Launcher$AppClassLoader@18b4aac2                                                                                                                                                                                                                            
    +-java.net.URLClassLoader@53d8d10a                                                                                                                                                                                                                                   
      +-ParallelWebappClassLoader

          context: spring-boot-deployment-0.0.1-SNAPSHOT

          delegate: false

        ----------> Parent Classloader:

        java.net.URLClassLoader@53d8d10a

但是在 TermHandler.java 对于 \r的处理是有问题的:

    @Override
    public String apply(String data) {
        term.write(data);
        return data;
    }

ParallelWebappClassLoader 刚好有 \r

    @Override
    public String toString() {

        StringBuilder sb = new StringBuilder(this.getClass().getSimpleName());
        sb.append("\r\n  context: ");
        sb.append(getContextName());
        sb.append("\r\n  delegate: ");
        sb.append(delegate);
        sb.append("\r\n");
        if (this.parent != null) {
            sb.append("----------> Parent Classloader:\r\n");
            sb.append(this.parent.toString());
            sb.append("\r\n");
        }
        if (this.transformers.size() > 0) {
            sb.append("----------> Class file transformers:\r\n");
            for (ClassFileTransformer transformer : this.transformers) {
                sb.append(transformer).append("\r\n");
            }
        }
        return sb.toString();
    }

现在考虑两种解决方式:1. classloader.toString() 的结果去除 \r;2. 研究 term 对 \r 的支持。个人倾向于第一种。