Monday, April 20, 2009

Favoring immutability

A few years ago, when I read Effective Java for the first time, Item 13 really stuck in my mind: make your objects immutable wherever possible. You can share them freely. You don't have to worry about checking to see if that Person object you created still has a name. You made sure of that when you created it. And while I don't do a lot of concurrency programming, I've seen time and time again how much you get "for free" when you use immutable objects in multi-threaded environments. So that's another benefit.

OK, so I read the book, and moved on. Then I start working on a new project. We happened to pick GWT as part of the tool stack. During the early stages, a light bulb goes off in my head: hey, I'm writing a bunch of new beans in Java - I should make them immutable! Silver bullet, right? All my problems will go away. So I write a bunch of immutable beans.

Then I tried to serialize my immutable objects, and BAM, I hit this RFE: Serialize final fields. Turns out, its actually kind of hard to take an immutable object, vaporize it into a bunch of bits, and then reassemble those bits back into an immutable object on the other side. So I ended up with a bunch of objects that really, really wanted to be immutable but couldn't. Frustrating. Turns out that a "90% immutable object" just doesn't have the same feel to it.

Alright, so lesson learned (so I thought), moved on. Then I started working on a different project. Same type of deal, writing a bunch of new beans, want to make them immutable so I don't have to worry about whether or not that Person has a name. This time I'm working with JAX-WS, and again the serialization problem hits me right in the face. Ultimately I end up leaving my immutable beans alone, and writing a bunch of data transfer objects (similar to the immutable ones, but mutable). Then I could send those across and reassemble them into immutable versions on my own.

The saga continued when I made my way into JFace Data Binding. I had my Person with their name, age, height, weight, etc. I wanted to have a simple data entry form for a new Person. Problem is, with my immutable Person object, I basically have to set all those properties all at once, during construction. Stopped in my tracks again, since for data binding I basically need a standard Java bean with getters AND setters. Again I find myself writing intermediate objects which ultimately become their immutable counterparts.

The last part of the story came today, when I was poking around the p2 APIs. I was trying to see how the various properties of an IInstallableUnit got set. I find that there are no setters on the interface. Then I stumble across InstallableUnitDescription:

Once created, installable units are immutable. This description class allows a client to build up the state for an installable unit incrementally, and then finally product the resulting immutable unit.
A-ha! So I'm not the only one doing a bunch of intermediate stuff just to get to that final immutable object (pun intended).

So I put these question to you readers: How are you using immutable objects in your application? How about in your Eclipse applications? What lessons have you learned?

Friday, March 27, 2009

Thanks, EclipseCon '09

This was my first year at EclipseCon. It was great to put names to faces and mingle with the community.

Here are some things that I learned, in no particular order.

  • Choose Import-Package over Require-Bundle (I feel like I am a bit late to the game on that one, but appreciate being let in on the secret)
  • Someone is using RCP to monitor nuclear power plants in France.
  • Migrating a traditional enterprise application to OSGi is a hard problem.
  • I am running out of excuses not to use modeling tools.
  • I should scrap my homegrown explorer and use Common Navigator.
  • e4 is coming here. Start using it.

Aside from the technical learning, I felt the pulse of the community. And the message is this: contribute. Submit patches. Write bug reports. Participate in newsgroup discussions. Help wanted. I think this is a great message and frankly I'm overwhelmed by the number of areas that I want to contribute to. I think I need to submit a proposal to the wife to get more free time...

I liked the session voting. I wonder how we could make it paperless? Maybe touch your RFID badge to a +1/0/-1 monitor or something..

I hope I am able to come again next year.

What did you take away this year (aside from a fish)?

Tuesday, March 17, 2009

Keyboard shortcuts and accessibility in GEF

Here is a handy reference list of keyboard usage with a GraphicalViewer. Zoom in and zoom out actions must be implemented for those key bindings to work. For panning support, use a PanningSelectionTool.


















































































Navigate leftRight arrow
Navigate rightRight arrow
Navigate downDown arrow
Navigate upUp arrow
Navigate into a containerAlt+Down arrow with the container selected
Navigate out of a containerAlt+Up arrow
Cycle through selection handlesPress the period key with a part selected
Move a component

  1. Cycle once to the Move handle using the period key
  2. Use navigation keys to move
  3. Press Enter to accept new location
  4. Press Escape to cancel the move

