2007-01-09

Adding a third party JAR to your Eclipse plugin

I often get the question "How to add a third party JAR-file to my Eclipse plugin". It is not that tricky, but neither that obvious. Two solutions has been posted on the Eclipse newslists, but it can be quite hard to find it as the sheer number of posts is overhelming.

Here is two ways of doing it:
1. Turn the JAR-file(s) into plugin(s)
This is probably the simplest solution, but maybe not always achieving the desired granularity though. "Use New" -> "Project" -> "Plug-in Development" -> "Plug-in from existing JAR Archive". That will turn the JAR-file into a single JAR-plugin. Check that all required packages are re-exported.

2. Include the JAR-file(s) in the plugin in question:

  • Use the "Import" -> "File System" to import the JAR-file(s) into your plugin project. E.g. '/lib' directory

  • Then use "Add..." to add the JAR-file(s) to the classpath section of the Manifest/plugin.xml runtime tab.

  • Press "New..." to add "." library back to the the classpath (without quotes).

  • Check that the binary build exports the new JAR-file(s) on the Build tab.

  • Press save, important for the changes to come through.

  • Select the project in question in the package explorer view, right click and select "PDE Tools" -> "Update classpath". This will add the newly added JAR-file(s) to the project´s classpath.
When you are in the process of exporting the plugin make shure you do not package the plugin as "individual JAR archives", Eclipse cannot load JARs from within JARs, yet.

13 comments:

Krzysztof (Chris) Daniel said...

thanks!

Satya said...

Nice post thanks

Blogger said...

Hi Robert! If i need to add library to my plugin class path at runtime, add some jar and load classes from him. Is there a mechanism to do this over eclipse tools. maybe some extension point that provide me such possibilities ? Thanks

padawan said...

I hope you read this :) I'm a total begginer to plug-in developement, and i was completely lost after searching in the hews groups of eclipse... until I read this, now my application works!
Thanks a lot!

R. Varttinen said...

Glad it was of some help. I'll check the dynamic possibilities and post back here.

Well, the most obvious one just on top of my head would be to make use of a bundle fragment - but I'll study it a bit more and try something out and post it back her...eventually..

Vipul Bahuguna said...

Hi Robert,

First of all thanks as this article really helped me to start with my plugin project.

I am still facing some problem which I am not able to figure out.

I did whatever you explained in the article and then I was able to run my plugin with dependent jars.

But then i included a set of jar files which my code needs and I am getting the exception pasted below.
The class it is not able to find is already present in this jar file:
lib/commons-digester-1.8.jar


I am not able to understand this because my manifest seems to be fine as follows:
===================================
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: BOInspector Plug-in
Bundle-SymbolicName: BOInspector; singleton:=true
Bundle-Version: 1.0.0
Bundle-Activator: boinspector.Activator
Bundle-Vendor: Vipul Bahuguna
Require-Bundle: org.eclipse.ui,
org.eclipse.core.runtime,
org.eclipse.core.resources
Eclipse-LazyStart: false
Bundle-ClassPath: .,
lib/commons-beanutils.jar,
lib/commons-beanutils-bean-collections.jar,
lib/commons-beanutils-core.jar,
lib/commons-digester-1.8.jar,
lib/commons-logging-1.1.jar,
lib/commons-logging-adapters-1.1.jar,
lib/commons-logging-api-1.1.jar

===================================


