The Access Modifier Modifier (AMM), Version 2

Purpose

to control class member accessibility in an agile context; to close a project against undesired access

System requirements

Rationale

Information hiding suggests that the accessibility 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 accessibility then becomes a speculative process, and not infrequently a wider accessibility than necessary is chosen, if only to save oneself and others the hassle of later correction. Also, changes to a program that would allow reduction of accessibility of members are often performed without this reduction, simply because one is unaware of the fact that one's changes would allow this lower accessibility. What follows is that after a project has been finalized, members with unnecessarily high accessibility persist.

The Access Modifier Modifier (AMM) tool provides programmers with immediate information about and control of the accessibility status of class members. All members with excessive (i.e., higher than required) accessibility are marked by a warning equipped with a corresponding Quick Fix, allowing reduction of accessibility with a few key strokes. Members of an API that are not currently used by the project (so that their accessibility appears excessive, but is not) can be tagged by an @API annotation and are thus excluded from analysis. Members with insufficient accessibility are nevertheless included in code completion (Content Assist in Eclipse terminology); upon selection, their accessibility is increased to the required level, without changing to the source file.

The AMM verifies that no change to accessibility it suggests or performs changes program semantics. It may thus be viewed as a refactoring tool with built-in smell detection and strict precondition checking.

How it works

The AMM tool is implemented as a builder that can be added to and removed from a project. To add the AMM Builder, go to the properties page of a project and select the AMM Properties sheet:

By checking and unchecking the "AMM Builder Active" box the AMM Builder is added and removed.

The property sheet also offers the exclusion of packages from the analysis. In framework and other open projects, the packages to be excluded are usually packages that are not explicitly designed as being internal (the API packages; see Eclipse Naming Conventions and Package Naming Conventions Used in the Apache Harmony Class Library).

After closing the property sheet, the project is automatically rebuilt if so required.

Markers suggesting reduction of accessibility

The AMM builder generates a warning and a gutter annotation (marker) for each member whose accessibility can be reduced:

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

Excluding the API from reduction of accessibility

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

@API
public abstract void someMethodToBeCalledFromOutsideTheProject();

This prevents markers suggesting a reduction of accessibility from appearing. Insertion of the annotation is offered as an alternative Quick Fix for a reducible access modifier ("Add @API annotation"; see above).

Increasing Accessibility

If a member of a class is inaccessible, it can nevertheless be offered in Content Assist, by pressing Ctrl + space until the corresponding frame is displayed; selecting a member automatically increases its accessibility to the required level.

Dealing with subtyping, overriding, and overloading

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

API declaration through interface types

The reduction of accessibility is limited by interface implementation: accessibility of members of a class required by an interface implemented by the class cannot be reduced (see above). Interface implementation therefore substitutes for @API annotations. This is a problem if the interface is designed for internal use only, i.e., if it is not meant to be part of the API – its publicity is then carried over to the implementing classes, and there is nothing the AMM can do about it. However, the size of the interface can be minimized by a different tool, namely our Infer Type refactoring.

Limitations

Other known issues

Installation

The AMM tool is installed using this update site. This Eclipse help shows you how to do it; in step 4, enter "AMM" as the name and "http://www.fernuni-hagen.de/ps/prjs/AMM2/update/" as the URL.

Publications

Team