I created an Eclipse 4 application and I needed a jar
offering a functionality as part of my application (this could be anything e.g. log4j
to make it trivial).
I added the jar
as part of my project's classpath (Right Click->Configure Build Path
) but on runtime my service failed with a ClassNotFound
error (from OSGI I guess?).
Anyway searching this it turned out, at least as I have understand it, that I should add the jar as part of another Plugin
and create a dependency from my application/service to this new plugin.
I.e. I created a Plugin Project from Existing JAR archives
.
This time the setup worked.
So if I understand this, when developing for Eclipse/OSGi we should not add jars
in the classpaths directly but add them via plugins (why?).
Question: If I am correct so far, what is the standard practice to include jars
when developing a project?
Define/Create one Plugin Project from existing JAR archives
and add all the required third party libraries needed there, or have a different plugin project per needed jar
or something else perhaps???
Sorry if my terminology is not accurate. I am new in OSGi and Eclipse programming
Note: When talking about jars
I am not refering to other OSGi services. I am refering to the norm of using ready, reliable third party libraries that would be needed by many parts of an application. E.g. log4j
or an xml parsing library or apache commons
etc
The key difference with OSGi is that a JAR is now all private, adding metadata in the manifest makes it a bundle that can safely share with other bundles. OSGi makes sure violations are detected ahead of time.
Locate the JAR file to convert. If the file is in your Eclipse workspace, click Add. If the file is in a folder on your computer, click Add External and browse to the JAR file. Select the required file and click Open to add it in the Jar selection dialog.
For the runtime it is always the Manifest and the headers there that control what is in your bundle classpath. There are three ways to get access to a jar:
Import-Package header. This is the recommended way. You define one import per package you need. You jar you want to access has to be deployed in the runtime as a bundle. It also needs to export all needed packages.
Require-Bundle . This is another way to access bundles. You define the id of the bundle you need and see all packages it exports. As Require-Bundle binds you more closely to the other bundle the Import-Package way should be preferred.
Bundle-Classpath . This allows to add jars to your classpath that you embed into your own bundle. This should only be a last resort when the other way do not work. You can have nasty classloading issues when mixing this with the other methods.
You can find many pre built bundles in maven central. Many jars today already contain an OSGi manifest. For the cases where this is not true many jars are repackaged as bundles by servicemix. See groupId: org.apache.servicemix.bundles. There is also the spring bundle repository where you find some more.
Below I listed some resources you might want to read:
http://www.aqute.biz/Blog/2007-02-19
http://wiki.osgi.org/wiki/Import-Package
http://wiki.osgi.org/wiki/Require-Bundle
http://www.vogella.com/blog/2009/03/27/required-bundle-import-package/
Extactaly same problem we faced in our project. we have some legacy jar which are not OSGi compatible, we create lib folder parallel to BundleContent and added it into the classpath section of manifest.
Bundle-ClassPath: .,
/lib/<legacy jar>.jar
There is no need to exporting and importing of packages unnecessarily if only one bundle is going to consume it,
The examples you have mentioned are available as OSGi bundles, so you don't need to make them bundles yourself. You don't typically use direct jar dependencies in OSGi, you typically use package or bundle dependencies. In the log4j example you are referring to, you should use import package as there can be multiple bundle providers (newer log4j jar, springsource bundled version of older log4j, slf4j implementation...). This will disconnect your code dependencies from the actual provider.
These dependencies are maintained via you manifest, not your project classpath. In an eclipse plugin project, the projects build classpath is derived from the entries in the manifest.
Even though you are not using services, all code dependencies are still maintained via the manifest.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With