The Access Modifier Modifier (AMM)

Important note

This version has been superseeded by the AMM2.

Purpose

to control and adjust class member visibility; to close a project against undesired access

System requirements

Rationale

Information hiding suggests that the visibility of class members should be no greater than required by their actual or designed use. However, during development, agile development especially, it is not always clear in advance which members of a class will be used and by whom. Selecting the required visibility then becomes a speculative process, and not infrequently a wider visibility than necessary is chosen, if only to save oneself and others the hassle of later correction. Likewise, changes to a program that would allow reduction of visibility of certain members are often performed without this reduction, simply because one is unaware of the fact that one's changes would allow this lower visibility (the higher visibility might still be required by other clients). What follows is that after a project has been finalized, members with unnecessarily high visibility persist.

The Access Modifier Modifier (AMM) lets one declare all members of a class or project open for access initially, and have visibility automatically adjusted to the actual requirements later (called class locking hereafter). To allow for future use of members (including use by third parties not included in the project), i.e., to let one design an API that survives automatic visibility reduction (locking), a minimum visibility can be introduced for individual members by means of a corresponding annotation. Also, the AMM lets one temporarily unlock a class (i.e., change visibility of all members to public), and later lock it to the prior visibility levels, save for the members that now need higher visibility.

How it works

After having downloaded and copied this jar into the plugin directory of Eclipse and restarting the workbench, the AMM is ready for use. However, each project to which it is to be applied must have access to the annotation types required to mark changes of visibility in the source code. For this, this library must be included in the project's build path:

Unlocking and locking

Individual compilation units or whole projects can be unlocked and locked, by selecting the corresponding entry from the AMM context menu:

Individual settings allow one to control the changes for unlocking

and locking

Note that unlocking a class introduces annotations where visibility is changed; these annotations are removed by subsequent locking, if the original visibility level is restored. Locking a class without prior unlocking produces no annotations.

Dealing with subclassing, overriding, and overloading

The AMM takes special care to not change the semantics of a program by changing the visibility of members. Such care is required in case of overriding (where reducing visibility of an overridden method may prevent dynamic binding of the overriding method) and overloading (where reducing visibility of a method with more specific parameter type may prevent it from being called). Also, visibility of an inherited member cannot be reduced below that of the superclass, and increased above that of its subclasses. However, the AMM can change visibility of complete class hierarchies (see locking dialog above).

Markers suggesting reduction of visibility

The AMM can be configured to check required visibility of the members of a class and provide gutter annotations (markers) for each member whose visibility can be reduced:

This produces markers like the following:

A quick fix is then available for performing the reduction if so desired:

Markers are computed upon opening a compilation unit in the editor, and recomputed (updated) after saving the compilation unit and after switching to its editor from that of another compilation unit. The latter allows changes in other compilation units to have an immediate effect on required visibility.

Excluding the API from locking

API methods (including hook methods) can be annotated as follows:

@MinAccess(AccessModifier.PROTECTED)
public abstract void someMethodCalledForOpenRecursion();

This bounds the possible change of visibility from below, and prevents corresponding markers from appearing.

Limitations

Other known issues

Installation

Copy this jar into Eclipse’s plugin directory and restart Eclipse. Include this library in the project's build path.

Future work

Publications

Team