Next: Miscellaneous
Up: Other Changes
Previous: Checking constraints
Tagging and exception handling
Most modifier-incompatible changes can be handled by tagging the global allocation table entries with modifiers (e.g. access control, readable/writable, instance/static, etc.). In the offset tables, the entries are tagged with the expected modifiers, too. During class loading, the class loader decides whether the modifiers are compatible, and fills in an offset table entry with the registered offset only if they are.
While we could use offset 0 for all kinds of error handling, it is usually preferred to raise different exceptions on different incompatible changes.
To achieve this, we can reserve more entries in the vtables and other data structures (e.g. itables) for various exception code.
If a certain access is denied according to the global allocation table, the offset of the corresponding exception entry is used.
- (24) Final virtual methods cannot be overridden. During class loading, a
subclass studies the vtable layout of its superclass. A
tag in the global allocation table indicates whether a virtual method is
final. If a final virtual method is overridden, VerifyError exception is raised immediately.
- (25) If a binary change restricts access to a member, the tag in the corresponding global allocation table entry can be used to decide whether an access is granted.
If an access attempt to a field is denied, IllegalAccessError exception is immediately raised. If an access attempt to a method or constructor is denied, the offset of the exception entry is used.
- (26) If a field that was not final is changed to be final, then it can break compatibility with pre-existing binaries that attempt to assign new values to the field.
Our solution is to tag the final
field with read-only access in the global allocation table. If some offset
table is expecting the field to be tagged with writable access,
IllegalAccessError
exception is raised.
- (27) Changing the static modifier of members could raise exceptions
when the member is accessed. Static members and instance members are tagged
differently in the global allocation table and the offset tables. In the
case of field modifier mismatch, IncompatibleClassChangeError
exception is raised; while in the case of modifier mismatch of other
members, the entry in the table is filled with the offset for code
raising the exception.
- (28) An abstract method cannot be invoked. If a subclass inherits a method defined in the old binary of a superclass , and is changed by declaring as an abstract method, invoking on an object of is going to raise an exception (AbstractMethodError).
Our solution is,
when constructing the vtable of a class that declares an abstract method , to put a pointer to the exception code in the entry of . A subclass that does not define inherits the exception code, while a subclass that defines works as if no change is made.
- (29,42) The members of nonpublic classes cannot be accessed from outside the package. Having access tags in the corresponding global allocation table entries solves this problem. Similar observations apply to interfaces.
Next: Miscellaneous
Up: Other Changes
Previous: Checking constraints
Dachuan Yu
2002-05-23