How can I combine our bundles with third party libraries into one large bundle for others use? - eclipse

There is more than one bundles in our project when we develop RCP product.
We could have one bundle maybe named common-xxx that would provide some utils method for other bundle using it.
I want to add some 3rd party jars (such as Apache or log4j etc ) into this common-xxx bundle and therefore others should use its API.
How can I do this?

In the MANIFEST.MF editor put your jars in the plugin 'Classpath' (on the 'Runtime' tab) - this will add the jars to the manifest Bundle-ClassPath.
Then add the packages you want the plugin to export the the Exported Packages (also on the 'Runtime' tab). This will add the packages to the Export-Package entry in the manifest.
With these two entries the jar packages will be available to other plugins which have your plugin as a dependency.

Related

Exporting an Eclipse plugin with a dependency on an external jar

Just recently started using Eclipse and ran into an issue with exporting the plugin I'm working on. I tried to search but so far no luck - but if the answer is already here I'd be grateful if someone can point me to it.
I'm writing a n OSGi/Equinox plugin with Eclipse. The plugin is for a 3rd party system, which allows extensions: basically all jars placed in the application's plugin folder are automatically loaded into the application at startup. I have managed to put together my plugin, it's loading fine and it works.
The issue is that I rely on another plugin which is placed beside mine in the plugins folder. For obvious reasons I do not want to package that plugin into my plugin jar file. I have tried to add the dependency as an external archive, but this breaks the export: when I try to export my plugin project ant complains about missing dependencies and types. (If I actually include the other jar file in my plugin everything works, but obviously this is less then ideal.)
So: how do I set up my plugin project dependency, that it's a) an external dependency and b) doesn't need to be specified with a path or a variable - i.e. how do I tell my exporter to "don't worry, it will be there right beside you"?
Edit: Apparently there's an important detail I didn't mention. The external jar file I depend on is not an OSGi plugin, just a regular jar file with some classes in it. To the 3rd party system it seems all the same (all are under the plugins folder, all are loaded into the application), but for Eclipse the distinction seems important.
If you reference the other plug-in as a dependency in your plug-in's MANIFEST.MF the export should work without errors. The plug-in should be listed in the Require-Bundle list in the MANIFEST.MF.
You can do this in the MANIFEST.MF editor by adding to the 'Required Plug-ins' list on the 'Dependencies' tab of the editor.
Note: When referencing other plug-ins you must always use this method. Do not try adding the plug-in jar to the Java build path or anything like that.
If the jar you want to use is not an Eclipse plug-in you must should include it as part of the plug-in and list the jar in the Bundle-Classpath in the MANIFEST.MF. If you cannot do this you can reference an external jar in the Bundle-Classpath using something like:
Bundle-Classpath: .,external:$LIB_LOCATION$/lib.jar
. is the normal entry in for the plug-in code. external:$LIB_LOCATION$/lib.jar looks for lib.jar in a location defined by the environment variable LIB_LOCATION. This method can be difficult to get right.
In the end the solution to my specific problem was to add the external jar file as an Extra Classpath Entry on the build properties tab (this translated to a "jars.extra.classpath = .jar" entry in the build.properties file). I have also added the jar file to the project itself - after adding the extra class path entry that got changed into an external dependency automatically.
With these two changes I was able to successfully export my plugin, which didn't contain the external jar file, but was able to reference it when loaded into the 3rd party system.

Eclipse RCP plugin dependencies

