removing the need to the "length" arg in Attribute constructors

Ray Blaak <[email protected]>
Newsgroups gmane.comp.jakarta.bcel.devel
Organization Ensemble Systems
Message-ID <[email protected]>
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.