Object Teams says: “Hello Eclipse”
I’d like to return the warm “welcome” Wayne recently pronounced under “Heady Times”.
The Object Teams Project is thrilled to finally move into the Eclipse house. I guess we are not complete strangers, as I’ve spoken at two EclipseCons and met quite a few of you in bugzilla etc. But still a majority might not be sure what the Object Teams Project is all about, so here comes a little introduction:
Origin
Formally, the Object Teams Project is a cross-over between ambitious research in language design and an extremely pragmatic approach to writing highly modular code even under high pressure of re-use, maintenance, evolution and that sort of conditions. Our pragmatism made us refrain from designing a language from scratch but made us create OT/J as an extension of Java. This pragmatism has furthermore led us to spending >99% of our time on building actual working tools in contrast to <1% of tweaking new language features. That’s why we decided as early as 2003 to not develop a standalone compiler for our language but to base everything on the JDT (v2.1.1!) so we would soon have a full-featured, high-quality IDE. From this the Object Teams Development Tooling (OTDT) was born
which had its first public appearance in 2005. This development was a tremendous joint effort (2003-2006) of the Fraunhofer FIRST institute and the Technical University Berlin.
Two ways of looking at Object Teams
(1) Conceptually: Object Teams solves the dilemma of structuring software by functions (procedural or functional approaches) or by data (object oriented approach). In Object Teams you do both simultaneously. Suppose you are writing a banking application. After some core concepts have been implemented and tested you are about to implement a new use case, say Wire-Transfer. Do you add new methods to existing classes like Customer, Account, ATM etc? Or do you consider those classes as dumb data objects and create one new class WireTransfer? The Object Teams answer: you do the best of both approaches: you create a role for each relevant class, implement the new behaviour in terms of role methods calling each other. Roles are grouped into a team (here: WireTransfer) and roles are bound to the underlying core objects (here: of type Customer, Account etc.). – Looking for a data-module, an entity? Just inspect the
Account together with all its roles. – Looking for a behavioral module? Just inspect the WireTransfer team with all its contained roles. Voila.
Sounds esoteric? “Role modeling”, “collaboration based design” and similar off-springs of the same ideas have been embraced for analysis and design for quite some time (cf. OOram, Catalysis etc.). Object Teams finally gives a natural implementation to such models. Finally we can cleanly compose a system from one module per use case.
It turns out, however, that you may also look at Object Teams from an even more pragmatic point of view:
(2) Pragmatically: As one of its core capabilities a role can override a method of its bound base. Given that roles can be added to existing entities at any time (add role classes at compile-time, add role instances to base instances even at run-time), roles provide a mechanism for extending and adapting existing things without touching them (“non-invasively”). As an example consider the JDT/UI: a plug-in providing an excellent user experience for working with Java code. Guess what: just by adding a number of roles and without changing a single source line of the the JDT/UI we created the OTDT/UI: a plug-ing providing an excellent user experience for working with OT/J code 🙂 .
While the mere possibility to non-invasively adapt existing plug-ins is fascinating by itself, using Object Teams for this task also guides you towards a code structure that is actually easy to read and highly suitable for future maintenance and evolution.
OT/Equinox
Here is why all this is highly relevant for everyone writing Eclipse plug-ins: we have married OT/J to Equinox (first presented at Eclipse Technology eXchange 2006 in Nantes) so that all the concepts of Object Teams can seamlessly be leveraged when developing plug-ins. The consequences of this I will leave for your imagination at this point. More to follow soon.
Show me the code
This post has become a little verbose, with no real examples. Some examples will follow in subsequent posts. In the meantime you may want to look at the
- Object Teams Quick-Start with actual code to pimp the Eclipse workbench “in less then 15 minutes”.
What’s next?
Currently our initial contribution awaits the initial OK so that we can start committing to SVN. Pretty soon after you should expect the first milestone release (incubation) from eclipse.org. “If all goes well” we will apply for graduation by the time of the Helios release, so you would see an OTDT 2.0.0 accompanying the Helios GA. After 70+ releases (incl. milestones) in our previous identity at objectteams.org I say we should be able to demonstrate the maturity required for that next big step.
Please stay tuned and join the discussion in our forum.
Thanks to everybody who made our move to Eclipse.org possible!
Why I’m sometimes a bad bug reporter
OK, I use Eclipse for getting some work done. Eclipse is software so we know it contains bugs. Given that Eclipse is open source software, we all can only expect it to run smoothly if we diligently report back all errors we encounter (and provide steps on how to reproduce etc.). I know all that and I really want to be a good bug reporter because I really want a good experience using Eclipse because I really want to get the work done (and I may even want to sustain the impression that I’ve got everything under control and thus working with Eclipse is a delight).
A task
The other day, I was a very bad bug reporter, and only today I find some time to reason about what happened. This was my task: In preparing the initial contribution for the Object Teams Project I had to rename a bunch of things from org.objectteams to org.eclipse.objectteams. Simply, huh? Back in the days of emacs+bash I might have chosen to just use one big
find . -exec /bin/sed -i -e "s/org.objectteams/org.eclipse.objectteams/g" {} ;
and voila, if fortuna was with me, I might have been done at the return of that single command. But things were actually just a little bit more challenging, like, a few occurrences would have to remain unchanged plus while touching about every single file in our software I was going to also do some clean-up: rename some packages to foo.internal.bar, fixing some copyright headers, etc. Also I preferred to change one plug-in at a time which would mean that all references to plug-ins not yet processed should stay unchanged, too. Plus a few more little deviations from the grand search-and-replace-globally.
OK, since I like to see myself an Eclipse-wizard this was a nice challenge for its refactoring support. Plug-in by plug-in I renamed, I renamed packages with / or without subpackages, and after each step I wanted to see that compiler and PDE agree with all changes and signal that everything is still (or again) consistent, ready to be built, actually. Perhaps things started the get wrong when I estimated the effort as one or two hours. So, after a day or so, I wasn’t perfectly relaxed any more. My fault, should’ve known better about that estimate. BTW, one of the reasons it took so long was simply the size of my workspace in comparison to the power of my computer / hard-disk: every time I performed a rename with updates in non-Java files, I was nervously looking at the screen: “should I sit and wait for the preview page, or should I go to the kitchen, get a chocolate, coffee, just something?“. I did some emailing in parallel, but let’s just keep this: due to those response times
I wasn’t perfectly relaxed any more.
A story of bug reporting
What I was going to tell here is a story of bug reporting, because as a safe bet doing a real-life stress test to an Eclipse component should give you a good chance to discover and report a few bugs that have not yet been reported by others. And indeed, I was successful in discovering some bugs, in various components actually.
I think one of the first things that occurred was that the svn synchronize view would sometimes fail to open the compare editor, more precisely, I had to explicitly close the compare editor before comparing the next file. At first this really **** me off, because the error dialog was popping up in some kind of infinite loop. Fun!#$ Once I’d figure out how to work around this problem it soon became a habit to just close the compare editor before clicking the next. Next, the svn plugin made a refactoring fail, because it was trying to create a directory which the previous refactoring had already created. The most creative bug having to do with subversive was a chain-reaction of first failing to undo a refactoring and than during reporting this error blocking the UI of Eclipse so I could only kill the Eclipse process, insert a new coin and start a new game.
I don’t intend to blame a particular component. For clean-up of license headers I have a little home-grown plugin that I just wanted to quickly install into the running Eclipse instance, so I went for the cool new feature to export/install into the host. Oops, my plugin depends on another plugin that only exists in the workspace but not in the host, install failed for good reasons. I removed the dependency and tried again. Installation still failed for the same reason: the ghost of this removed dependency prevented installation into the host Eclipse. Oh, I should have incremented the version or let a version qualifier do this automatically, of course. Tried again, still failed. Tried something so slightly different I cannot recall, from there on it worked. Can I reproduce the two or three different levels of failure? I didn’t even take the time to think of it. Well I would’ve been disappointed without a bug from p2 in this list 😉 .
PDE did its share by reporting overlapping text edits in plugin.xml and therefore disabling its refactoring participant. What the **** caused those overlapping text edits, and how do I re-enable the refactoring participant to give it one more chance to behave well?
The list could go on if only I could remember. Instead I was happy to finish this 1.5 hours task after 2.7 days, ready to submit our initial code contribution, wow!
Looking back, I / we missed a great opportunity: we could have identified plenty of bugs in various components of Eclipse. With only a few more days of debugging I might have been able to present reproducing steps for all those bugs. And, if triaged and fixed by the corresponding devs, this might have contributed to M6 containing fewer of those bugs that just only occur in real world, never during testing. I failed, I managed only to submit two bug reports, with very little information on how to reproduce.
Lesson learned
Susan McCourt responded to an earlier bug report of mine in a very descriptive comment:
That is one of those things I’ve been meaning to fix forever, never wrote a
bug, and so keep forgetting to fix. And it seems like if I’m actually
[doing what triggers the bug], it’s because something is wrong, and so I again postpone
writing a bug.
Sure, when we hit a bug (or a bug hits us) we are always in some context of doing something challenging. Something that requires our mind to stay in focus. Something we want to get done.
Well, work isn’t perfectly linear, so we know how to react to interrupts. Bugs are such interrupts. Sometimes I like the challenge of isolating a bug etc. Sometimes I’m sufficiently relaxed when the bug occurs so I actually take the challenge. Sometimes the bug is sufficiently good-natured so making a small note and going back to the bug after the actual work is done is a perfect strategy. Some bugs, however, smell like depending on so many factors from your current context that reproduction an hour later seems extremely unlikely.
I think I have a solution to all this: given we don’t want to be distracted from our actual work, given also that some bugs need immediate care or they will escape our attempts to identify. Given some of the worst moments are when we start to isolate a bug and during that task a second bug stops us from working on the first bug etc. The only way to relentlessly follow all those tasks is to enable branching universes in your working environment. The frequent use of the work “task” may give a hint that I should finally start using Mylyn (I have no excuse for not doing so), but I would need a Mylyn that is able to capture full contexts: the complete state of my machine plus the full state of my brain. As a start I’m dreaming of always working in a virtual machine, and whenever something strange happens, I quickly (!!) create a snapshot of the virtual machine. Then I could first isolate (and fix 🙂 ) the bug that just occurred, and then go back to the exact point where I
interrupted my work and act as if nothing had happened. Branching universes with the ability of back porting fixes between branches is what I need. Of course the clock needs to be reset when returning from a bug reporting / fixing branch.
Yeah, that’s why I can’t quite live up to my dreams of good participation in open source development: I haven’t figured out how to enable branching universes for my character. If anybody has a hint on how to do this or any other strategy to not get overwhelmed between work and bug reporting, I’d really appreciate.
And if I don’t smile while writing a bug report, please excuse, I might just be terribly stressed because your bug interrupted my work on isolating another bug that stopped me from doing …
”Always look at the bright side of life…” 🙂
Hello world!
Welcome to The Object Teams Blog.
Here you will find various examples of how OT/J can be used to create great software, plus updates on recent developments.
Why do we bother to run our own instance of wordpress? Simply because we want syntax highlighting for our code snippets, and we do want it for OT/J code, too.
So, here’s a welcome also from OT/J:
public team class HelloOTJ { protected class HelloAdaptor playedBy HelloWorld { void hello2 () { System.out.println("Hello from OT/J, too!"); } hello2 <- after main; } }