I am trying to generate an RCP product from a set of Eclipse plugin. When I am trying to run the Eclipse plugin from my Eclipse.rcp.product plugin, Eclipse is asking me to add all the dependent plugins. I have done that.
However, on adding a new plugin, it starts asking for dependencies (e.g., third party libraries from Eclipse's Orbit repo) of that plugin too. All the dependencies of individual plugins are referenced in those plugins.
Why do I have to add all the references again in the RCP plugin. What is the way around or right way?
The xxx.product file must list every plugin that your RCP is going to use as this list determines what is included in the resulting product.
This is a separate list from the individual plugin dependencies.
The Dependencies tab of the .product file editor has an 'Add Required' button which should add everything that is needed (assuming you have already added all your plugins).
You can also use 'features' rather than 'plugins' for the product file which reduces the number of things that need to be included in the dependencies.

The best practice to use Tycho/Maven to remove jars dependencies in Eclipse RCP?

I'm working one an Eclipse RCP project. Currently we create a dependencies plug-in project and put all jars libraries into that project and export all packages. This method will give a huge repo, thus we want to use Tycho/Maven and let it figure out the dependencies for us.
The first approach is removing dependenciec project and use p2-maven-pluging to transform existing jars libraries to p2 format repo. Install all libraries from p2 repos and add required bundle in Require-Bundle section in each MANIFEST.MF. This is a little bit tedious since in every project having dependencies in Require-Bundle, I have to manually replace it to corresponding bundle names. And in the end, the project build using Tycho could successfully run, but in Eclipse it gives me java.lan.NoClassDefFoundError: Could not initialize class X.
I think there are few configuration files, where Tycho depends on some of them and Eclipse depends on the rest, but I'm not sure what it is.
The second approach is removing all jars in dependencies project but adding them in Require-Bundle or Import-Package. However, both won't work since in Export-Package section Eclipse will complain these packages are not existed. Thus other projects depends on this dependencies project won't find those packages they need, which causing more errors in Eclipse.
Does anyone know the best practice to deal with this issue?
Update:
I'm using basically the first approach, but add dependencies in Import-Package in each project instead of Require-Bundle. This would eliminate the need to specify the specific bundle version, as long as they provide the same API and they are compatible, your application would work. So everytimes I update private p2 repository, I don't need to change MANIFEST.MF in each project.
The only MANIFEST.MF I need to manually add dependencies in Require-Bundle is a library developed by our self. Without it, Tycho won't fetch required dependencies from private p2 repository. If still get NoClassDefFoundError, try adding all plugins in Run -> Run Configuration .. -> plug-ins, it may help.
I definitely not apply your approach 1, with the mega-plugin of exports. There's a related discussion here: Handling non-OSGi dependencies when integrating Maven, Tycho and Eclipse
As a rule, use Import-Package instead of Require-Bundle.
To get bundles will appear in the Export-Package section Eclipse:
if they are non-Eclipse (maven libraries), then build the project and reference the libraries in the Eclipse runtime section.
if they are Eclipse dependences, they should be in your workspace or Target Platform.
More generally, it may help for you to define a Target Platform. You can build/deploy all of your locally created plugins into a local p2 repository (see http://www.sonatype.org/nexus/). Then add that p2 site to your Target Platform.

Add 3rd party library to an eclipse plugin

What is the right way to include an additional JAR file in an Eclipse plugin? My own plugin requires apache-commons-io. I copied the JAR into my plugins directory and added it via the "Dependencies" tab of the plugin manifest. This works for me, but other users of my plugins will have to download Commons-IO manually.
What is the correct way to package Commons-IO in my plugin?
I usually use the following strategy:
If I can find the JAR in question packaged as a bundle - i.e. the MANIFEST.MF contains the correct entries - then I use this. Have a look at the Orbit project for a set of pre-packaged bundles of all sorts. org.apache.commons.io is already here...
If that is not possible, then I just include the JAR in my bundle, and updates MANIFEST.MF - e.g. Bundle-ClassPath: library.jar,.
Sometimes it is cleaner to create a unique plugin for libraries.
(So you can use it from several plugins, License topics, Size of your Plug-In, different version, ...)
Do so by "New ..."
Category: "Plug-In Development"
then "Plug-In from existing jar archieve"
Select your jars and there you go.

How can I add the external jar to the eclipse rcp application?

I tried to add the apache vfs jar file as the runtime dependency. Even though it throws the below error:
java.lang.ClassNotFoundException: org.apache.commons.vfs.VFS
at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:489)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:405)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:393)
at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:105)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
at file_explorer.View.setInput(View.java:295)
at file_explorer.View.initialize(View.java:130)
How can i resolve this, thanks in advance.
If you are looking for adding the required jars to your project classpath.Add the required files to lib directory in the project structure.Then from project click the 'run time' tab of plugin.xml and add the required jars from the lib directory to the project classpath.
The best way to include external Jar in Eclipse RCP application is to package it as a plugin and then use classic plugin dependency.
Just create a new plugin containing only your Jar. Then in the build tab of the manifest editor, add your jar to the classpath (at the bottom right) and export all its packages in this same runtime tab. Also be sure to check that you jar is checked in the Build tab.
Nevertheless you should be able to use the jar in a Given plugin source code if you only add it to the classpath as I mentioned previously.
Because some other of your plugins may be interested in using the vfs jar and for separtion of concerns matter I think you should wrap it in its own plugin
The easiest way is to find bundle in an existing OSGI bundle repository.
http://bundles.osgi.org/Main/Repository
http://www.springsource.com/repository/app/
http://www.eclipse.org/orbit/
http://www.knopflerfish.org/repo/index.html
springsource repo contains apache VFS bundle
Then you need to add the bundle to the target platform (or just copy it to the dropins folder)
In order to properly install bundle into a newer version of eclipse you should use an existing p2 repository and install bundle from p2 repository into your runtime platform. There are two ways: you could use existing one (like orbit p2 repo), or you could create your own using p2 publisher as described at https://docs.sonatype.org/display/TYCHO/How+to+make+existing+OSGi+bundles+consumable+by+Tycho
Eclipse RCP is an OSGi environment which extends the Java dependency model, so you can't simply take a jar file and hope it works. To use an external jar, you have to build it to a plugin first, which p2-maven-plugin can help, you can follow the readme document.
With the plugin ready, you should install the plugin and add it to MANIFEST.MF. Then restart Eclipse to make the plugin work.
A more easily way, you needn't install the plugin, just follow(but build the jar):
go to plugin.xml -> Runtime tab;
click Add at the classpath section, then add the plugin to classpath;
make sure there is . path in the text area, otherwise New it.