I just ran into a tedious bug with my use of BCEL: I was emitting some inner class declarations and got the byte length wrong for the InnerClasses attribute.

Both Sun's JVM and BCEL itself don't seem to actually care about the length field of attributes when loading a class, so I had never noticed a problem for a long time.

But when I tried to run my stuff in IBM's websphere runtime, I (correctly) got a class format error.

Ok, so I fixed it. The problem though is that knowing the byte length value for attributes is a tedious and fragile thing to maintain. One has to know the byte lengths of every piece being contributed to the attribute's data.

It doesn't have to be this way. Why can't the Attribute class compute it itself? This approach will work:

 final public void dump(DataOutputStream file) throws IOException
 {
// Dump attribute contents to an in-memory stream first so we can compute
   // the length.
   ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
   DataOutputStream memoryStream = new DataOutputStream(byteStream);
   dumpAttribute(memoryStream);
   memoryStream.close();
   byteStream.close();
   byte[] bytes = byteStream.toByteArray();

   file.writeShort(name_index);
   file.writeInt(bytes.length);
   file.write(bytes, 0, bytes.length);
 }

abstract protected void dumpAttribute(DataOutputStream output) throws IOException; The downside I see is a bit of a performance hit on dumping. However, the benefits of improved usage outweigh that by my standards at least. The getLength() method will not be valid until after a dump() is called, but I could not find any usage of this query in the existing sources. I suggest deprecating getLength() and setLength() as well.

The existing length-based constructors can be still exist but be made deprecated, essentially ignoring the length arg. Provide new constructors for all attribute subclasses without the length arg. This gives a migration path.

Cheers,
Ray Blaak



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to