# jad [`jad` online tutorial](https://arthas.aliyun.com/doc/arthas-tutorials?language=en&id=command-jad) ::: tip Decompile the specified classes. ::: `jad` helps to decompile the byte code running in JVM to the source code to assist you to understand the logic behind better. If you need to download the bytecode of classes in a specific package directory in bulk, you can refer to the [dump](/en/doc/dump.md) tool for assistance. - The decompiled code is syntax highlighted for better readability in Arthas console. - It is possible that there's grammar error in the decompiled code, but it should not affect your interpretation. ## Options | Name | Specification | | --------------------: | :-------------------------------------------------------------- | | _class-pattern_ | pattern for the class name | | `[c:]` | hashcode of the class loader that loads the class | | `[classLoaderClass:]` | The class name of the ClassLoader that executes the expression. | | `[E]` | turn on regex match while the default is wildcard match | ## Usage ### Decompile `java.lang.String` ```java $ jad java.lang.String ClassLoader: Location: /* * Decompiled with CFR. */ package java.lang; import java.io.ObjectStreamField; import java.io.Serializable; ... public final class String implements Serializable, Comparable, CharSequence { private final char[] value; private int hash; private static final long serialVersionUID = -6849794470754667710L; private static final ObjectStreamField[] serialPersistentFields = new ObjectStreamField[0]; public static final Comparator CASE_INSENSITIVE_ORDER = new CaseInsensitiveComparator(); ... public String(byte[] byArray, int n, int n2, Charset charset) { /*460*/ if (charset == null) { throw new NullPointerException("charset"); } /*462*/ String.checkBounds(byArray, n, n2); /*463*/ this.value = StringCoding.decode(charset, byArray, n, n2); } ... ``` ### Print source only By default, the decompile result will have the `ClassLoader` information. With the `--source-only` option, you can print only the source code. Conveniently used with the [mc](mc.md)/[retransform](retransform.md) commands. ```java $ jad --source-only demo.MathGame /* * Decompiled with CFR 0_132. */ package demo; import java.io.PrintStream; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Random; import java.util.concurrent.TimeUnit; public class MathGame { private static Random random = new Random(); public int illegalArgumentCount = 0; ... ``` ### Decompile the specified method ```java $ jad demo.MathGame main ClassLoader: +-sun.misc.Launcher$AppClassLoader@232204a1 +-sun.misc.Launcher$ExtClassLoader@7f31245a Location: /private/tmp/math-game.jar public static void main(String[] args) throws InterruptedException { MathGame game = new MathGame(); while (true) { /*16*/ game.run(); /*17*/ TimeUnit.SECONDS.sleep(1L); } } ``` ### Do not print line numbers - `--lineNumber`: Output source code contins line numbers, default value true ```java $ jad demo.MathGame main --lineNumber false ClassLoader: +-sun.misc.Launcher$AppClassLoader@232204a1 +-sun.misc.Launcher$ExtClassLoader@7f31245a Location: /private/tmp/math-game.jar public static void main(String[] args) throws InterruptedException { MathGame game = new MathGame(); while (true) { game.run(); TimeUnit.SECONDS.sleep(1L); } } ``` ### Decompile with specified classLoader ::: tip If the target class is loaded by multiple classloaders, `jad` outputs the `hashcode` of the corresponding classloaders, then you can re-run `jad` and specify `-c ` to decompile the target class from the specified classloader. ::: ```java $ jad org.apache.log4j.Logger Found more than one class for: org.apache.log4j.Logger, Please use jad -c hashcode org.apache.log4j.Logger HASHCODE CLASSLOADER 69dcaba4 +-monitor's ModuleClassLoader 6e51ad67 +-java.net.URLClassLoader@6e51ad67 +-sun.misc.Launcher$AppClassLoader@6951a712 +-sun.misc.Launcher$ExtClassLoader@6fafc4c2 2bdd9114 +-pandora-qos-service's ModuleClassLoader 4c0df5f8 +-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. ``` For classloader with only one instance, it can be specified by `--classLoaderClass` using class name, which is more convenient to use. The value of `--classloaderclass` is the class name of classloader. It can only work when it matches a unique classloader instance. The purpose is to facilitate the input of general commands. However, `-c ` is dynamic. ### Decompile with specified directory for dumpping class Decompile class with `jad` need to dump corresponding classes into files. The default directory for dumpping classes is the directory of log file specified in logback.xml, we can use `-d/--directory` to specify the directory for dummping class. ```java $ jad demo.MathGame -d /tmp/jad/dump ```