The Object Teams Blog

Everthing Object Teams - adding team spirit to your objects.

Archive for the ‘presentation’ tag

Object Teams with Null Annotations

with 5 comments

The recent release of Juno M4 brought an interesting combination: The Object Teams Development Tooling now natively supports annotation-based null analysis for Object Teams (OT/J). How about that? :)

NO NPE

The path behind us

Annotation-based null analysis has been added to Eclipse in several stages:

Using OT/J for prototyping
As discussed in this post, OT/J excelled once more in a complex development challenge: it solved the conflict between extremely tight integration and separate development without double maintenance. That part was real fun.
Applying the prototype to numerous platforms
Next I reported that only one binary deployment of the OT/J-based prototype sufficed to upgrade any of 12 different versions of the JDT to support null annotations — looks like a cool product line
Pushing the prototype into the JDT/Core
Next all of the JDT team (Core and UI) invested efforts to make the new feature an integral part of the JDT. Thanks to all for this great collaboration!
Merging the changes into the OTDT
Now, that the new stuff was mixed back into the plain-Java implementation of the JDT, it was no longer applicable to other variants, but the routine merge between JDT/Core HEAD and Object Teams automatically brought it back for us. With the OTDT 2.1 M4, annotation-based null analysis is integral part of the OTDT.

Where we are now

Regarding the JDT, others like Andrey, Deepak and Aysush have beaten me in blogging about the new coolness. It seems the feature even made it to become a top mention of the Eclipse SDK Juno M4. Thanks for spreading the word!

Ah, and thanks to FOSSLC you can now watch my ECE 2011 presentation on this topic.

Two problems of OOP, and their solutions

Now, OT/J with null annotations is indeed an interesting mix, because it solves two inherent problems of object-oriented programming, which couldn’t differ more:

1.: NullPointerException is the most widespread and most embarrassing bug that we produce day after day, again and again. Pushing support for null annotations into the JDT has one major motivation: if you use the JDT but don’t use null annotations you’ll no longer have an excuse. For no good reasons your code will retain these miserable properties:

  • It will throw those embarrassing NPEs.
  • It doesn’t tell the reader about fundamental design decisions: which part of the code is responsible for handling which potential problems?

Why is this problem inherent to OOP? The dangerous operator that causes the exception is this:


right, the tiny little dot. And that happens to be the least dispensable operator in OOP.

2.: Objectivity seems to be a central property on any approach that is based just on Objects. While so many other activities in software engineering are based on the insight that complex problems with many stakeholders involved can best be addressed using perspectives and views etc., OOP forces you to abandon all that: an object is an object is an object. Think of a very simple object: a File. Some part of the application will be interested in the content so it can decode the bytes and do s.t. meaningful with it, another part of the application (maybe an underlying framework) will mainly be interested in the path in the filesystem and how it can be protected against concurrent writing, still other parts don’t care about either but only let you send the thing over the net. By representing the “File” as an object, that object must have all properties that are relevant to any part of the application. It must be openable, lockable and sendable and whatnot. This yields bloated objects and unnecessary, sometimes daunting dependencies. Inside the object all those different use cases it is involved in can not be separated!

With roles objectivity is replaced by a disciplined form of subjectivity: each part of the application will see the object with exactly those properties it needs, mediated by a specific role. New parts can add new properties to existing objects — but not in the unsafe style of dynamic languages, but strictly typed and checked. What does it mean for practical design challenges? E.g, direct support for feature oriented designs - the direct path to painless product lines etc.

Just like the dot, objectivity seems to be hardcoded into OOP. While null annotations make the dot safe(r), the roles and teams of OT/J add a new dimension to OOP where perspectives can be used directly in the implementation. Maybe it does make sense, to have both capabilities in one language :) although one of them cleans up what should have been sorted out many decades ago while the other opens new doors towards the future of sustainable software designs.

The road ahead

The work on null annotations goes on. What we have in M4 is usable and I can only encourage adopters to start using it right now, but we still have an ambitious goal: eventually, the null analysis shall not only find some NPEs in your program, but eventually the absense of null related errors and warnings shall give the developer the guarantee that this piece of code will never throw NPE at runtime.

What’s missing towards that goal:

  1. Fields: we don’t yet support null annotations for fields. This is next on our plan, but one particular issue will require experimentation and feedback: how do we handle the initialization phase of an object, where fields start as being null? More on that soon.
  2. Libraries: we want to support null specifications for libraries that have no null annotations in their source code.
  3. JSR 308: only with JSR 308 will we be able to annotate all occurrences of types, like, e.g., the element type of a collection (think of List<@NonNull String>)

