写点什么

Arthas jad(字节码文件反编译成源代码 )

作者:刘大猫
  • 2025-05-08
    黑龙江
  • 本文字数:4207 字

    阅读完需:约 14 分钟


@[toc]

二、命令列表

2.2 class/classloader 相关命令

2.2.1 jad(字节码文件反编译成源代码 )

提示:

jad 命令将 JVM 中实际运行的 class 的 byte code 反编译成 java 代码,便于你理解业务逻辑


参数说明:


举例 1:反编译指定的函数 :jad com.hero.lte.ems.sysmanager.cache.SMTaskCache executeTask

基本用法:jad 全路径类名 方法名


[arthas@24056]$ jad com.hero.lte.ems.sysmanager.cache.SMTaskCache executeTask
ClassLoader: +-sun.misc.Launcher$AppClassLoader@18b4aac2 +-sun.misc.Launcher$ExtClassLoader@232204a1
Location: /home/ems/ems_eam/app/ems-eam-sysmanager-server-1.0-SNAPSHOT.jar
/* * WARNING - Removed try catching itself - possible behaviour change. */ public static void executeTask(Long sysTaskId, Date nextTime) { try {/*233*/ lock.writeLock().lock();/*234*/ Long curTime = System.currentTimeMillis();/*235*/ for (SmconfigDmTaskMain smconfigdmtaskmain : taskCache) {/*237*/ if (!smconfigdmtaskmain.getSysTaskId().equals(sysTaskId)) continue;/*240*/ if (smconfigdmtaskmain.getSysTaskEndTime() != null && smconfigdmtaskmain.getSysTaskEndTime().getTime() <= curTime) {/*241*/ smconfigdmtaskmain.setSysTaskState(SMTaskStatusEnum.PASTDUE.getCodeString());/*242*/ smconfigdmtaskmain.setTaskSwitch(SMTaskSwitchEnum.INVALID.getCode()); } else {/*244*/ smconfigdmtaskmain.setSysTaskState(SMTaskStatusEnum.EXECUTING.getCodeString());/*245*/ smconfigdmtaskmain.setTaskSwitch(SMTaskSwitchEnum.ACTIVE.getCode()); }/*247*/ smconfigdmtaskmain.setSysTaskNextTime(nextTime); } } finally {/*253*/ lock.writeLock().unlock(); } }
Affect(row-cnt:1) cost in 1003 ms.[arthas@24056]$
复制代码

举例 2:反编绎时只显示源代码(默认情况下,反编译结果里会带有 ClassLoader 信息)

默认情况下,反编译结果里会带有ClassLoader信息,通过--source-only选项,可以只打印源代码。方便和mc/retransform命令结合使用。


基本用法:jad --source-only 全路径类名 方法名


[arthas@24056]$ jad --source-only com.hero.lte.ems.sysmanager.cache.SMTaskCache executeTask        /*         * WARNING - Removed try catching itself - possible behaviour change.         */        public static void executeTask(Long sysTaskId, Date nextTime) {            try {/*233*/         lock.writeLock().lock();/*234*/         Long curTime = System.currentTimeMillis();/*235*/         for (SmconfigDmTaskMain smconfigdmtaskmain : taskCache) {/*237*/             if (!smconfigdmtaskmain.getSysTaskId().equals(sysTaskId)) continue;/*240*/             if (smconfigdmtaskmain.getSysTaskEndTime() != null && smconfigdmtaskmain.getSysTaskEndTime().getTime() <= curTime) {/*241*/                 smconfigdmtaskmain.setSysTaskState(SMTaskStatusEnum.PASTDUE.getCodeString());/*242*/                 smconfigdmtaskmain.setTaskSwitch(SMTaskSwitchEnum.INVALID.getCode());                    } else {/*244*/                 smconfigdmtaskmain.setSysTaskState(SMTaskStatusEnum.EXECUTING.getCodeString());/*245*/                 smconfigdmtaskmain.setTaskSwitch(SMTaskSwitchEnum.ACTIVE.getCode());                    }/*247*/             smconfigdmtaskmain.setSysTaskNextTime(nextTime);                }            }            finally {/*253*/         lock.writeLock().unlock();            }        }
[arthas@24056]$
复制代码

举例 3:反编译时不显示行号

基本用法:jad --source-only 全路径类名 方法名 --lineNumber false


--lineNumber 参数默认值为 true,显示指定为 false 则不打印行号。


