OTDT 1.2 - New and Noteworthy

 Views

Call Hiearchy Extensions since 1.1.4
since E 3.4

The Call Hierarchy now supports more control flows:

  • Already version 0.9.22 of the OTDT supported method bindings (callin/callout) in the call hierarchy
  • In 1.1.4 we added support to search for write accesses to a given field, too.

    CallHierarchyForField

    Note, that method getCollectedCredits() is not shown in the Call Hierarchy, as it only reads from the given field. Also note the control flow through the callin binding earnCredit <- book

  • Later, we contributed patches to Eclipse 3.4, supporting:
    1. seeding a Call Hiearchy with a class (= all instantiations)
    2. seeding a Call Hiearchy with a field (= all field accesses)
    3. selecting the kind of field access:
      • all references
      • only read accesses
      • only write accesses
    Item 3 is missing from Eclipse's "New and Noteworthy". Here is the menu in action:

    CallHierarchyMenu

    This is one of a set of examples where an aspect plug-in was used to prototype a new feature and to immediately publish the prototype, while later restructuring the feature to become a patch for the original system.

Filter generated variables since 1.2.0
#114

During debugging it now possible to switch the filtering of variables that have been generated by the OT/J compiler or the Object Teams Runtime Environment.

  • Per default only source-level variables are shown, but the view menu now offers a new configuration option Java > Show OT/J Internal Variables
    variables1
  • With this option turned on during the execution of OT/J specific code like, e.g., a callin method, various internal variables (fields and locals) will be shown, which all start with the prefix _OT$:
    variables2
    This display may be helpful for validating internal mechanisms, for inspecting the state of a team and for navigating between team, role and base objects.
  • This option is available in the variable_view Variables view (see above) and in the team monitor Team Monitor:
    variables3

Beautified Debug View since 1.1.7
#67#91

The debug view has been improved for presenting call stacks with aspect dispatch code in a more useful way
DebugView
In this screenshot the following improvements can be seen:

  • Method names are translated back to source level code. This applies to
    • method bindings,
    • guard predicates and
    • base calls.
    These stack frames are printed in green.
  • Intermediate stack frames are marked as {{Dispatch aMethod}} or {{Lift to ARole}} (printed in pale purple).
The colors can be configured on the preference page Object Teams > Debug.

Team Monitor

since 1.1.2

since 1.1.6

