An Oak class file is a single structure, read from start to end. It has no padding and
no alignment, and every number in it is big-endian. Types are written u1,
u2 and u4 for unsigned numbers of one, two and four bytes. No
specification of this format survives; the layout here is the one HotSpot’s reader
applied to versions 45.0 to 45.2.
Fields
Only the first four fields have fixed offsets. The constant pool’s entries vary in size, so the rest must be found by reading through it.
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 0 | 4 | u4 | magic | CA FE BA BE |
| 4 | 2 | u2 | minor_version | 0, 1 or 2 |
| 6 | 2 | u2 | major_version | 45 |
| 8 | 2 | u2 | constant_pool_count | One more than the number of constant pool indexes; entries are numbered 1 to count − 1 |
| 10 | varies | cp_info[] | constant_pool | The constant pool |
| … | 2 | u2 | access_flags | The class’s access flags |
| … | 2 | u2 | this_class | Index of a Class entry: this class |
| … | 2 | u2 | super_class | Index of a Class entry: the direct superclass; 0 only for java/lang/Object |
| … | 2 | u2 | interfaces_count | The number of direct superinterfaces |
| … | 2 × n | u2[] | interfaces | Indexes of Class entries, one per direct superinterface |
| … | 2 | u2 | fields_count | The number of fields declared by this class |
| … | varies | field_info[] | fields | See fields and methods |
| … | 2 | u2 | methods_count | The number of methods, constructors and initialisers |
| … | varies | method_info[] | methods | See fields and methods |
| … | 2 | u2 | attributes_count | The number of class attributes |
| … | varies | attribute_info[] | attributes | The class’s attributes |
Nothing may follow the last attribute; the explorer shows any further bytes as “Extra bytes” and marks them.
magic
The first four bytes are always CA FE BA BE. A Mach-O universal binary
starts with the same four bytes; the family page
explains how to tell them apart.
minor_version and major_version
The major version is 45 and the minor version 0, 1 or 2. These are the versions before JDK 1.0.2. The explorer turns down any other version for this format, and shows the version as “before JDK 1.0.2”. Which pre-release compiler wrote which minor version is not recorded.
this_class
An index of a Class entry
naming this class or interface, with / between packages, such as
java/util/EmptyStackException.
super_class
An index of a Class entry naming the direct superclass. It is 0 only in
java/lang/Object, which has none. An interface’s super_class is
java/lang/Object.
interfaces
interfaces_count is followed by that many two-byte indexes of Class
entries: the interfaces in the class’s implements clause, or an
interface’s extends clause, in the order of the source.
Limits
- At most 65,535 constant pool slots, interfaces, fields and methods, since the counts are two bytes.
- A method’s bytecode is at most 65,535 bytes, and its
max_stackandmax_localsat most 255, since the Code header gives them one byte. - A Utf8 constant is at most 65,535 bytes.
An example file
No Oak class files were found to examine for this site, so this example was built for
it: java/util/EmptyStackException from JDK 1.1.4, rewritten in this
format. It is the real file with its version changed to 45.2 and its one Code attribute
given the 4-byte header, which makes it 4 bytes shorter, 244 in all. The explorer reads
it as an Oak class file.
00000000 CA FE BA BE 00 02 00 2D 00 0F 07 00 0D 07 00 0E .......-........
00000010 0A 00 01 00 04 0C 00 06 00 05 01 00 03 28 29 56 .............()V
00000020 01 00 06 3C 69 6E 69 74 3E 01 00 04 43 6F 64 65 ...<init>...Code
00000030 01 00 0D 43 6F 6E 73 74 61 6E 74 56 61 6C 75 65 ...ConstantValue
00000040 01 00 18 45 6D 70 74 79 53 74 61 63 6B 45 78 63 ...EmptyStackExc
00000050 65 70 74 69 6F 6E 2E 6A 61 76 61 01 00 0A 45 78 eption.java...Ex
00000060 63 65 70 74 69 6F 6E 73 01 00 0E 4C 6F 63 61 6C ceptions...Local
00000070 56 61 72 69 61 62 6C 65 73 01 00 0A 53 6F 75 72 Variables...Sour
00000080 63 65 46 69 6C 65 01 00 1A 6A 61 76 61 2F 6C 61 ceFile...java/la
00000090 6E 67 2F 52 75 6E 74 69 6D 65 45 78 63 65 70 74 ng/RuntimeExcept
000000A0 69 6F 6E 01 00 1D 6A 61 76 61 2F 75 74 69 6C 2F ion...java/util/
000000B0 45 6D 70 74 79 53 74 61 63 6B 45 78 63 65 70 74 EmptyStackExcept
000000C0 69 6F 6E 00 01 00 02 00 01 00 00 00 00 00 01 00 ion.............
000000D0 01 00 06 00 05 00 01 00 07 00 00 00 0D 01 01 00 ................
000000E0 05 2A B7 00 03 B1 00 00 00 00 00 01 00 0C 00 00 .*..............
000000F0 00 02 00 09 ....
| Offset | Bytes | Field | Value |
|---|---|---|---|
| 0x00 | CA FE BA BE | magic | |
| 0x04 | 00 02 | minor_version | 2 |
| 0x06 | 00 2D | major_version | 45: version 45.2 |
| 0x08 | 00 0F | constant_pool_count | 15: entries #1 to #14, as on the constant pool page |
| 0xC3 | 00 01 | access_flags | public |
| 0xC5 | 00 02 | this_class | #2, java/util/EmptyStackException |
| 0xC7 | 00 01 | super_class | #1, java/lang/RuntimeException |
| 0xC9 | 00 00 00 00 | interfaces_count, fields_count | 0, 0 |
| 0xCD | 00 01 | methods_count | 1 |
| 0xCF | 00 01 00 06 00 05 00 01 | method 0 | public, <init>, ()V, 1 attribute |
| 0xD7 | 00 07 00 00 00 0D | its attribute | Code, 13 bytes long |
| 0xDD | 01 01 00 05 | Code header | max_stack 1, max_locals 1, code_length 5 |
| 0xE1 | 2A B7 00 03 B1 | code | aload_0; invokespecial #3; return |
| 0xE6 | 00 00 00 00 | Code tail | no exception handlers, no attributes |
| 0xEA | 00 01 | attributes_count | 1 |
| 0xEC | 00 0C 00 00 00 02 00 09 | attribute 0 | SourceFile: EmptyStackException.java |
Read with the later layout, the Code header’s bytes 01 01 would be a
max_stack of 257, 00 05 a max_locals of 5, and 2A B7 00 03
a code_length of over 700 million bytes, far past the 13 the attribute holds.