Please stay tuned as the feature evolves. Feedback including bug reports is very welcome!

Ah, and one more thing in the future: I finally have the opportunity to work out a cool tutorial with a fellow JDT committer: How To Train the JDT Dragon with Ayushman. Hope to see y’all in Reston!

Written by stephan

December 20th, 2011 at 10:32 pm

Follow-up: Object Teams Tutorial at EclipseCon 2011

without comments

At our EclipseCon tutorial we mentioned a bonus excercise, for which we didn’t have the time at the tutorial.

Now it’s time to reveal the solution.

Task

Implement the following demo-mode for the JDT:

• When creating a Java project let the user select:
❒ Project is for demo purpose only
• When creating a class in a Demo project:
insert class name as “Foo1”, “Foo2” …”

So creating classes in demo mode is much easier, and you’ll use the names “Foo1″… anyway :)
(See also our slides (#39)).

Granted, this is a toy example, yet it combines a few properties that I frequently find in real life and which cause significant pains without OT/J:

  • The added behavior must tightly integrate with existing behavior.
  • The added behavior affects code at distant locations,
    here two plug-ins are affected: org.eclipse.jdt.ui and org.eclipse.jdt.core.
  • The added behavior affects execution at different points in time,
    here creation of a project plus creation of a class inside a project.
  • The added behavior requires to maintain more state at existing objects,
    here a JavaProject must remember if it is a demo project.

Despite these characteristics the task can be easily described in a few English sentences. So the solution should be similarly concise and delivered as a single coherent piece.

Strategy

With a little knowledge about the JDT the solution can be outlined as this

  • Add a checkbox to the New Java Project wizard
  • When the wizard creates the project mark it as a demo project if the box is checked.
  • Let the project also count the names of Foo.. classes it has created.
  • When the new class wizard creates a class inside a demo project pre-set the generated class name and make the name field unselectable.

From this we conclude the need to define 4 roles, playedBy these existing types:

  • org.eclipse.jdt.ui.wizards.NewJavaProjectWizardPageOne.NameGroup:
    the wizard page section where the project name is entered and where we want to add the checkbox.
  • org.eclipse.jdt.ui.wizards.NewJavaProjectWizardPageTwo:
    the part of the wizard that triggers setup of the JavaProject.
  • org.eclipse.jdt.core.IJavaProject:
    this is where we need to add more state (isDemoProject and numFooClasses).
  • org.eclipse.jdt.ui.wizards.NewTypeWizardPage:
    this is where the user normally specifies the name for a new class to be created.

Note, that 3 classes in this list resided in org.eclipse.jdt.ui, but IJavaProject is from org.eclipse.jdt.core, which leads us to the next step:

Plug-in configuration

Our solution is developed as an OT/Equinox plug-in, with the following architecture level connections:

This simply says that the same team demohelper.ProjectAdaptor is entitled to bind roles to classes from both org.eclipse.jdt.ui and org.eclipse.jdt.core.
One more detail in these extensions shouldn’t go unmentioned: Don’t forget to set “activation: ALL_THREADS” for the team (otherwise you won’t see any effect …).

Now we’re ready to do the coding.

Implementing the roles

18
19
20
21
22
23
24
25
26
27
28
29
30
31
protected class DialogExtender playedBy NameGroup {
 
	protected SelectionButtonDialogField isDemoField;
 
	void createControl(Composite parent) <- after Control createControl(Composite composite)
		with { parent <- (Composite) result }
 
	private void createControl(Composite parent) {
		isDemoField= new SelectionButtonDialogField(SWT.CHECK);
		isDemoField.setLabelText("Project is for demo purpose only");
		isDemoField.setSelection(false);
		isDemoField.doFillIntoGrid(parent, 4);
	}
}

Our first role adds the checkbox. The implementation of createControl is straight-forward UI business. Lines 22,23 hook our role method into the one from the bound base class NameGroup. After the with keyword, we are piping the result from the base method into the parameter parent of the role method (with a cast). This construct is a parameter mapping.

Here’s the result:

Next we want to store the demo-flag to instances of IJavaProject, so we write this role:

52
53
54
55
56
57
58
59
60
protected class EnhancedJavaProject playedBy IJavaProject {
 
	protected boolean isDemoProject;
	private int numFooClasses = 1;
 
	protected String getTypeName() {
		return "Foo"+(numFooClasses++);
	}		
}

Great, now any IJavaProject can play the role EnhancedJavaProject which holds the two additional fields, and we can automatically serve an arbitrary number of class names Foo1 …
In the IDE you will actually see a warning, telling you that binding a role to a base interface currently imposes a few restrictions, but these don’t affect us in this example.

Next comes a typical question: how to transfer the flag from role DialogExtender to role EnhancedJavaProject?? The roles don’t know about each other nor do the bound base classes. The answer is: use a chain of references.

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
protected class FirstPage playedBy NewJavaProjectWizardPageOne {
 
	DialogExtender getFNameGroup() -> get NameGroup fNameGroup;
 
	protected boolean isDemoProject() {
		return getFNameGroup().isDemoField.isSelected();
	}		
}
 
protected class WizardExtender playedBy NewJavaProjectWizardPageTwo {
 
	FirstPage getFFirstPage() -> get NewJavaProjectWizardPageOne fFirstPage;
 
	markDemoProject <- after initializeBuildPath;
	private void markDemoProject(EnhancedJavaProject javaProject) {
		if (getFFirstPage().isDemoProject())
			javaProject.isDemoProject = true;
	}
}

Role WizardExtender intercepts the event when the wizard initializes the IJavaProject (line 46). Method initializedBuildPath receives a parameter of type IJavaProject but the OT/J runtime transparently translates this into an instance of type EnhancedJavaProject (this - statically type safe - operation is called lifting). Another indirection is needed to access the checkbox: The base objects are linked like this:

NewJavaProjectWizardPageTwo —fFirstPage—> NewJavaProjectWizardPageOne —fNameGroup—> NameGroup

This link structure is lifted to the role level by the callout bindings in lines 35 and 44.

We’re ready for our last role:

62
63
64
65
66
67
68
69
70
71
72
73
protected class NewTypeExtender playedBy NewTypeWizardPage {
 
	void setTypeName(String name, boolean canBeModified) -> void setTypeName(String name, boolean canBeModified);
 
	void initTypePage(EnhancedJavaProject prj) <- after void initTypePage(IJavaElement element)
		with { prj <- element.getJavaProject() }
 
	private void initTypePage(EnhancedJavaProject prj) {
		if (prj.isDemoProject)
			setTypeName(prj.getTypeName(), false);
	}
}

Here we intercept the initialization of the type page of a New Java Project wizard (lines 66,67). Another parameter mapping is used to perform two adjustments in one go: fetch the IJavaProject from the enclosing element and lift it to its EnhancedJavaProject role. This follows the rule-of-thumb that base-type operations (like navigating from IJavaElement to IJavaProject) should happen at the right hand side, so that we are ready to lift the IJavaProject to EnhancedJavaProject when the data flow enters the team.

The EnhancedJavaProject can now be asked for its stored flag (isDemoProject) and it can be asked for a generated class name (getTypeName()). The generated class name is then inserted into the dialog using the callout binding in line 64. Looks like this:

See this? No need to think of a good class name :)

Wrap-up

So that’s it. All these roles are collected in one team class and here is the fully expanded outline:

All this is indeed one concise and coherent module. In the tutorial I promised to do this no more than 80 LOC, and indeed the team class has 74 lines including imports and white space.

Or, if you are interested just in how this module connects to the existing implementation, you may use the “binding editor” in which you see all playedBy, callout and callin bindings:

The full sources are also available for download.

have fun

Written by stephan

April 14th, 2011 at 9:14 pm

Object Teams @ GeeCON 2010 in Poznań

with one comment

Last week I had the great opportunity to speak at GeeCON 2010.

Wow, that was a big screen in Multikino 51 to use for presentations!

I’ve uploaded my slides, so if you missed the presentation or want to recap some points, just grab the slides. Please post your feedback or questions to the Object Teams forum.

I very much enjoyed all those discussions at the conference and I’m very sorry I had to leave early. I was specifically happy to hear that quite a few people in the audience had actually experienced the exact problems that Object Teams addresses (erm, no, I’m not happy to see people suffering but about the chance to help ‘em with our approach :) ).

Another good thing about the conference was that I found some minutes to chat with one of the mentors of the Eclipse Object Teams Project, Chris Aniszczyk. He gave me some new ideas for our project plan, which I will update shortly.

Thanks for the warm welcome by the organizers and the audience!

Written by stephan

May 17th, 2010 at 1:20 pm

Posted in Eclipse, Object Teams

Tagged with ,