OTDT 0.7.1 (Incubation) - New and Noteworthy

Views & Dialogs

Traditional Hierarchy View
since 0.7.1

The "traditional" hierarchy view is a mode of the Type Hierarchy View, where starting from a given focus type both the tree of subclasses and the chain of superclass is rendered in a single view. Due to the fact that roles may have multiple superclasses this mode was disabled in the OTDT.

A new adaptation of the internal TypeHierarchy classes allows us to linearize the set of superclasses wrt the focus class, i.e., superclasses are shown in the order as seen from the focus class, which prioritizes implicit inheritance over explicit inheritance.

E.g., consider the following code:

public team class EcoSystem {
   protected class Project { }
   protected class IDEProject extends Project { }
public team class Eclipse extends EcoSystem {
   protected class Project { }
   protected class IDEProject/*open Type Hierarchy here*/ extends Project { } 
   protected class CDT extends IDEProject { }
   protected class JDT extends IDEProject { }
   protected class OTDT extends IDEProject { }

which yields the following rendering:


Content assist

Adjust callin return
since 0.7.1

Previously, when creating a callin method using completion, the role method designator would be created with the exact same return type as the bound base method. However, for before and especially after callin bindings this was misleading, because any value returned by the role method would be simply ignored.

In order to avoid confusing the user, method binding completion now works with the following changes:

  • Completion generally offers the option to replace the role method return type with void:

Return type options

  • Still, the binding kind <- after can be selected without selecting void as the return type:

Selecting after

  • However, when the binding kind is confirmed by hitting enter, the return type is automatically adjusted to void:

Created method binding


Change Signature Refacoring
since 0.7.1

The Change Signature refactoring has been adapted to work for OT/J sources, too. Now, if the signature of a method is refactored that is referenced from a callout or callin method binding, the binding is adjusted accordingly. The refactoring tries to absorb all changes within the binding, like adding a parameter mapping to absorb a re-ordering of arguments. If a change needs to be propagated through the binding (i.e., it cannot be fully absorbed) the refactoring will inform the user by issuing a warning.

Here is a preview of a refactoring, where the signature of bm has been changed by (a) adding an argument String str and (b) moving argument i to the end:

Change Signature preview

Run / Debug

Stack frame beautifying
since 0.7.1

The Debug View now knows about more kinds of synthetic methods generated by the OT/J compiler. All these methods are beautified by replacing the internal name with a human readable explanation and de-emphasizing these stack frames using a lighter color.

Beautified stack frames

The shaded stackframes in the above screenshot signify (from top to bottom):

  • Access to a private base method applying decapsulation
  • Invocation of a synthetic method for initializing the fields of a role
  • Indirect invocation of a role's constructor (late binding of the role class)


isActive() is now final
since 0.7.1

Previously, methods Team.isActive() and Team.isActive(Thread) could be overridden in sub-teams, but if an overriding version did not return immediately it could cause a deadlock, because the infrastructure invokes these methods from synchronized blocks.

In order to avoid this risk of deadlocks, both methods have been changed to final.


Internal State Pattern
since 0.7.1

Previously, OTJLD (v1.2) §2.1.2(b) disallowed to bind a role to its enclosing team. This rule was found to be overly cautious and prohibitive. By essentially removing this restriction (except for a few corner cases), the following pattern is now possible:

public team class MyTeam {
   public void service() { ... }
   Mode mode;
   protected class MaintenanceMode playedBy MyTeam
      base when (MyTeam.this.mode == Mode.MAINTENANCE) {
      	  mainenanceNotice <- replace service;
   protected class BootingMode playedBy MyTeam
      base when (MyTeam.this.mode == Mode.BOOT_IN_PROGRESS) { ... }
The point is here that both roles adapt their enclosing team MyTeam - thus providing a very well localized implementation for different states/modes of the team.

Note, that the above code will cause the compiler to signal a warning: "Base class MyTeam is an enclosing type of MaintenanceMode ...", which can be silenced by @SuppressWarnings("baseclasscycle")

See also the Internal State Pattern in the wiki.


playedBy Interface
since 0.7.1

The OTJLD never said that the type after playedBy definitely must be a class, but contained a note mentioning a compiler limitation in this regard. This limitation has been weakened so that now a role can also be bound to an interface. Only, in such situations the role cannot declare callin method bindings (callout is not a problem). It is of course possible to define sub-roles that are bound to classes implementing the base interface such that those sub-roles can declare callin bindings, too.

Object Teams Runtime Environment

Packaged as a bundle
since 0.7.1

Packaging and deployment of the OTRE has changed from a plain Jar to a regular OSGi bundle called org.eclipse.objectteams.runtime. Yet, this bundle Jar can still be used outside any OSGi context. While this simplifies several build and deploy issues, the change should be mostly transparent for users. Only when compiling/running OT/J applications outside Eclipse script will need adjusting to refer to the bundle Jar instead of the old otre.jar.