jad

反编译指定已加载类的源码

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

  • 在 Arthas Console 上,反编译出来的源码是带语法高亮的,阅读更方便
  • 当然,反编译出来的 java 代码可能会存在语法错误,但不影响你进行阅读理解

参数说明

参数名称 参数说明
class-pattern 类名表达式匹配
[c:] 类所属 ClassLoader 的 hashcode
[E] 开启正则表达式匹配,默认为通配符匹配

使用参考

当有多个 ClassLoader 都加载了这个类时,jad 命令会输出对应 ClassLoader 实例的 hashcode,然后你只需要重新执行 jad 命令,并使用参数 -c <hashcode> 就可以反编译指定 ClassLoader 加载的那个类了;
  1. $ jad org.apache.log4j.Logger
  2.  
  3. Found more than one class for: org.apache.log4j.Logger, Please use jad -c hashcode org.apache.log4j.Logger
  4. HASHCODE CLASSLOADER
  5. 69dcaba4 +-monitor's ModuleClassLoader
  6. 6e51ad67 +-java.net.URLClassLoader@6e51ad67
  7. +-sun.misc.Launcher$AppClassLoader@6951a712
  8. +-sun.misc.Launcher$ExtClassLoader@6fafc4c2
  9. 2bdd9114 +-pandora-qos-service's ModuleClassLoader
  10. 4c0df5f8 +-pandora-framework's ModuleClassLoader
  11.  
  12. Affect(row-cnt:0) cost in 38 ms.
  13. $ jad org.apache.log4j.Logger -c 69dcaba4
  14.  
  15. ClassLoader:
  16. +-monitor's ModuleClassLoader
  17.  
  18. Location:
  19. /Users/zhuyong/Downloads/taobao-hsf.sar/plugins/monitor/lib/log4j-1.2.14.jar
  20.  
  21. package org.apache.log4j;
  22.  
  23. import org.apache.log4j.spi.*;
  24.  
  25. public class Logger extends Category
  26. {
  27. private static final String FQCN;
  28.  
  29. protected Logger(String name)
  30. {
  31. super(name);
  32. }
  33.  
  34. public static Logger getLogger(String name)
  35. {
  36. return LogManager.getLogger(name);
  37. }
  38.  
  39. public static Logger getLogger(Class clazz)
  40. {
  41. return LogManager.getLogger(clazz.getName());
  42. }
  43.  
  44. public static Logger getRootLogger()
  45. {
  46. return LogManager.getRootLogger();
  47. }
  48.  
  49. public static Logger getLogger(String name, LoggerFactory factory)
  50. {
  51. return LogManager.getLogger(name, factory);
  52. }
  53.  
  54. public void trace(Object message)
  55. {
  56. if (repository.isDisabled(5000))
  57. {
  58. return;
  59. }
  60. if (Level.TRACE.isGreaterOrEqual(getEffectiveLevel()))
  61. {
  62. forcedLog(Logger.FQCN, Level.TRACE, message, null);
  63. }
  64. }
  65.  
  66. public void trace(Object message, Throwable t)
  67. {
  68. if (repository.isDisabled(5000))
  69. {
  70. return;
  71. }
  72. if (Level.TRACE.isGreaterOrEqual(getEffectiveLevel()))
  73. {
  74. forcedLog(Logger.FQCN, Level.TRACE, message, t);
  75. }
  76. }
  77.  
  78. public boolean isTraceEnabled()
  79. {
  80. if (repository.isDisabled(5000))
  81. {
  82. return false;
  83. }
  84. return Level.TRACE.isGreaterOrEqual(getEffectiveLevel());
  85. }
  86.  
  87. static
  88. {
  89. Logger.FQCN = Logger.class.getName();
  90. }
  91.  
  92. }
  93.  
  94. Affect(row-cnt:1) cost in 190 ms.

反编译指定的方法:

  1. $ jad com.taobao.container.web.arthas.rest.MetricsController directMetrics
  2.  
  3. ClassLoader:
  4. +-com.taobao.pandora.boot.loader.ReLaunchURLClassLoader@1817d444
  5. +-sun.misc.Launcher$AppClassLoader@14dad5dc
  6. +-sun.misc.Launcher$ExtClassLoader@a38d7a3
  7.  
  8. Location:
  9. /Users/zhuyong/middleware/tomcat-web/tomcat-web-web/target/classes/
  10.  
  11. private Map<String, Object> directMetrics(String ip, String[] metrics) {
  12. JSONObject obj;
  13. HashMap<String, Object> result = new HashMap<String, Object>();
  14. result.put("success", false);
  15. String metricUrl = "http://" + ip + ":8006/metrics/specific";
  16. String postBody = Arrays.stream(metrics).map(metric -> "metric=" + metric).collect(Collectors.joining("&"));
  17. HttpClientUtils.Response resp = HttpClientUtils.sendPostRequest((String)metricUrl, (String)postBody);
  18. if (resp.isSuccess() && (obj = JSON.parseObject(resp.getContent())).containsKey("success") && obj.getBoolean("success").booleanValue() && obj.containsKey("data")) {
  19. JSONArray dataArray = obj.getJSONArray("data");
  20. HashMap<String, Object> metricMap = new HashMap<String, Object>();
  21. for (Object aDataArray : dataArray) {
  22. JSONObject o = (JSONObject)aDataArray;
  23. metricMap.put(o.getString("metric"), o.get("value"));
  24. }
  25. result.put("data", metricMap);
  26. result.put("success", true);
  27. return result;
  28. }
  29. return result;
  30. }
  31.  
  32. Affect(row-cnt:1) cost in 1508 ms.

原文: https://alibaba.github.io/arthas/jad.html