Aug 21

If Eclipse hangs when it tries to load your plug-in and if you see something like this in your error log:
thread "Thread [main,6,main]" timed out waiting (5000ms) for thread
"Thread [Worker-3,5,main]" to finish

then you’re probably interested in this post.

This is a somewhat known Eclipse bug and you can find more information about it here.
The problem is best described by Thomas Watson in Comment #4 in the Eclipse bug report.

The bottom line is that you should avoid doing heavy work in your plug-in start() method and instead defer the execution of any plug-in initialization code until you’re sure that the plug-in has been successfully resolved. Why? As Thomas points out, this ensures that the plug-in does not need to load any classes before it is initialized, which seems to be to root cause of the thread deadlock problem (one thread tries to initialized the plug-in and another thread tries to load a need class - but they both wait for the other to finish).

So to essentially dig yourself out of such a situation you need to listen for bundle event. To make this clearer, let’s look at an example. Let’s say your plug-in start() method looks something like this:

public void start(BundleContext context) throws Exception {
super.start(context);
myPluginInitialization();
}

If you’re trying to load classes from within your plug-in in myPluginInitialization(), then what you need to do is have your plug-in implement org.osgi.framework.SynchronousBundleListener, replace the myPluginInitialization() call from start() with context.addBundleListener(this), and implement the bundleChanged(BundleEvent event) method from SynchronousBundleListener as follows:

Bundle bundle = event.getBundle();
if (!bundle.equals(getBundle()))
return;
int type = event.getType();
switch (type) {
case BundleEvent.RESOLVED:
myPluginInitialization();
break;
}

Jul 26

In Eclipse plug-in development you may need a java.io.File reference to a file which resides in your plug-in distribution location.

For example, to get access to the following file

com.mycompany.myproduct/files/sample_data.xml

you might do the following:

File file = new File(FileLocator.toFileURL( FileLocator.find(MyPlugin.getDefault().getBundle(), new Path("/files/sample_data.xml"), null)).getFile() );

where MyPlugin is your plug-in activator

Jun 30

Eclipse class loading is not quite intuitive for the beginner Eclipse developer. If you’re a plug-in developer and if your application is comprised of two or more plug-ins you’ve likely encountered class loading issues. For example, if plug-in A contains a library say a.jar and plug-in B depends on plug-in A and needs to use a class found in a.jar, then that’s a likely situation to run into a plug-in class loading problem.

A simple way of fixing such an issue would be to pair the two plug-ins as “buddies”. Eclipse has uses a concept called Buddy Class Loading whereby a plug-in is allowed to load classes from its buddies. In our example above, plug-in A would require the following entry in its manifest file:

Eclipse-BuddyPolicy: registered

which essentially means that any plug-in that will register with plug-in A as a buddy, will be allowed to load classes from plug-in A. In our scenario then plug-in B would register with plug-in A with the following manifest entry:

Eclipse-RegisterBuddy: A

For more details on Eclipse class loading, here’s an article I like.