Plug-in Best Practices for RCP

Note: For those of you reading my posts on Planet Eclipse, you’ve probably noticed the titles have reverted to my WordPress user name. I’ve posted a Bugzilla entry about this, but if anyone has a clue what’s going on, I’d appreciate the help!

I just finished giving a talk at Eclipse World entitled Plug-in Best Practices for Rich Client Applications. For those who attended, and anyone else who’s interested, here is a summary list of the practices discusses. Feedback is obviously welcome and much appreciated.

Encapsulation

  • Design plug-ins to maximize encapsulation. Expose packages only when forced to.
  • Use a package structure that maximizes your ability to hide code.
  • Never mix public and private classes in the same package.
  • Consider incorporating the “internal” keyword into your package naming convention.

Cohesion and abstraction

  • Start thinking of plug-in contracts in addition to traditional class/type contracts.
  • Your plug-in should have a coherent API. In some cases, this can be composed of a set of factories that return a set of interfaces.
  • A plug-in should represent a coherent concept or subsystem.
  • A plug-in should do one thing and do it well.
  • Add a “New plug-in” refactoring to the list of design refactorings you look for.
  • Many fine-grained plug-ins should be preferred to a few large-grained ones. Don’t worry about plug-ins with a small number of classes.

Dual use code

  • If code is going to be used both inside and outside of an OSGi framework, make it into a plug-in. It’s still just a JAR!
  • If running plug-in code outside of an OSGi framework, remember that your encapsulation mechanisms will no longer be enforced at runtime. The “internal” keyword in package names can help here to inform non-OSGi developers that they should not access certain code.

Third party libraries

  • Third party libraries should always be distributed as separate plug-ins. Do not embed these libraries into plug-ins that also contain your own code.
  • When using third party libraries, look at repositories like Orbit to see if there is already a version packaged as a plug-in.
  • Move third party plug-ins out of your workspace and into your development and build targets.

Activators

  • Activators should be used strictly for lifecycle management. Do not let them become a dumping ground for factory methods.

Plug-in dependencies

  • Visualize plug-in dependencies as a stream, not as a hierarchy.
  • Use Require Bundle to declare dependencies when you want to hard code a dependency to a specific plug-in.
  • Use Import Package to declare dependencies when you want to allow multiple plug-ins to provide an implementation.
  • Minimize the coupling between plug-ins, just as you do with classes.
  • Use extension points and OSGi services to help minimize coupling.
  • Avoid reexporting dependencies unless the exporting plug-in represents a coherent API. Unnecessary reexporting leads to dependency leaks and makes issues like circular dependencies hard to track down.

RCP-related

  • Always create development and build targets for your application. Version those targets.
  • Place RCP product definitions (Application, advisors and branding) in separate plug-ins, Do not mix products into your other code.
  • Use features to wrap your plug-ins and simplify your product configurations.
  • Place unit tests in a separate plug-in or, better yet, a plug-in fragment.
Advertisements

4 Responses to Plug-in Best Practices for RCP

  1. vainqueur says:

    In my Activators, I usually start service trackers & also register OSGi services (& place these services into singletons). What is your position on the use of singletons in an eclipse RCP ?

  2. Patrick says:

    I do have singletons in my RCP applications, and find them useful. There may be situations where singletons cause problems, particularly if you’d like to reuse your plug-ins in a Rich Ajax Platform application or in a server-side OSGi application.

    If there are any specific concerns or problems you’ve had with singletons in RCP application, I’d be interested in hearing them.

  3. Lex Robin says:

    IMHO singletons are a no-go. Our projects used them a long time because it was so easy to add functionality anywhere. After I had to refactor our (non-RCP) code and introduce a constructor parameter for singletons, the only problems were singletons. Some could be removed easily, others really hard. My conclusion: avoid singletons where possible. Always try to find another way, e.g. by creating an instance at application startup. First, you see what code requires the instance – second, you avoid such major problems we had with the refactoring our singletons.

    Now to RCP (I’m a RCP beginner):
    Unfortunately, I did not found a way how to pass a instance reference from my IApplication to my views. The latter are simply created using “magic”, there is no way to pass needed references in the constructor.

  4. Patrick says:

    Hi Lex,

    Yeah, singletons are now something of an anti-pattern and I agree that their use should be limited. But as you say, eliminating singletons can cause problems when you’d like to access a “global” instance deep down in the framework.

    There are a few solutions to this.

    * Make the instance available via a factory class or something like a singleton registry (which itself would need to be a singleton). This solves many of the problems associated with singletons, but isn’t the cleanest approach.

    * A better solution may be to simply create OSGi services for these classes. This provides you a lot of flexibility in how and where your instances are created. It’s true that the view has to reach out and pick up the service, but in a modular framework like the RCP this is hard to get away from.

    * There is also a way to add proprietary (non-OSGi) services. Check out the documentation for the org.eclipse.ui.services extension point for more info. Services added through this extension point would be available globally via the PlatformUI.getWorkbench().getService() method.

    There have been rumblings about adding dependency injection to the RCP framework as part of the e4 project, but I’m not sure what the exact plan is. Check out this page for more info:

    http://wiki.eclipse.org/E4/Architectural_Foundations

    Hope this helps,

    — Patrick

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: