Disassembling and Decompiling
Viewing bytecode with javap
Section titled “Viewing bytecode with javap”If you want to see the generated bytecode for a Java program, you can use the provided javap command to view it.
Assuming that we have the following Java source file:
package com.stackoverflow.documentation;
import org.springframework.stereotype.Service;
import java.io.IOException;import java.io.InputStream;import java.util.List;
@Servicepublic class HelloWorldService {
public void sayHello() { System.out.println("Hello, World!"); }
private Object[] pvtMethod(List<String> strings) { return new Object[]{strings}; }
protected String tryCatchResources(String filename) throws IOException { try (InputStream inputStream = getClass().getResourceAsStream(filename)) { byte[] bytes = new byte[8192]; int read = inputStream.read(bytes); return new String(bytes, 0, read); } catch (IOException | RuntimeException e) { e.printStackTrace(); throw e; } }
void stuff() { System.out.println("stuff"); }}After compiling the source file, the most simple usage is:
cd <directory containing classes> (e.g. target/classes)javap com/stackoverflow/documentation/SpringExampleWhich produces the output
Compiled from "HelloWorldService.java"public class com.stackoverflow.documentation.HelloWorldService { public com.stackoverflow.documentation.HelloWorldService(); public void sayHello(); protected java.lang.String tryCatchResources(java.lang.String) throws java.io.IOException; void stuff();}This lists all non-private methods in the class, but that is not particularly useful for most purposes. The following command is a lot more useful:
javap -p -c -s -constants -l -v com/stackoverflow/documentation/HelloWorldServiceWhich produces the output:
Classfile /Users/pivotal/IdeaProjects/stackoverflow-spring-docs/target/classes/com/stackoverflow/documentation/HelloWorldService.class Last modified Jul 22, 2016; size 2167 bytes MD5 checksum 6e33b5c292ead21701906353b7f06330 Compiled from "HelloWorldService.java"public class com.stackoverflow.documentation.HelloWorldService minor version: 0 major version: 51 flags: ACC_PUBLIC, ACC_SUPERConstant pool: #1 = Methodref #5.#60 // java/lang/Object."<init>":()V #2 = Fieldref #61.#62 // java/lang/System.out:Ljava/io/PrintStream; #3 = String #63 // Hello, World! #4 = Methodref #64.#65 // java/io/PrintStream.println:(Ljava/lang/String;)V #5 = Class #66 // java/lang/Object #6 = Methodref #5.#67 // java/lang/Object.getClass:()Ljava/lang/Class; #7 = Methodref #68.#69 // java/lang/Class.getResourceAsStream:(Ljava/lang/String;)Ljava/io/InputStream; #8 = Methodref #70.#71 // java/io/InputStream.read:([B)I #9 = Class #72 // java/lang/String #10 = Methodref #9.#73 // java/lang/String."<init>":([BII)V #11 = Methodref #70.#74 // java/io/InputStream.close:()V #12 = Class #75 // java/lang/Throwable #13 = Methodref #12.#76 // java/lang/Throwable.addSuppressed:(Ljava/lang/Throwable;)V #14 = Class #77 // java/io/IOException #15 = Class #78 // java/lang/RuntimeException #16 = Methodref #79.#80 // java/lang/Exception.printStackTrace:()V #17 = String #55 // stuff #18 = Class #81 // com/stackoverflow/documentation/HelloWorldService #19 = Utf8 <init> #20 = Utf8 ()V #21 = Utf8 Code #22 = Utf8 LineNumberTable #23 = Utf8 LocalVariableTable #24 = Utf8 this #25 = Utf8 Lcom/stackoverflow/documentation/HelloWorldService; #26 = Utf8 sayHello #27 = Utf8 pvtMethod #28 = Utf8 (Ljava/util/List;)[Ljava/lang/Object; #29 = Utf8 strings #30 = Utf8 Ljava/util/List; #31 = Utf8 LocalVariableTypeTable #32 = Utf8 Ljava/util/List<Ljava/lang/String;>; #33 = Utf8 Signature #34 = Utf8 (Ljava/util/List<Ljava/lang/String;>;)[Ljava/lang/Object; #35 = Utf8 tryCatchResources #36 = Utf8 (Ljava/lang/String;)Ljava/lang/String; #37 = Utf8 bytes #38 = Utf8 [B #39 = Utf8 read #40 = Utf8 I #41 = Utf8 inputStream #42 = Utf8 Ljava/io/InputStream; #43 = Utf8 e #44 = Utf8 Ljava/lang/Exception; #45 = Utf8 filename #46 = Utf8 Ljava/lang/String; #47 = Utf8 StackMapTable #48 = Class #81 // com/stackoverflow/documentation/HelloWorldService #49 = Class #72 // java/lang/String #50 = Class #82 // java/io/InputStream #51 = Class #75 // java/lang/Throwable #52 = Class #38 // "[B" #53 = Class #83 // java/lang/Exception #54 = Utf8 Exceptions #55 = Utf8 stuff #56 = Utf8 SourceFile #57 = Utf8 HelloWorldService.java #58 = Utf8 RuntimeVisibleAnnotations #59 = Utf8 Lorg/springframework/stereotype/Service; #60 = NameAndType #19:#20 // "<init>":()V #61 = Class #84 // java/lang/System #62 = NameAndType #85:#86 // out:Ljava/io/PrintStream; #63 = Utf8 Hello, World! #64 = Class #87 // java/io/PrintStream #65 = NameAndType #88:#89 // println:(Ljava/lang/String;)V #66 = Utf8 java/lang/Object #67 = NameAndType #90:#91 // getClass:()Ljava/lang/Class; #68 = Class #92 // java/lang/Class #69 = NameAndType #93:#94 // getResourceAsStream:(Ljava/lang/String;)Ljava/io/InputStream; #70 = Class #82 // java/io/InputStream #71 = NameAndType #39:#95 // read:([B)I #72 = Utf8 java/lang/String #73 = NameAndType #19:#96 // "<init>":([BII)V #74 = NameAndType #97:#20 // close:()V #75 = Utf8 java/lang/Throwable #76 = NameAndType #98:#99 // addSuppressed:(Ljava/lang/Throwable;)V #77 = Utf8 java/io/IOException #78 = Utf8 java/lang/RuntimeException #79 = Class #83 // java/lang/Exception #80 = NameAndType #100:#20 // printStackTrace:()V #81 = Utf8 com/stackoverflow/documentation/HelloWorldService #82 = Utf8 java/io/InputStream #83 = Utf8 java/lang/Exception #84 = Utf8 java/lang/System #85 = Utf8 out #86 = Utf8 Ljava/io/PrintStream; #87 = Utf8 java/io/PrintStream #88 = Utf8 println #89 = Utf8 (Ljava/lang/String;)V #90 = Utf8 getClass #91 = Utf8 ()Ljava/lang/Class; #92 = Utf8 java/lang/Class #93 = Utf8 getResourceAsStream #94 = Utf8 (Ljava/lang/String;)Ljava/io/InputStream; #95 = Utf8 ([B)I #96 = Utf8 ([BII)V #97 = Utf8 close #98 = Utf8 addSuppressed #99 = Utf8 (Ljava/lang/Throwable;)V #100 = Utf8 printStackTrace{ public com.stackoverflow.documentation.HelloWorldService(); descriptor: ()V flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 10: 0 LocalVariableTable: Start Length Slot Name Signature 0 5 0 this Lcom/stackoverflow/documentation/HelloWorldService;
public void sayHello(); descriptor: ()V flags: ACC_PUBLIC Code: stack=2, locals=1, args_size=1 0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #3 // String Hello, World! 5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 8: return LineNumberTable: line 13: 0 line 14: 8 LocalVariableTable: Start Length Slot Name Signature 0 9 0 this Lcom/stackoverflow/documentation/HelloWorldService;
private java.lang.Object[] pvtMethod(java.util.List<java.lang.String>); descriptor: (Ljava/util/List;)[Ljava/lang/Object; flags: ACC_PRIVATE Code: stack=4, locals=2, args_size=2 0: iconst_1 1: anewarray #5 // class java/lang/Object 4: dup 5: iconst_0 6: aload_1 7: aastore 8: areturn LineNumberTable: line 17: 0 LocalVariableTable: Start Length Slot Name Signature 0 9 0 this Lcom/stackoverflow/documentation/HelloWorldService; 0 9 1 strings Ljava/util/List; LocalVariableTypeTable: Start Length Slot Name Signature 0 9 1 strings Ljava/util/List<Ljava/lang/String;>; Signature: #34 // (Ljava/util/List<Ljava/lang/String;>;)[Ljava/lang/Object;
protected java.lang.String tryCatchResources(java.lang.String) throws java.io.IOException; descriptor: (Ljava/lang/String;)Ljava/lang/String; flags: ACC_PROTECTED Code: stack=5, locals=10, args_size=2 0: aload_0 1: invokevirtual #6 // Method java/lang/Object.getClass:()Ljava/lang/Class; 4: aload_1 5: invokevirtual #7 // Method java/lang/Class.getResourceAsStream:(Ljava/lang/String;)Ljava/io/InputStream; 8: astore_2 9: aconst_null 10: astore_3 11: sipush 8192 14: newarray byte 16: astore 4 18: aload_2 19: aload 4 21: invokevirtual #8 // Method java/io/InputStream.read:([B)I 24: istore 5 26: new #9 // class java/lang/String 29: dup 30: aload 4 32: iconst_0 33: iload 5 35: invokespecial #10 // Method java/lang/String."<init>":([BII)V 38: astore 6 40: aload_2 41: ifnull 70 44: aload_3 45: ifnull 66 48: aload_2 49: invokevirtual #11 // Method java/io/InputStream.close:()V 52: goto 70 55: astore 7 57: aload_3 58: aload 7 60: invokevirtual #13 // Method java/lang/Throwable.addSuppressed:(Ljava/lang/Throwable;)V 63: goto 70 66: aload_2 67: invokevirtual #11 // Method java/io/InputStream.close:()V 70: aload 6 72: areturn 73: astore 4 75: aload 4 77: astore_3 78: aload 4 80: athrow 81: astore 8 83: aload_2 84: ifnull 113 87: aload_3 88: ifnull 109 91: aload_2 92: invokevirtual #11 // Method java/io/InputStream.close:()V 95: goto 113 98: astore 9 100: aload_3 101: aload 9 103: invokevirtual #13 // Method java/lang/Throwable.addSuppressed:(Ljava/lang/Throwable;)V 106: goto 113 109: aload_2 110: invokevirtual #11 // Method java/io/InputStream.close:()V 113: aload 8 115: athrow 116: astore_2 117: aload_2 118: invokevirtual #16 // Method java/lang/Exception.printStackTrace:()V 121: aload_2 122: athrow Exception table: from to target type 48 52 55 Class java/lang/Throwable 11 40 73 Class java/lang/Throwable 11 40 81 any 91 95 98 Class java/lang/Throwable 73 83 81 any 0 70 116 Class java/io/IOException 0 70 116 Class java/lang/RuntimeException 73 116 116 Class java/io/IOException 73 116 116 Class java/lang/RuntimeException LineNumberTable: line 21: 0 line 22: 11 line 23: 18 line 24: 26 line 25: 40 line 21: 73 line 25: 81 line 26: 117 line 27: 121 LocalVariableTable: Start Length Slot Name Signature 18 55 4 bytes [B 26 47 5 read I 9 107 2 inputStream Ljava/io/InputStream; 117 6 2 e Ljava/lang/Exception; 0 123 0 this Lcom/stackoverflow/documentation/HelloWorldService; 0 123 1 filename Ljava/lang/String; StackMapTable: number_of_entries = 9 frame_type = 255 /* full_frame */ offset_delta = 55 locals = [ class com/stackoverflow/documentation/HelloWorldService, class java/lang/String, class java/io/InputStream, class java/lang/Throwable, class "[B", int, class java/lang/String ] stack = [ class java/lang/Throwable ] frame_type = 10 /* same */ frame_type = 3 /* same */ frame_type = 255 /* full_frame */ offset_delta = 2 locals = [ class com/stackoverflow/documentation/HelloWorldService, class java/lang/String, class java/io/InputStream, class java/lang/Throwable ] stack = [ class java/lang/Throwable ] frame_type = 71 /* same_locals_1_stack_item */ stack = [ class java/lang/Throwable ] frame_type = 255 /* full_frame */ offset_delta = 16 locals = [ class com/stackoverflow/documentation/HelloWorldService, class java/lang/String, class java/io/InputStream, class java/lang/Throwable, top, top, top, top, class java/lang/Throwable ] stack = [ class java/lang/Throwable ] frame_type = 10 /* same */ frame_type = 3 /* same */ frame_type = 255 /* full_frame */ offset_delta = 2 locals = [ class com/stackoverflow/documentation/HelloWorldService, class java/lang/String ] stack = [ class java/lang/Exception ] Exceptions: throws java.io.IOException
void stuff(); descriptor: ()V flags: Code: stack=2, locals=1, args_size=1 0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #17 // String stuff 5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 8: return LineNumberTable: line 32: 0 line 33: 8 LocalVariableTable: Start Length Slot Name Signature 0 9 0 this Lcom/stackoverflow/documentation/HelloWorldService;}SourceFile: "HelloWorldService.java"RuntimeVisibleAnnotations: 0: #59()Syntax
Section titled “Syntax”- javap [options]
Parameters
Section titled “Parameters”|Name|Description
|---|---|---|---|---|---|---|---|---|---
|<classes>|List of classes to disassemble. Can be in either package1.package2.Classname format, or package1/package2/Classname format. Do not include the .class extension.
|-help, --help, -?|Print this usage message
|-version|Version information
|-v, -verbose|Print additional information
|-l|Print line number and local variable tables
|-public|Show only public classes and members
|-protected|Show protected/public classes and members
|-package|Show package/protected/public classes and members (default)
|-p, -private|Show all classes and members
|-c|Disassemble the code
|-s|Print internal type signatures
|-sysinfo|Show system info (path, size, date, MD5 hash) of class being processed
|-constants|Show final constants
|-classpath <path>|Specify where to find user class files
|-cp <path>|Specify where to find user class files
|-bootclasspath <path>|Override location of bootstrap class files