The Team Monitor, which was missing from the 1.1.0 release has been resurrected and enhanced. Using the Team Monitor you can easily check the activation state of all team instances of an OT/J program running in the debugger.

  • The Team Monitor now supports optional variable filtering
  • Values can be displayed with columns (just like the Variables view — configurable via the view's drop down menu).
  • When the program is suspended due to a breakpoint or when stepping, a context menu supports to interactively (de)activate a team.
    Depending on the selection in the debug view (launch target launch target or individual thread thread) the team will be (de)activated either for all threads or only for the selected thread.
    The following example would deactivate team team ui.WindowPlacer for all threads (the launch target is selected):
    TeamMonitor
  • Consistent display of the team's activation state (team inactive, team active, team implicitly activated) either regarding all threads (launch target selected) or regarding the selected thread.

Filter applicable types since 1.1.7
since E 3.4
#59

The Extension Editor of the PDE has a Browse button for each field representing a class. The selection dialog opened by this button now filters available types using the information from the extension point schema. If, e.g., the extension being created is an org.objectteams.otequinox.aspectBinding, the dialog will only show subclasses of org.objectteams.Team as specified in the schema:
SelectType
This feature has first been implemented for the OTDT 1.1.7. Later the patch was adopted by the PDE UI, available now in every Eclipse 3.4.

 Content Assist

Selecting the binding kind
since 1.1.5
#31

When a method binding is created using completion, the different binding kinds are now offered as options.

CompletionBindingKind

Lifting-aware completion
since 1.1.9
#101

When creating a method binding (callin callin or callout callout) via completion (Ctrl-space), the role method signature can be adjusted to replace base types by corresponding role types. If the role type is chosen, compatibility will still be guaranteed due to translation polymorphism (lifting/lowering), since only compatible roles are offered by the completion:

CompletionLifting

More locations support completion
since 1.1.9
several

Completion is now also available within

  • (partially typed) method bindings including parameter mappings, #97
  • guard predicates #24
  • the New Role Wizard #39

Various new Quickfixes

The OTDT offers various new quickfixes (Ctrl-1):

  • Generic Callin: since 1.1.3
    Due to stricter rules of the type system, some callin methods and bindings must now be written using a type parameter. Violations against 4.9.3(c) will now offer a quickfix to insert appropriate type parameters.
  • Team Anchor: since 1.1.5
    Refering to an externalized role without specifying a team anchor can now be corrected using quickfix:
    AddTeamAnchor1
    A list of all variables in scope that are suitable as a team anchor in the current position is offered to select from:
    AddTeamAnchor2
  • Unresolved methods in method bindings: since 1.1.2
    If a method binding refers to an inexistent role method a quickfix can be used to either
    • correct the method name to match an existing method, or:
    • create the missing role method. A callin modifier is inserted if required by the binding.
    CreateRoleMethod
  • Materialize inferred callout: since 1.1.2 (cf. #32)
    When the compiler reports that a callout was inferred, a quickfix is provided to materialize the callout binding:
    MaterializeInferredCallout

    When a callout to field was inferred, additionally the field access can be changed to a method call to the callout binding: (#43)
    MaterializeInferredCallout2

 Language

Improved reflective methods
since 1.2.0
#110#112

The reflective method getRole(Object,Class) and getAllRoles(Class) defined in class org.objectteams.Team have been improved in two ways:

  • Method getAllRoles(Class) now always uses the given class as a filter (see #110).
  • The signatures of both mentioned methods have been improved such that no casting is required for the returned value. This is achieved by declaring both methods generic (see #112):
    <T> T[] getAllRoles(Class<T> class_arg);
    <T> T getRole(Object aBase, Class<T>);
    // use is as in:
    R r = t.getRole(aBase, R.class);

Generic method bindings
since 1.1.9
#99

Method bindings now fully support the use of type parameters to reconcile type safety with desirable flexibility.
See 4.9.3 and 4.10

  • The OT/J type system had a bug which is/was common to all known aspect languages: seemingly compatible signatures could cause a type error in correct client code:
    old:
    protected class MyRole playedBy MyBase {
        callin Object roleMethod() {
            System.out.println(base.roleMethod(); // type safe
            return new Object();
            // bound using a seeming compatibility:
            Object roleMethod() <- replace String baseMethod();
        }
    }
    // Client code that breaks if the callin is active:
    MyBase b = ...
    String s = b.baseMethod(); // ClassCastException!
    
    This callin binding is type safe wrt the base call within roleMethod() but client code expecting a String result from baseMethod() breaks when actually roleMethod() is executed instead.
    The same situation arose when baseMethod() was actually declared to return Object but was overridden in a sub class and redefined to return Stringcovariant return types are allowed since Java 1.5.

    To fix this problem the language now requires the callin method to be declared generic whenever base methods with different return types should be intercepted:
    new:
    protected class MyRole playedBy MyBase {
        callin <T> T roleMethod() {
            T val = base.roleMethod(); // type of val is now unknown
            return val; // type Object is no longer allowed here
        }
        <T> T roleMethod() <- replace Object+ baseMethod(), String otherBaseMethod();
    }
    This kind of callin method can safely intercept base methods with different signatures. Capturing covariant overrides must now explicitly be specified with a "+" after the return type.
    Should the role method require more information about the type of val then the type parameter should be constrained as in <T extends List>, which restricts the set of compatible base methods to those returning at least a List.

    A quickfix exists for adding type parameters to a callin method and its binding.

  • Also methods with different parameter types can be captured using generics. See #99 for a list of test cases.

Inferred Callout
since 1.1.2 #30

When a role tries to directly access a base feature (method or field) for which no callout binding has been defined, the missing callout binding can be inferred by the compiler. Similarly an attempted field access can internally be re-mapped to a call to the corresponding (inferred) callout.

The compiler can be configured to treat inferred callouts as an error, or to issue a warning or to silently accept (ignore).

Quickfixes exist to materialize the callouts, i.e. for migrating from inference to explicit declarations.

Improved keyword scoping
since 1.1.9
#105

The control over when base is interpreted as a keyword or an identifier has been improved to cover even situations like this:

import base base.MyClass;

Here the first occurrence of base is recognized as a keyword, while the next word is interpreted as an identifier (the name of a package).
 OT/Equinox

OT/Equinox robustness
since 1.2.0
#69#122

OT/Equinox integrates its byte code transformer in a much more robust way now.
Previously, OT/Equinox had significantly modified the sequence of bundle and class loading when Eclipse (Equinox) is launched. This modification could trigger potential deadlocks whose root cause was by a bad interplay of Equinox and the Sun JVM. These problems have been summarized in Trac #122.
Starting with the solution to Eclipse bug 208591 which we adopted as of #69 several improvements could be made to minimize the danger of deadlocks. As part of the solution, two non-standard JVM-arguments are now automatically added to the file eclipse.ini when the OTDT is installed. This automatic modification of eclipse.ini was made possible by new capabilities of the "p2" provisioning system.

Forced Exports

since 1.1.4

since 1.1.5

#3#18

Despite decapsulation, even an aspect plug-in can normally access only those classes of its base plug-in, that are exported from that plug-in. If access to a non-exported class is indeed needed, the required export can be forced upon the base plug-in. The steps required for accessing a class using forced export are (see also this detailed description):

  • The class must be imported using import base which ensures that the class can only be accessed via a playedBy relation and callin/callout method bindings.
  • The aspect binding must request a forced export from the base plug-in.
  • The forced export must additionally be granted by an entry in the systems config.ini or by properties passed on the command line.
Compiler and runtime environment together strictly enforce these rules.

Launch types
since 1.1.3

A new launch type OTEquinox launch type "OT/Equinox Application" has been added for running OT/Equinox bundles without an Eclipse runtime workbench.

Self adaptation
since 1.1.3

OT/Equinox also supports teams adapting classes from their own enclosing plug-in (bundle). This is achieved by declaring an aspect binding in the plugin.xml with the pseudo base plug-in "SELF". Activation is declared as usual using either NONE, THREAD or ALL_THREADS.

<aspectBinding>
   <basePlugin id="SELF" />
   <team class="my.pack.age.MyTeam" activation="ALL_THREADS" />
</aspectBinding>
 Supported Platforms

Virtual Machines

since 1.1.4

since 1.2.0

OT/J programs can now be executed on more virtual machines. While conceptually any virtual machine should be able to execute OT/J programs, experimenting with other VMs revealed a few situations where the Sun's JVM accepts byte code that other VMs consider illegal.

Currently, the following virtual machines have been tested:

  • Sun (JRE 1.5, 1.6)
  • IBM (JRE 1.6)
  • JamVM (1.5) with Gnu Classpath.zip