Eclipse from the bottom up

The view of the Eclipse world from the bottom of the stack

Tuesday, May 23, 2006

SSH2 Support in Eclipse

One of the things that has happened in Eclipse 3.2 is that the SSH2 client used by CVS has become a separate plug-in: com.jcraft.jsch. The Jsch library has been used since 3.0 for the SSH2 connection (extssh) support and is now also used to provide proxy support for pserver connections. In order to make the Jsch library accessible to the Core CVS plug-in, we needed to move it out of the extssh plug-in and into a separate plug-in. As a result of this, other plug-ins in Eclipse 3.2 can now make use of the Jsch library to make SSH2 connections.

It was a patch provided by Eugene Kuleshov to add the pserver proxy support that was the catalyst that resulted in the split. Atsuhiko Yamanaka from JCraft also played an active role in making this happen (Jcraft has also just posted an SFTP plugin on their website that makes use of the Jsch plugin to provide SFTP file transfers). I think this is a great example of how community members have worked together to make Eclipse better.

Common Navigator and the Synchronize view

Thanks to Chris, I saw Michael's Common Navigator post over the weekend. The framework is new in Eclipse 3.2 and there have been a number of questions about it on the eclipse-platform newsgroup already. Michael gives a pretty thourough description of the features of the framework. I would encourage anyone who provides a tree-based view of their model in Eclipse to check it out.

As it turns out, the new model-based synchronization support that was added in Eclipse 3.2 makes use of the Common Navigator framework to allow models like Java to appear in the Synchronize view. Here's a screenshot that shows our Team Example model, a Java model and the Resource model all in the same CVS synchronization.

For those that are curious, the Team Example model is available in the plugin which you can get from the repository or in the RC5 or later Eclipse Platform Example plug-ins download. The purpose of the example is to illustrate how to integrate logical models like Java with Team providers like CVS and includes Common Navigator extensions for both the Project Explorer and the Synchronize view. The RC5 version of the example is in reasonable shape but the version in HEAD is more complete.

Monday, May 01, 2006

Don't speak until spoken too

As the 3.2 release date approaches, I thought that it would be a good time to install Callisto. We're performing an RC2 2-day test pass on the Platform so I didn't really plan on digging too deeply into the features of Callisto right away but I thought it may add a bit of variety to the test pass to have some new stuff to look at. It turns out that even just having Callisto installed while doing my Platform testing was a useful exercise and here is why.

I had several plugin projects in my workspace and needed to close a few. Upon doing so, I got an exception from a validator that was trying to write out some project preferences. There were two problems with this. Firstly, the validator should not have been writing the preferences out during the project close delta (hence the exception). However, the larger problem is that I was doing plugin developement and the validator that was writing out the preferences had nothing to do with developing plugins.

There's been a lot of talk about Eclipse and Callisto as a Platform. An important aspect of this is how invisible a component is if it is present in an install but is not being used. We've really felt this with the Eclipse CVS client since it is part of the SDK but is not of interest to all users of Eclipse. One can think of Callisto as a mega-SDK so the same rules apply. However, we developers become so focused on improving the feature set of our components, that it is hard to adequately test how well our component behaves when it is not being used.

So, if you would like to help out testing for Callisto but you only use a small subset of the features, it is still worthwhile to install the whole thing. Then you can help tests the parts you care about and also help to ensure that the parts you aren't using remain silent.

Image Management

Just to follow up on what Tod mentioned in his blog about image management, the ResourceManager and ImageRegistry classes are not just about maqnaging the lifecycle of an image, they're also about how images can be shared. I thought it would be worthwhile to give a brief description of each of these classes.

ResourceManager: A resource manager can be used to keep track of a set of created Images. The client of this class is still responsible for creating and disposing of images but creation and disposal is done by calling the createImage(ImageDescriptor) and destryImage(ImageDescriptor) methods on ResourceManager. The obvious question is why would you want to use a resource manager if you still need to dispose of the image at some point. The reason is that the resource manager will ensure that, for a particular descriptor, the image is only created once, thus saving precious OS resources. The manager uses reference counting to ensure that the image is only disposed when it has been destroyed the same number of times it has been created.

So the advantage of using a resource manager is that you can reuse images but the disadvantage is that you still need to dispose of the images when you are done with them. However, disposal can be simplified somewhat by using a LocalResourceManager. Let's say I have a set of images that need to be available while a particular viewer is opened but can be disposed when the viewer is closed. I can create a LocalResourceManager that wraps the JFace resource manager (JFaceResource.getResources()) and use it to create any images I need. I can add a dispose listener to the control of the viewer that will dispose of the manager when the viewer is closed. This way, I don't need to ensure that I match each create with a dispose. I can just happily call create when I need an image, knowing that the manager will never create the same image twice and will dispose of them all when I call dispose on the manager.

There is another advantage of managing images this way. The image created from a LocalResourceManager for a particular descriptor is also pushed up to the parent manager(e.g. the JFace resource manager). This means that the image is accessible through the parent manager or through other local managers that share the same parent. This means that at most one image is created for a particular descriptor but the image will be disposed when it is no longer used anywhere.

ImageRegistry: An ImageRegistry wraps a ResourceManager and allows image descriptors and images to be referenced by a key of type String. Also, when creating an image registry, you can populate it with image descriptors and the registry will only create the corresponding image the first time it is referenced. Because an ImageRegistry wraps a ResourceManager, you get all those benefits as well. As with a ResourceManager, an ImageRegistry needs to be disposed of when the images in the registry are no longer needed and disposing a registry will free all the images in its resource manager if they are not used by another manager.

However, as Tod pointed out, one must be careful when adding images to either the JFace image registry (JFaceResources.getImageRegistry()) or the image registry of a plugin (AbstractUIPlugin#getImageRegistry()) since both of these registries are only disposed when the workbench is closed. I think a better approach would be to create ImageRegistries that are local to views and editors and have these registries wrap LocalResourceManagers so that the created images are shared when possible but are disposed when no longer in use.

Disclaimer: I started out as a Core level guy who has been thrust into this UI level stuff. It turns out that most of the image mangement code I've written up until this point has been done using a HashMap. I just recently stumbled on this API when fixing an image disposal problem. Given that 3.2 development on the Platform is pretty much frozen at this point, I'll need to wait until 3.3 before I can put this into practice (i.e. treat the above as ideas and discussion points instead of the carved-in-stone way to do image management).

Yet another blog about Eclipse

Now that I'm a committer on Platform/UI as well as Team/CVS, I figured it would be worthwhile to start a blog to capture some of the things I come across while developing and maintaining these components.