[arthas@24056]$ jad --source-only com.hero.lte.ems.sysmanager.cache.SMTaskCache executeTask --lineNumber false/* * WARNING - Removed try catching itself - possible behaviour change. */public static void executeTask(Long sysTaskId, Date nextTime) {    try {        lock.writeLock().lock();        Long curTime = System.currentTimeMillis();        for (SmconfigDmTaskMain smconfigdmtaskmain : taskCache) {            if (!smconfigdmtaskmain.getSysTaskId().equals(sysTaskId)) continue;            if (smconfigdmtaskmain.getSysTaskEndTime() != null && smconfigdmtaskmain.getSysTaskEndTime().getTime() <= curTime) {                smconfigdmtaskmain.setSysTaskState(SMTaskStatusEnum.PASTDUE.getCodeString());                smconfigdmtaskmain.setTaskSwitch(SMTaskSwitchEnum.INVALID.getCode());            } else {                smconfigdmtaskmain.setSysTaskState(SMTaskStatusEnum.EXECUTING.getCodeString());                smconfigdmtaskmain.setTaskSwitch(SMTaskSwitchEnum.ACTIVE.getCode());            }            smconfigdmtaskmain.setSysTaskNextTime(nextTime);        }    }    finally {        lock.writeLock().unlock();    }}
[arthas@24056]$
复制代码

举例 4:反编译时指定 ClassLoader

提示:

当有多个 ClassLoader 都加载了这个类时,jad 命令会输出对应 ClassLoader 实例的 hashcode,然后你只需要重新执行 jad 命令,并使用参数 -c <hashcode> 就可以反编译指定 ClassLoader 加载的那个类了;


基本用法:jad 全路径类名


$ jad org.apache.log4j.Logger
Found more than one class for: org.apache.log4j.Logger, Please use jad -c hashcode org.apache.log4j.LoggerHASHCODE CLASSLOADER69dcaba4 +-monitor's ModuleClassLoader6e51ad67 +-java.net.URLClassLoader@6e51ad67 +-sun.misc.Launcher$AppClassLoader@6951a712 +-sun.misc.Launcher$ExtClassLoader@6fafc4c22bdd9114 +-pandora-qos-service's ModuleClassLoader4c0df5f8 +-pandora-framework's ModuleClassLoader
Affect(row-cnt:0) cost in 38 ms.$ jad org.apache.log4j.Logger -c 69dcaba4
ClassLoader:+-monitor's ModuleClassLoader
Location:/Users/admin/app/log4j-1.2.14.jar
package org.apache.log4j;
import org.apache.log4j.spi.*;
public class Logger extends Category{ private static final String FQCN;
protected Logger(String name) { super(name); }
...
Affect(row-cnt:1) cost in 190 ms.
复制代码


对于只有唯一实例的 ClassLoader 还可以通过--classLoaderClass指定 class name,使用起来更加方便:


--classLoaderClass 的值是 ClassLoader 的类名,只有匹配到唯一的 ClassLoader 实例时才能工作,目的是方便输入通用命令,而-c <hashcode>是动态变化的。

本人其他相关文章链接

1.Arthas 全攻略:让调试变得简单2.Arthas dashboard(当前系统的实时数据面板)3.Arthas thread(查看当前JVM的线程堆栈信息)4.Arthas jvm(查看当前JVM的信息)5.Arthas sysprop(查看和修改JVM的系统属性)6.Arthas sysenv(查看JVM的环境变量)7.Arthas vmoption(查看和修改 JVM里诊断相关的option)8.Arthas getstatic(查看类的静态属性 )9.Arthas heapdump(dump java heap, 类似 jmap 命令的 heap dump 功能)10.Arthas logger(查看 logger 信息,更新 logger level)11.Arthas mbean(查看 Mbean 的信息)12.Arthas memory(查看 JVM 内存信息)13.Arthas ognl(执行ognl表达式)14.Arthas perfcounter(查看当前 JVM 的 Perf Counter 信息)15.Arthas vmtool(从 jvm 里查询对象,执行 forceGc)16.Arthas jad(字节码文件反编译成源代码 )17.Arthas mc(Memory Compiler/内存编译器 )18.Arthas redefine(加载外部的.class文件,redefine到JVM里 )19.Arthas classloader (查看 classloader 的继承树,urls,类加载信息)20.Arthas sc(查看JVM已加载的类信息 )21.Arthas sm(查看已加载类的方法信息 )22.Arthas monitor(方法执行监控)23.Arthas stack (输出当前方法被调用的调用路径)24.Arthas trace (方法内部调用路径,并输出方法路径上的每个节点上耗时)25.Arthas tt(方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测)26.Arthas watch (方法执行数据观测)27.Arthas profiler(使用async-profiler对应用采样,生成火焰图)

用户头像

刘大猫

关注

还未添加个人签名 2022-08-23 加入

还未添加个人简介

评论

发布
暂无评论
Arthas jad(字节码文件反编译成源代码 )_监控_刘大猫_InfoQ写作社区