有一次在测试环境想看resources下面的mapper文件内容(代码执行和预期不一致,所以想排查一下是不是打上去的包有问题,没有通过下载jar的方式解压查看),然后想到了使用arthas来弄,这里记录一下怎么个查看法。
- 首先启动arthas,我一般都是通过
java -jar arthas-boot.jar
的方式,启动之后选择所要附加的程序 - 随便找一个已经加载到jvm中的类,最好不要用jdk里面的,全类名,通过
sc -d 全类名
查看类加载的信息,主要是拿到classLoaderHash
后面有用
比如我这里拿一个hutool工具包里面的StrUtil类,换成项目中自己建的类也行
控制台输入sc -d cn.hutool.core.util.StrUtil
回车,然后就可以看到 classLoaderHash 18b4aac2
- 使用arthas的ognl指令执行代码,获取文件内容
因为ognl指令可以执行表达式,所以获取文件内容就很简单了,大概的思路就是先获取一个resource下面的文件输入流,然后读取流的内容。因为大部分项目都用了hutool工具包,所以这边使用hutool工具包里面的ResourceUtil类来获取,ResourceUtil类有一个readUtf8Str方法,传入一个classpath的路径,返回值是字符串。如果自己读取的话,要考虑流关闭的情况(毕竟控制台写一堆内容也不太方便阅读),所以就用hutool工具包了。
指令:ognl -c 18b4aac2 '@cn.hutool.core.io.resource.ResourceUtil@readUtf8Str("HobbyMapper.xml")'
18b4aac2就是步骤2中获取的classLoaderHash,说白了就是指定使用哪个类加载器,@cn.hutool.core.io.resource.ResourceUtil代表使用ResourceUtil这个类@readUtf8Str代表调用前面那个类的readUtf8Str方法,里面传参的内容就是clpasspath中文件的路径(可以不用加上classpath:前缀),这里我是想查看resources目录下面的HobbyMapper.xml文件内容,实际上这个项目中没有这个文件,我们查看一下输出的结果是什么
可以看到提示这个路径下面的资源不存在,接下来换一个存在的文件进行查看,比如sitLog/logback.xml文件(大家改成自己的)
ognl -c 18b4aac2 '@cn.hutool.core.io.resource.ResourceUtil@readUtf8Str("sitLog/logback.xml")'
换成一个存在的文件就能正常的输出文件内容了,里面的\r\n是转义字符,可以复制出来查看