Resize a component

  1. Cycle to desired resize handle using the period key
  2. Use navigation keys to resize
  3. Press Enter to accept new size
  4. Press Escape to cancel the resize

Select multiple

  1. Hold down Ctrl
  2. Use navigation keys to navigate to additional components
  3. Press Space to select additional components

Select in sequenceHold down Shift, use navigation keys to select additional components
Zoom InCtrl +
Zoom OutCtrl -
Select multiple w/ mouseHold down Ctrl and use the mouse to select components
Pan when zoomed inHold down Spacebar and drag the mouse

Monday, March 16, 2009

Favorites from 3.5M6

There are some goodies in 3.5M6. Here are a few of my favorites.
  • DataBinding support for the SWT DateTime widget. No doubt this will be useful. [169876]
  • DataBinding MultiValidator: Add support for dependencies other than those expressed by IObservables. We have run into this roadblock a few times and its good to see it has been lifted. [235859]
  • Copy/paste support for installed software list. Helpful for reporting issues. [227220]
  • Enable CTRL-mouse navigation for implementing classes. You know when Ctrl-Click takes you to the interface instead of the implementation? Now its smart. This is awesome. [44277]
  • New tracing API. Recently noticed we need debug level output in our product and this will be useful in implementing such a log. [258705]

Monday, February 23, 2009

p2 likes its 404s straight up

Setting up p2 to work with a repository that is behind HTTPS has been quite challenging. First I ran into this Java bug which was affecting ECF, the underlying transport for p2.

After moving past that problem, I was getting a lot of "No repository found at.." error messages, even though I knew damn well there was a repository hosted at the URL I was specifying.

After digging through the p2 code with the debugger turned on, I found the problem. You can deploy your repository metadata in two formats, compressed (JAR) or uncompressed (XML). When the repository manager goes out to a URL to look for the repository contents, it tries to find the JAR version first. If that fails with a 404, then it looks for the XML version.

I was deploying the XML version, and the fallback behavior wasn't working. It was pulling in an empty artifacts file, and trying to parse it, which of course failed. Turns out the web server was sending a 302 redirect with a user friendly page explaining that the page had moved. I found this by intentionally hitting a bad URL with Firefox, using Firebug to examine the response headers:



You can see that the 404 is coming AFTER the 302, which is too late. ECF was relying on the 404 to cause a FileNotFoundException, which translates into a known failure status in the p2 repository manager code, from which it can recover and try again with a different filename.

After tweaking the web server to return a 404 immediately, I was able to refresh the repository in the Software Updates dialog without any errors.

Sunday, February 22, 2009

First look at e4

I finally had some time to take a look at the first e4 Milestone. Download and install from here. New and Noteworthy here.

My main interest is in the declarative UI and CSS components. So I spun up the photo demo per Boris' instructions. It works and looks about what I would expect for the first milestone. I found the CSS file and tweaked it a bit, restarted, and saw my changes take effect. That was cool. Some thoughts on CSS in Eclipse:

  • Styling RCP apps can be left up to a designer. I wonder what the collaboration challenges will be like.
  • What does this mean for native widgets? Will people go hog wild and make their application so customized that it doesn't look like it fits in anymore? Ditto for plugins. I see a need for a whole host of new UI standards..
  • I wonder how well you can hot replace your CSS tweaks.
  • I haven't looked at Tk-UI (the CSS engine) much yet, but I wonder to what extent they support the CSS spec, and how much of that translates meaningfully into SWT constructs. First thing I'd be looking for is a mapping document.

Quick spin through the photo demo is complete. Lets look under the covers at the app itself. First class I look at is ExitHandler. Except, its not a handler. Or at least it doesn't extend AbstractHandler.. what's going on here? I can only guess: dependency injection. This will take some getting used to.

I also see an .xmi file. Quickly I can scan through it and see the structure of the entire user interface. I'm comparing this to the umpteen times I've had to follow that "parent" instance variable up the tree, to figure out where the heck a particular Composite lives, and what the structure is.

I can see already that I'm going to need Ctrl+Click to go from the .xmi file to the relevant classes. (Maybe I just need the appropriate EMF editor)

I have to wonder what newproject.js is. I can only think it is related to writing plug-ins in other languages. I see mention of Rhino as the toolkit. Perhaps the BIRT team can lend some expertise in this area.

I hope to get to the Resource model changes next time.