===================================org.eclipse.core.runtime.internal.adaptor.EclipseLazyStarter$TerminatingClassNotFoundException: An error occurred while automatically activating bundle BOInspector (168).
at org.eclipse.core.runtime.internal.adaptor.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:125)
at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClass(ClasspathManager.java:417)
at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.findLocalClass(DefaultClassLoader.java:189)
at org.eclipse.osgi.framework.internal.core.BundleLoader.findLocalClass(BundleLoader.java:340)
at org.eclipse.osgi.framework.internal.core.BundleLoader.findClassInternal(BundleLoader.java:408)
at org.eclipse.osgi.framework.internal.core.BundleLoader.findClass(BundleLoader.java:369)
at org.eclipse.osgi.framework.internal.core.BundleLoader.findClass(BundleLoader.java:357)
at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:83)
at java.lang.ClassLoader.loadClass(Unknown Source)
at org.eclipse.osgi.framework.internal.core.BundleLoader.loadClass(BundleLoader.java:289)
at org.eclipse.osgi.framework.internal.core.BundleHost.loadClass(BundleHost.java:227)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.loadClass(AbstractBundle.java:1269)
at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:160)
at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:788)
at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243)
at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:51)
at org.eclipse.ui.internal.WorkbenchPlugin$1.run(WorkbenchPlugin.java:252)
at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:67)
at org.eclipse.ui.internal.WorkbenchPlugin.createExtension(WorkbenchPlugin.java:248)
at org.eclipse.ui.internal.PluginAction.createDelegate(PluginAction.java:122)
at org.eclipse.ui.internal.PluginAction.runWithEvent(PluginAction.java:228)
at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:546)
at org.eclipse.jface.action.ActionContributionItem.access$2(ActionContributionItem.java:490)
at org.eclipse.jface.action.ActionContributionItem$5.handleEvent(ActionContributionItem.java:402)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:66)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:938)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3682)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3293)
at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2389)
at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2353)
at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2219)
at org.eclipse.ui.internal.Workbench$4.run(Workbench.java:466)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:289)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:461)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:106)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:169)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:106)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:76)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:363)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:176)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:508)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:447)
at org.eclipse.equinox.launcher.Main.run(Main.java:1173)
Caused by: org.osgi.framework.BundleException: The activator boinspector.Activator for bundle BOInspector is invalid
at org.eclipse.osgi.framework.internal.core.AbstractBundle.loadBundleActivator(AbstractBundle.java:141)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.start(BundleContextImpl.java:970)
at org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:346)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:260)
at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:400)
at org.eclipse.core.runtime.internal.adaptor.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:111)
... 47 more
Caused by: java.lang.NoClassDefFoundError: org/apache/commons/digester/Digester
at com.amdocs.core.SchemaExplorer.prepareDigester(SchemaExplorer.java:72)
at com.amdocs.core.SchemaExplorer.init(SchemaExplorer.java:47)
at boinspector.Activator.init(Activator.java:28)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at java.lang.Class.newInstance0(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.loadBundleActivator(AbstractBundle.java:136)
... 52 more
Caused by: java.lang.ClassNotFoundException: org.apache.commons.digester.Digester
at java.lang.ClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at org.eclipse.osgi.framework.internal.core.BundleLoader.findClassInternal(BundleLoader.java:429)
at org.eclipse.osgi.framework.internal.core.BundleLoader.findClass(BundleLoader.java:369)
at org.eclipse.osgi.framework.internal.core.BundleLoader.findClass(BundleLoader.java:357)
at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:83)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClassInternal(Unknown Source)
... 62 more
===================================

Vipul Bahuguna said...

I will try to identify what went wrong. If anyone has any suggestions as to why the java.lang.ClassNotFoundException is coming, please do reply.

Thanks in Advance.

R. Varttinen said...

Time permitting I'll check the stacktrace during the weekend.

And... thank you all for your comments! Really appreciated!

Vipul Bahuguna said...

Hey Robert,

Thanks for taking out time.
The problem is resolved. I was probably making mistake and not updating the classpath properly. I again made te project and followed steps. It worked.

R. Varttinen said...

Vipul,
Good news that the issue is resolved. I was about to ask whether you had updated the classpath or not, using the PDE menu helps in most cases.

NoName said...

I have followed your instructions, but then I go File -> Export -> Plug-in Development -> Deployable plug-ins and fragments and I get the following error

Problems during export
/home/xxxx/workspace/.metadata/.plugins/org.eclipse.pde.core/temp/org.eclipse.pde.container.feature/build.xml:29: The following error occurred while executing this line:
/home/xxxxxxx/workspace/.metadata/.plugins/org.eclipse.pde.core/temp/org.eclipse.pde.container.feature/build.xml:10: The following error occurred while executing this line:
/home/xxxxxxx/workspace/thesis/build.xml:368: The following error occurred while executing this line:
/home/xxxxxxxxx/workspace/thesis/build.xml:321: IO error scanning directory '/.links'

The build.xml mentioned is not mine. Any ideas?

Anonymous said...
This comment has been removed by a blog administrator.
Unknown said...

Thanks - that last bit about PDE Tools -> Update Classpath is not obvious and never occured to me!