Version

Date

Description

Author

2.1

4 August 2006

ccode file format description

A. Esin

 

 

 

 

Ccode file format

The structure of the document

Ccode file format 1

The structure of the document 1

The ccode-file format 2

Header 2

Class name. 2

Magic. 2

Minor and major version. 2

Constant pool 2

Constant pool count 2

Constant pool table. 2

Access rights. 5

Access flags. 5

This class. 5

Super class. 5

Implemented interfaces. 5

Interfaces count 5

Interfaces table. 5

Fields. 6

Fields count 6

Fields table. 6

Methods. 9

Methods count 9

Methods table. 9

Class Attributes. 14

Attributes count 14

Attributes table. 14

Attributes. 15

Constant value attribute. 15

Code attribute. 15

Exceptions attribute. 17

Inner classes attribute. 17

Synthetic attribute. 19

Enclosing method attribute. 19

Signature attribute. 19

Source file attribute. 20

Line number table attribute. 20

Local variable table attribute. 21

Local variable type table attribute. 21

Deprecated attribute. 22

SourceDebugExtension attribute. 22

RuntimeVisibleAnnotations attribute. 22

RuntimeInvisibleAnnotations attribute. 27

RuntimeVisibleParameterAnnotations attribute. 27

RuntimeInvisibleParameterAnnotations attribute. 28

AnnotationDefault attribute. 28

Custom attribute. 28

Comments. 28

Detailed information about class file format 28

The ccode-file format

The ccode file contains ordered and readable information of a class file. Ccode file is split into logic parts according to the description of the class file format in Java Virtual Machine Specification Second Edition. Ccode file contains a header, constant pool, access rights, implemented interfaces, fields, methods, and class attributes in readable form.

Header

Class name

Header can contain the class_name string. The main purpose of this item is to specify real name of class which is used as a name of generated class file if “this_class” index is bad (if it refers to a wrong place in the constant pool). Thus, the class_name item can be simply omitted if everything is ok with “this_class” index. Also, if class_name is specified it is used as a name of generated class file instead of reference of “this_class” index regardless it is correct.

class_name= “org/openintel/test/Test”

Magic

Header contains the magic number that identifies the class file format. The valid value is 0xCAFEBABE.

magic = 0xCAFEBABE

Minor and major version

Also, the header contains minor and major version numbers of the class file. A minor version together with a major version set the version of the class file format.

minor_version = 0

major_version = 46

Constant pool

Constant pool count

Constant pool count number is equal to the number of items in the constant pool table + 1.

constant_pool_count = 47

Constant pool table

This is a table of various string constants, class and interface names, field and method names, and other constants. The constant pool table is indexed from 1 to constant pool count – 1. The numbers that starts with # is a references to the constant pool. For example, the 8th item of the constant pool  has type Class, and its’ value is #41, this is a references to the 41 item of the constant pool. The value of the 41 item is “Test”. There are seven types of the constants:

