The goal for this lab is to read a Java class file and determine how many constant pool entries, interfaces and fields it contains.
You should consult Chapter 4 of the Java Virtual Machine specification.
The name of the class file to read will be given as the only command line argument. You should print an error message and terminate the program if no file name is given, or a bad file name is given, or more than one argument is given.
I recommend that to simplify the program you first open the file and read the whole program into a malloc-ed buffer. A simple way to do this is to read the file twice using getc. The first time you can discard the bytes that are read because you are just counting the number of bytes in the file. Once you know how long the file is, then malloc the buffer. And then read the file a second time into the buffer. (If you cannot open the file, print this error message to stderr on its own line, "cannot open", and follow it with the name of the file given on the command line.
Next you want to check the first four bytes in the file, which should contain the Java class file magic number, 0xCAFEBABE. All multi-byte values in a class file are stored in Big Endian format. If this check fails print the error message "not a Java class file (bad magic number)" to stderr on its own line and exit the program.
Next retrieve and display to stderr the number of constant pool entries in decimal on a line by itself. Label this output appropriately, such as "constant pool entry count is 351". The value to be displayed should be the count stored in the file, which is one more than the number of entries contained in the file.
Next skip over the constant pool entries to locate the number of interfaces. This is tricky because the constant pool entries are of variable length, but each begins with a one-byte tag that identifies the type of the constant pool entry. In most cases, this tag fully determines the length of its entry. However, in one case, CONSTANT_Utf8, you will need to access an internal length field, in order to determine the overall length of the entry. Another complication is that two types of entries (CONSTANT_Long and Constant_Double) are considered to consume two contant pool entries. That is, they are counted twice in the constant pool entry count.
Next retrieve and display to stderr the number of interfaces in decimal on a line by itself. Label this output appropriately, such as "interface count is 4".
Next skip over the interface descriptors. This is easy to do, because each interface descriptor is a fixed length.
Next retrieve and display to stderr the number of fields in decimal on a line by itself. Label this output appropriately, such as "field count is 7".
Next terminate the program.
Lab 6 will continue this code from this point, to further explore a class file.
Put all your source code in a single file, "prog3.c".
If you find it helpful, you can include /usr/java/jdk/include/classfile_constants.h. But you should write all the other code yourself.
There are a variety of class files in ~cs520/public/prog3.
Also test with bad input files. In particular, in addition to detecting files that do not begin with the Java class file magic number, also detect class files that are truncated or that contain invalid constant pool entry tags. These are the only file validations that you need to perform.
You can use the javap command, as well as od, to examine class files to determine if your program is working correctly.
Points will be awarded for this lab in the following way:
Turn in this laboratory by typing:
% ~cs520/bin/submit lab5 prog3.c
Submissions can be checked by typing:
% ~cs520/bin/scheck lab5
Remember that there are no late submissions of labs. Submit what you have prior to 12noon on Sunday February 24. Be careful: one minute late is late.
Comments and questions should be directed to pjh@cs.unh.edu