Search code examples
javacompilationdependencies.class-file

Where are dependencies stored in a compiled Java class?


In which section of a compiled class are dependencies to other classes (the imports) stored and can they be viewed (with an editor or something not programatically) ?

Thanks,


Solution

  • This is stored in the "constant pool" of the class (along with everything else, classes and method names, etc).

    You would use javap to look at the bytecode in a readable format.

    See Anton Arhipov's excellent blog on bytecode fundamentals

    An example taken from there for class:

    public class Foo {
        private String bar;
    
        public String getBar(){ 
          return bar; 
        }
        ...
    

    ... yields bytecode:

    public java.lang.String getBar();
      Code:
       0:   aload_0
       1:   getfield        #2; //Field bar:Ljava/lang/String;
       4:   areturn
    

    And has constant pool:

    Compiled from "Foo.java"
    public class Foo extends java.lang.Object
      SourceFile: "Foo.java"
      minor version: 0
      major version: 50
      Constant pool:
    const #1 = Method       #4.#17; //  java/lang/Object."<init>":()V
    const #2 = Field        #3.#18; //  Foo.bar:Ljava/lang/String;
    const #3 = class        #19;    //  Foo
    const #4 = class        #20;    //  java/lang/Object
    const #5 = Asciz        bar;
    const #6 = Asciz        Ljava/lang/String;;
    const #7 = Asciz        <init>
    const #8 = Asciz        ()V;
    const #9 = Asciz        Code;
    const #10 = Asciz       LineNumberTable;
    const #11 = Asciz       getBar;
    const #12 = Asciz       ()Ljava/lang/String;;
    const #13 = Asciz       setBar;
    const #14 = Asciz       (Ljava/lang/String;)V;
    const #15 = Asciz       SourceFile;
    const #16 = Asciz       Foo.java;
    const #17 = NameAndType #7:#8;//  "<init>":()V
    const #18 = NameAndType #5:#6;//  bar:Ljava/lang/String;
    const #19 = Asciz       Foo;
    const #20 = Asciz       java/lang/Object;
    

    You can trace the reference to String from Foo#getBar through the constant pool as:

    • getfield #2
    • where #2 is a Field, referencing #3.#18
      • where #3 is referencing Class #19
        • which is class Foo
      • and #18 is a NameAndType referencing #5 and #6
        • and #5 is bar (field)
        • and #6 is the reference to java.lang.String

    I strongly advise reading Anton's blog. It's really well done!

    I'd also read James D. Bloom's JVM Internals article as it covers a lot of JVM internal architecture. Be aware of dates and versions referenced though as things change (such as the use of the java heap in java 8 and String inlining.