Writing constant pool bytes to a class file

Hello,

I'm in the process of writing the bytes to generate a class file for a small programming language Ive developed for a project.

I'm putting all the data from the various structures storing the class file data into a ByteBuffer, in the order specified in the Class File Format Specification, which i'm then writing to a file.

This is working fine for the magic number, minor and major version numbers and constant pool count, but then when javac gets to what should be the tag byte of the first element in the constant pool it returns a "unknown constant tag" error (even though the value written for it is 1 as the first element is a Utf8_info element. When comparing the contents of my generated class file to an equivlent class file for an empty java program with matching values for magic number, minor, major version and constant pool count, the contents are exactly the same byte for byte for those values except the equivielent class file has a few extra bytes before the first constant pool element. Does this mean I need to write some value before writing the constant pool bytes, maybe so javac knows that that signals the start of the constant pool? At the moment, i'm writing the tag byte of the first constant pool element straight after the constant pool count value. Any help is greatly appreciated.

regards

adam

[1373 byte] By [adamcuza] at [2007-11-26 20:17:13]
# 1

Sounds like you're not writing the correct data types to the fields.

Eg. The pool count is an unsigned short, the tag is a byte.

Also, when you get to the rest of the constant pool entries...

Long and Double values need TWO entries in the constant pool.

It's awkward, but can't be avoided.

So the constant pool "count', is not a count but the size of the array.

Eg. 4 Long values = a constant pool size of 8.

regards,

Owen

omcgoverna at 2007-7-10 0:40:27 > top of Java-index,Developer Tools,Java Compiler...
# 2

That was the problem - I was writing the number of elements in the constant pool array not the actual size of the array. Java now accepts everything up until the byte array containing the string bytes of the first CONSTANT_Utf8_info element, where it returns an Illegal UTF8 string in constant pool error. I've used the getBytes() method to encode the bytes of the string into the byte array of the CONSTANT_Utf8 _info element, and write the length of the resulting array for the length field but I still get the above error. I read somewhere that the UTF8 encoding for java class files is slightly different from the standard UTF8 encoding mechanism. Is there something I'm missing out / need to do differently to get the jvm to accepts my utf8 strings? With regards to writing the different data types to the fields, I've been using the putByte(), putShort() and putInt() methods of the bytebuffer for the appropriate fields. Thanks for your help with the previous questions.

adamcuza at 2007-7-10 0:40:27 > top of Java-index,Developer Tools,Java Compiler...
# 3

When I'm reading those entries I use DataInputStream.readUtf();

So try writing it as DataOutputStream.writeUtf ( String mystring );

You won't need to mess around with encoding, it accepts a string as it is.

Ps. You do know there's libraries like ASM out there, to help you dynamically build class files, if needed ?

regards,

Owen

omcgoverna at 2007-7-10 0:40:27 > top of Java-index,Developer Tools,Java Compiler...