Eclipse's Team Project Set: Easier Collaboration

Eclipse has this feature Team Project Set which is rarely used. Really rarely I must say.

The point of Team Project Set is when you have many projects on your workspace that build the entire application. People often ask new developers to just check out each project from CVS/SVN. While this works, it is certainly not efficient. With Team Project Set, you will get the same result just by several mouse clicks.

To use Team Project Set, first you have to have a workspace fully configured for your application. Now, click anywhere the Package View and select Export. Select Team Project Set from the list. You should get this dialog window.

Now select the projects you want to include in the Team Project Set and click Next. Select the target file and click finish. Your job is done. Now you can share the project set file to the new developers.

In the new workspace, you can do the reversed step that you do before. Do Import and select Team Project Set.

The next step is self-explanatory, select the project set file you’ve created before and click finish. Depends on the size of your projects, the process will take time anywhere from couple of seconds until several hours. And there you go, the complete projects of your application configured with the SCM.

Limit Your Access to Java API for More Productivity

Simplify your work environment to get more jobs done. One example here is to limit your access to the Java API so you won’t be distracted by proposals that you don’t need.

RCP/SWT developers are facing this all the time. Point is a class in org.eclipse.swt.graphics, but it is also a class in java.awt. When you start to autocomplete, you will get at least two proposals of Point and alas, the Point from java.awt is usually put in the first place. The same with MouseListener. You will get at least one from java.awt.event and one from org.eclipse.swt.events.

You can solve the problem by limiting your access to Java API. To do this, you need to open the Build Path properties of your project.

Here you can double click the Access rules to get the Type Access Rules dialog.

Click Add… to add a rule. For the example I gave before, you may need to set rule to access type java/awt/** as forbidden. You can set many rules as you like and after that close the dialog.

Now if you try to get proposal for Point, you’ll get only the class from SWT and nothing from AWT. This will surely help you choose the right class that you intended.

Guava: Using CheckedFuture

In this post, I want to discuss another class from Google Guava. Today, it will be CheckedFuture. Let’s first see the JavaDoc of the class:

A CheckedFuture is an extension of Future that includes versions of the get methods that can throw a checked exception and allows listeners to be attached to the future. This makes it easier to create a future that executes logic which can throw an exception.

Implementations of this interface must adapt the exceptions thrown by Future#get(): CancellationException, ExecutionException and InterruptedException into the type specified by the E type parameter.

This interface also extends the ListenableFuture interface to allow listeners to be added. This allows the future to be used as a normal Future or as an asynchronous callback mechanism as needed. This allows multiple callbacks to be registered for a particular task, and the future will guarantee execution of all listeners when the task completes.

From this explanation, we can conclude two things about CheckedFuture:

  1. It extends ListenableFuture which has been discussed in this article.
  2. It aims to simplify exception management of Future.

Let’s look at code. Normally, if Future execution is cancelled because the inner-process throws exception, it will wrap the exception in a ExecutionException. So, our code will looks like something like this.

try {
	task.get();
} catch (ExecutionException e) {
	if (e.getCause()
			instanceof ApplicationException) {
		throw (ApplicationException) e.getCause();
	}
	throw new ApplicationException(e);
} catch (InterruptedException e) {
	throw new ApplicationException(e);
} catch (CancellationException e) {
	throw new ApplicationException(e);
}

A lazy programmer (don’t we all are lazy)? will write that like this:

try {
	task.get();
} catch (Exception e) {
	if (e.getCause()
			instanceof ApplicationException) {
		throw (ApplicationException) e.getCause();
	}
	throw new ApplicationException(e);
}

The same code can be implemented using CheckedFuture like this:

Function<Exception, ApplicationException> mapper =
	new Function<Exception, ApplicationException>() {

	@Override
	public ApplicationException apply(
			Exception from) {
		if (from.getCause() instanceof ApplicationException) {
			throw (ApplicationException) from.getCause();
		}
		throw new ApplicationException(from);
	}
};
CheckedFuture<String, ApplicationException> checkedTask =
	Futures.makeChecked(task, mapper);

checkedTask.checkedGet();

So I guess you’ll say: ‘but the code is longer than the original’. It’s true that in this example the code seems to be longer. In fact, if your case is so simple like this, I’ll suggest you to just use the original version.

This is pretty much same case of using functional-like Java coding style. It’s overkill if the case is so small. The advantage can only be seen once your code grows bigger.

In this CheckedFuture case, one example where using it will give you huge benefit is when you start sending the Future/CheckedFuture around and the get()/checkedGet() is executed in many places. That time, you’ll see that wrapping each call will try catch is annoying and this is where CheckedFuture-based solution will shine.