·         Class, used to represent a class or an interface; (Class #ref);

·         Reference, used to represent fields, methods, and interface methods; (Method #ref, Field #ref, InterfaceMethod #ref);

·         String, used to represent constant objects of the String type; (String #ref);

·         Num32, used to represent 32-bit numeric constants (int, float); (int 10, float 3,1415f);

·         Num64, used to represent 64-bit numeric constants (long, double); (long 123456789l, double 124543,1415926535d);

·         NameAndType, used to represent a field or a method; (NameAndType #ref #ref);

·         Utf8, used to represent constant string values; (Utf8 “String”);

constant_pool {

  #1 = Method  #9 #33  //  java/lang/Object."<init>":()V

  #2 = Field   #8 #34  //  Test.field_pri:I

  #3 = Field   #35 #36 //  java/lang/Byte.TYPE:Ljava/lang/Class;

  #4 = Field   #8 #37  //  Test.clazz:Ljava/lang/Object;

  #5 = Class   #38     //  java/lang/Throwable

  #6 = Method  #5 #39  //  java/lang/Throwable.printStackTrace:()V

  #7 = Field   #8 #40  //  Test.field_pri_stat:I

  #8 = Class   #41     //  Test

  #9 = Class   #42     //  java/lang/Object

  #10 = class  #43     //  java/lang/Runnable

  #11 = UTF-8  "field_pub_stat_final"

  #12 = UTF-8  "I"

  #13 = UTF-8  "ConstantValue"

  #14 = int    0xa // 10

  #15 = UTF-8  "field_pri_stat_final"

  #16 = int    0xb // 11

  #17 = UTF-8  "field_pri_stat"

  #18 = UTF-8  "field_pro_stat"

  #19 = UTF-8  "field_pub"

  #20 = UTF-8  "field_pri"

  #21 = UTF-8  "clazz"

  #22 = UTF-8  "Ljava/lang/Object;"

  #23 = UTF-8  "<init>"

  #24 = UTF-8  "()V"

  #25 = UTF-8  "Code"

  #26 = UTF-8  "LineNumberTable"

  #27 = UTF-8  "run"

  #28 = UTF-8  "getPriSta"

  #29 = UTF-8  "()I"

  #30 = UTF-8  "getPri"

  #31 = UTF-8  "SourceFile"

  #32 = UTF-8  "Test.java"

  #33 = NameAndType  #23 #24 //  "<init>":()V

  #34 = NameAndType  #20 #12 //  field_pri:I

  #35 = Class  #44  //  java/lang/Byte

  #36 = NameAndType  #45 #46 //  TYPE:Ljava/lang/Class;

  #37 = NameAndType  #21 #22 //  clazz:Ljava/lang/Object;

  #38 = UTF-8  "java/lang/Throwable"

  #39 = NameAndType  #47 #24 //  printStackTrace:()V

  #40 = NameAndType  #17 #12 //  field_pri_stat:I

  #41 = UTF-8  "Test"

  #42 = UTF-8  "java/lang/Object"

  #43 = UTF-8  "java/lang/Runnable"

  #44 = UTF-8  "java/lang/Byte"

  #45 = UTF-8  "TYPE"

  #46 = UTF-8  "Ljava/lang/Class;"

  #47 = UTF-8  "printStackTrace"

}

If user wants to include record of unknown format to the constant pool then he/she should use next structure {<hex code>}. For example:

constant_pool {

  #1 = Method  #9 #33  //  java/lang/Object."<init>":()V

  #2 = Field   #8 #34  //  Test.field_pri:I

  {x01 xA4 xCC xCB xF3 x67 xFA}

}

VMTT will put the structure {<hex code>} into the class file “as is”.

Access rights

Access flags

This element is a mask of flags used to set access permissions and properties of this class or interface.

Flag

Value

PUBLIC

0x0001

FINAL

0x0010

SUPER

0x0020

INTERFACE

0x0200

ABSTRACT

0x0400

SYNTHETIC

0x1000

ANNOTATION

0x2000

ENUM

0x4000

access_flags = PUBLIC FINAL SUPER

This class

This element contains a references to the constant pool item. In a valid class file the specified constant pool item should have a Class type. The item represents the class or interface defined by this class file.

this_class = #8         // Test

Super class

This item of the class file contains a reference to the constant pool item or zero. In valid class file the specified constant pool item should have a Class type. The item represents the class extended by this class.

super_class = #9        // java/lang/Object

Implemented interfaces

Interfaces count

This item contains a number of direct superinterfaces of this class or interface.

interfaces_count = 1

Interfaces table

This is a table of references to the constant pool table. The type of constant pool entry should have a Class type. Each of entries represents an interface that is a direct superinterface of this class or interface.

interfaces {

  #10       // "java/lang/Runnable"

}

Fields

Fields count

This element of the class file contains a number of fields, declared by this class or interface.

fields_count = 7

Fields table

This is a table of fields, declared by this class. Each field contains:

·         access_flag item used to set access permissions and properties of this field;

 

Flag

Value

PUBLIC

0x0001

PRIVATE

0x0002

PROTECTED

0x0004

STATIC

0x0008

FINAL

0x0010

VOLATILE

0x0040

TRANSIENT

0x0080

SYNTHETIC

0x1000

ENUM

0x4000

 

·         name_index it’s reference to the constant pool item, that represents a name of this field;

·         descriptor_index it’s a references to the constant pool item, that represents a field descriptor;

·         attributes_count – the number of attributes;

·         attributes – the table of attributes. The types of attributes may be the following: constant value attribute, synthetic attribute, and deprecated attribute (for more details see Attributes section);

fields {

  field {

    access_flag = PUBLIC STATIC FINAL

    name_index = #11 // "field_pub_stat_final"

    descriptor_index = #12 // "I"

    attributes_count = 1

      attribute {

        attribute_name_index = #13 // "ConstantValue"

        attribute_length = 2

        constantvalue_index = #14 // 0xa

      }

  }

  field {

    access_flag = PRIVATE STATIC FINAL

    name_index = #15 // "field_pri_stat_final"

    descriptor_index = #12 //"I"

    attributes_count = 1

      attribute {

        attribute_name_index = #13 // "ConstantValue"

        attribute_length = 2

        constantvalue_index = #16 // 0xb

      }

  }

  field {

    access_flag = PRIVATE STATIC

    name_index = #17 // "field_pri_sta"

    descriptor_index = #12 // "I"

    attributes_count = 0

  }

  field {

    access_flag = PROTECTED STATIC

    name_index = #18 // field_pro_stat

    descriptor_index = #12 // "I"

    attributes_count = 0

  }

  field {

    access_flag = PUBLIC

    name_index = #19 // "field_pub"

    descriptor_index = #12 // "I"

    attributes_count = 0

  }

  field {

    access_flag = PRIVATE

    name_index = #20 // "field_pri"

    descriptor_index = #12 // "I"

    attributes_count = 0

  }

  field {

    access_flag = PRIVATE

    name_index = #21 // "clazz"

    descriptor_index = #22 // "Ljava/lang/Object;"

    attributes_count = 0

  }

}


Methods

Methods count

The number of methods in the table of methods.

methods_count = 4

Methods table

This is a table of methods which are declared in this class. Each method contains:

·         access_flag item used to set access permissions and properties of this method;

 

Flag

Value

PUBLIC

0x0001

PRIVATE

0x0002

PROTECTED

0x0004

STATIC

0x0008

FINAL

0x0010

SYNCHRONIZED

0x0020

BRIDGE

0x0040

VARARGS

0x0080

NATIVE

0x0100

ABSTRACT

0x0400

STRICT

0x0800

SYNTHETIC

0x1000

 

·         name_index it’s reference to the constant pool item, that represents a name of this method;

·         descriptor_index it’s a references to the constant pool item, that represents a method descriptor;

·         attributes_count – the number of attributes;

·         attributes – the table of attributes. The types of attributes may be the following: code attribute, exceptions attribute, synthetic attribute, and deprecated attribute  (for more details see Attributes section);

 

The table of attributes of the method contains code attributes that contains the Java VM instructions. Ccode file format has two types of refining:

1.      Binary code type;

2.      Instructions code type;

 

The 1st type of refining represents a code attribute as binary (for example 2A B7 00 01 2A 04), the 2nd type represents a code attribute as instructions (see example of methods table).

methods {

  method {

    access_flag = 0x00  // custom value (no flags are set)

    name_index = #23 // "<init>"

    descriptor_index = #24 // "()V"

    attributes_count = 1

      attribute {

        attribute_name_index = #25 // "Code"

        attribute_length = 81

        max_stack = 2

        max_locals = 2

        code_length = 25

        code asm {

          0:      aload_0

          1:      invokespecial     #1; //Method java/lang/Object."<init>":()V

          4:      aload_0

          5:      iconst_1

          6:      putfield    #2; //Field field_pri:I

          9:      aload_0

          10:     getstatic   #3; //Field java/lang/Byte.TYPE:Ljava/lang/Class;

          13:     putfield    #4; //Field clazz:Ljava/lang/Object;

          16:     goto  24

          19:     astore_1

          20:     aload_1

          21:     invokevirtual#6//Method java/lang/Throwable.printStackTrace:()V

          24:     return

        }

        exception_table_length = 1

        exception_table {

        // from   to    target      type

           4      16    19    #5    // java/lang/Throwable

        }

        attributes_count = 1

          attribute {

            attribute_name_index = #26 // "LineNumberTable"

            attribute_length = 30

            line_number_table_length = 7

            line_number_table {

            // start_pc line_number

               0  10

               4  12

               9  13

               16 16

               19 14

               20 15

               24 17

            }

          }

      }

  }

 

  method {

    access_flag = ACC_PUBLIC

    name_index = #27 // "run"

    descriptor_index = #24 // "()V"

    attributes_count = 1

      attribute {

        attribute_name_index = #25 // "Code"

        attribute_length = 25

        max_stack = 0

        max_locals = 1

        code_length = 1

        code asm {

          0:      return

        }

        exception_table_length = 0

        attributes_count = 1

          attribute {

            attribute_name_index = #26 // "LineNumberTable"

            attribute_length = 6

            line_number_table_length = 1

            line_number_table {

            // start_pc line_number

               0  20

            }

          }

      }

  }

 

  method {

    access_flag = ACC_PUBLIC | ACC_STATIC

    name_index = #28 // "getPriSta"

    descriptor_index = #29 // "()I"

    attributes_count = 1

      attribute {

        attribute_name_index = #25 // "Code"

        attribute_length = 28

        max_stack = 1

        max_locals = 0

        code_length = 4

        code asm {

          0:      getstatic   #7; //Field field_pri_stat:I

          3:      ireturn

        }

        exception_table_length = 0

        attributes_count = 1

          attribute {

            attribute_name_index = #26 // "LineNumberTable"

            attribute_length = 6

            line_number_table_length = 1

            line_number_table {

            // start_pc line_number

               0  23

            }

          }

      }

  }

 

  method {

    access_flag = ACC_PUBLIC

    name_index = #30 // "getPri"

    descriptor_index = #29 "()I"

    attributes_count = 1

      attribute {

        attribute_name_index = #25 // "Code"

        attribute_length = 29

        max_stack = 1

        max_locals = 1

        code_length = 5

        code asm {

          0:      aload_0

          1:      getfield    #2; //Field field_pri:I

          4:      ireturn

        }

        exception_table_length = 0

        attributes_count = 1

          attribute0 {

            attribute_name_index = #26 // "LineNumberTable"

            attribute_length = 6

            line_number_table_length = 1

            line_number_table {

            // start_pc line_number

               0        27

            }

          }

      }

  }

}

Class Attributes

Attributes count

This field of class file contains a number of the attributes in the attributes table.

Attributes table

This attributes table contains attributes of class, or interface. The types of attributes may be the following: source file attribute, deprecated attribute, inner classes attribute, synthetic attribute. For more details see Attributes section.

attributes_count = 1

attribute SourceFile {

  attribute_name_index = #31 // “SourceFile”

  attribute_length = 2

  sourcefile_index = #32     // “Test.java”

}

Attributes

The field, method, and class can have attributes. There are eighteen types of attributes (it means if VM supports major version of class file 49.0 or greater it should recognize such attributes).

Constant value attribute

This attribute is used in fields. It represents constant values and looks like:

attribute ConstantValue {

  attribute_name_index = #13 // “ConstantValue”

  attribute_length = 2

  constantvalue_index = #14  // 0xA

}

Code attribute

The code attribute is used in methods. It contains the JVM instructions.

attribute Code {

  attribute_name_index = #25 // "Code"

  attribute_length = 29

  max_stack = 1

  max_locals = 1

  code_length = 5

  code asm {

     0:     aload_0

     1:     getfield    #2; //Field field_pri:I

     4:     ireturn

  }

  exception_table_length = 0

  attributes_count = 1

  attribute {

    attribute_name_index = #26 // "LineNumberTable"

    attribute_length = 6

    line_number_table_length = 1

    line_number_table {

    // start_pc   line_number

       0          27

    }

  }

}

For more information about code attribute format see Detailed information about class file format.


Exceptions attribute

This attribute is used in methods. It represents exceptions which method may throw.

attribute Exceptions {

  attribute_name_index = # 67 // “Exceptions”

  attribute_length = 10

  number_of_exceptions = 1

  exception_index_table {

    #87     // “java/io/IOException”

  }

}

Inner classes attribute

This attribute is used in classes. It represents inner classes of class.

attribute InnerClasses {

  attribute_name_index = #109 // “InnerClasses”

  attribute_length = 10

  number_of_classes = 1

  classes {

    inner_class_info_index = #291

    outer_class_info_index = #193

    inner_name_index = #189

    inner_class_access_flags = PUBLIC

  }

}


Synthetic attribute

This attribute is used in classes, fields, and methods.

attribute Synthetic {

  attribute_name_index = #340 // “Synthetic”

  attribute_length = 0

}

Enclosing method attribute

The enclosing method attribute is used in class, if this class is a local class or an anonymous class.

attribute EnclosingMethod {

  attribute_name_index = #15  // "EnclosingMethod"

  attribute_length = 4

  class_index = #16  // "EnclosingMethodTest"

  method_index = #17  // "testMethod" "()V"

}

Signature attribute

The signature attribute is used in classes, fields and methods.

attribute Signature {

  attribute_name_index = #8  // "Signature"

  attribute_length = 2

  signature_index = #6  // "<T:Ljava/lang/Object;>Ljava/lang/Object;"

}

Source file attribute

The source file attribute is used in classes.

attribute SourceFile {

  attribute_name_index = #31 // “SourceFile”

  attribute_length = 2

  sourcefile_index = #32 // “Test.java”

}

Line number table attribute

This attribute is used in methods in the Code attribute. It may be used by debugger. It has the following format:

attribute LineNumberTable {

  attribute_name_index = #26 // "LineNumberTable"

  attribute_length = 6

  line_number_table_length = 1

  line_number_table {

  // start_pc     line_number

     0      23

}


Local variable table attribute

This attribute is used in methods in the Code attribute. It may be used by debugger.

attribute LocalVariableTable {

  attribute_name_index = #243 // "LocalVariableTable"

  attribute_length = 12

  local_variable_table_length = 1

  local_variable_table {

  // start_pc length name_index descriptor_index index

     0 23 #244 #245 2

}

Local variable type table attribute

This attribute is used in methods in the Code attribute. It may be used by debugger.

attribute LocalVariableTypeTable {

  attribute_name_index = #243 // "LocalVariableTypeTable"

  attribute_length = 12

  local_variable_type_table_length = 1

  local_variable_type_table {

  // start_pc length name_index signature_index index

     0 23 #244 #250 2

}

Deprecated attribute

This attribute is used in classes, fields, and methods. A class, field, or method may be marked by this attribute to indicate that class, field, or method has been suppressed.

attribute Deprecated {

  attribute_name_index = #356 // “Deprecated”

  attribute_length = 0

}

SourceDebugExtension attribute

This attribute is used in classes. This attribute contains a data which can be interpreted as extended debugging information.

attribute SourceDebugExtension {

  attribute_name_index = #11  // "SourceDebugExtension"

  attribute_length = 9

  debug_extension {

    x62  x6C  x61  x68  x20  x62  x6C  x61  x68

  }

}

RuntimeVisibleAnnotations attribute

This attribute is used in classes, fields, and methods. In Java program these annotations can be obtained through Reflective API.

attribute RuntimeVisibleAnnotations {

    attribute_name_index = #9  // "RuntimeVisibleAnnotations"

    attribute_length = 30

    num_annotations = 2

    Annotation {

      type_index = #17  // "LTest;"

      num_element_value_pairs = 1

      {

        element_name_index = #12  // "value"

        tag = I

        const_value_index = #18  // 667

      }

    }

    Annotation {

      type_index = #19  // "LTest2;"

      num_element_value_pairs = 3

      {

        element_name_index = #12  // "value"

        tag = I

        const_value_index = #18  // 667

      }

      {

        element_name_index = #14  // "value2"

        tag = s

        const_value_index = #20  // "the second value"

      }

      {

        element_name_index = #21  // "value3"

        tag = s

        const_value_index = #22  // "the third value"

      }

    }

  }

 

If tag equals ‘e’ the value is of enumeration type. In this case type_name_index and const_name_index should be specified instead of const_value_index:

Annotation {

   type_index = #10  // "Ljava/lang/annotation/Retention;"

   num_element_value_pairs = 1

   {

     element_name_index = #4  // "value"

     tag = e

     type_name_index = #11  // "Ljava/lang/annotation/RetentionPolicy;"

     const_name_index = #12  // "RUNTIME"

   }

}

If tag equals ‘c’ the type of value is java.lang.Class. class_info_index should be specified instead of const_value_index.

Annotation {

   type_index = #18  // "LTest5;"

   num_element_value_pairs = 1

   {

     element_name_index = #4  // "value"

     tag = c

     class_info_index = #24  // "Ljava/lang/Object;"

   }

}

If tag equals ‘@’ the type of value is Annotation:

Annotation {

  type_index = #11  // "LTest4;"

  num_element_value_pairs = 1

  {

    element_name_index = #12  // "value"

    tag = @

    Annotation {

      type_index = #13  // "LTest2;"

      num_element_value_pairs = 1

      {

        element_name_index = #12  // "value"

         tag = I

        const_value_index = #14  // 44

      }

    }

}

If tag equals ‘[’ the type of value is an array of Annotations:

Annotation {

      type_index = #11  // "LTest6;"

      num_element_value_pairs = 1

      {

        element_name_index = #12  // "value"

        tag = [

        array_length = 2 {

          tag = @

          Annotation {

            type_index = #13  // "LTest2;"

            num_element_value_pairs = 1

            {

              element_name_index = #12  // "value"

              tag = I

              const_value_index = #14  // 1

            }

          }

          tag = @

          Annotation {

            type_index = #13  // "LTest2;"

            num_element_value_pairs = 1

            {

              element_name_index = #12  // "value"

              tag = I

              const_value_index = #15  // 44

            }

          }

        }

      }

    }

}

RuntimeInvisibleAnnotations attribute

This attribute is used in classes, fields, and methods. It is very similar to RuntimeVisibleAnnotations with the exception of an ability of Java programs to obtain these annotations through Reflective API. (See the paragraph RuntimeVisibleAnnotations attribute for details).

RuntimeVisibleParameterAnnotations attribute

This attribute is used in methods. The annotations of annotated parameters can be obtained in Java program through Reflective API.

attribute RuntimeVisibleParameterAnnotations {

  attribute_name_index = #10  // "RuntimeVisibleParameterAnnotations"

  attribute_length = 11

  num_parameters = 3

  {

  }

  {

    num_annotations = 2

    Annotation {

       type_index = #11  // "LTest;"

       num_element_value_pairs = 0

    }

    Annotation {

       type_index = #11  // "LTest;"

       num_element_value_pairs = 0

    }

  }

  {

    num_annotations = 0

  }

}

In this example RuntimeVisibleParameterAnnonations attribute is used in method which has 3 parameters and only second is annotated.

(See the paragraph RuntimeVisibleAnnotations attribute for information about other elements).

RuntimeInvisibleParameterAnnotations attribute

This attribute is used in methods. It is very similar to RuntimeVisibleParameterAnnotations with the exception of an ability of Java programs to obtain the annotations of annotated parameters through Reflective API. (See the paragraph RuntimeVisibleParameterAnnotations attribute for details).

AnnotationDefault attribute

This attribute is used in methods of classes which represent annotation types themselves. This attribute must contain only one element-value pair.

attribute AnnotationDefault {

   attribute_name_index = #6  // "AnnotationDefault"

   attribute_length = 3

   tag = s

   const_value_index = #9  // "the default value."

}

(See the paragraph RuntimeVisibleAnnotations attribute for information about attribute’s elements).

Custom attribute

User may set custom attributes for each attribute set. Format of this attribute is attribute{<hex code>}.

attribute {x34 xCA x10 x0A x0B xCC}

VMTT will put custom attribute into the class file “as is”.

Comments

The ccode file format allow to use end-of-line comments, all text from the // characters to the end of line is ignored (as in C++).

Detailed information about class file format

For more details about the class file format see Java Virtual Machine Specification Second Edition, Chapter 4 (http://java.sun.org/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html).