9

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

Cratylus
  • 52,998
  • 69
  • 209
  • 339
  • What's your ultimate goal: Do you want to create a deliverable for "your" project, say a jar/zip which has all needed classes/jars/resources to run your program? – Kashyap Sep 24 '12 at 16:57
  • @thekashyap:Not sure I understand your question.The exported product is predefined by the `.product` configuration, right?So my concern is how the project should be setup so that in the deployment I know that all the required jars are available. – Cratylus Sep 24 '12 at 17:04
  • Check out: http://www.vogella.com/articles/OSGi/article.html and http://www.coderanch.com/t/104274/vc/Order-Export-tab-Java-Build – Kashyap Sep 24 '12 at 17:10
  • my bad.. didn't read "OSGi" anywhere in your question.. :-).. checkout the link I posted, it describes the "bundles" concept.. given teh OSGi architecture my guess would be that you should have all the basic services available as existing bundles. – Kashyap Sep 24 '12 at 17:12

3 Answers3

5

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:

  1. 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.

  2. 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.

  3. 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/

Christian Schneider
  • 19,420
  • 2
  • 39
  • 64
  • For case (1) if I need to create a bundle for needed jars, should I put *all* the jars needed in this one bundle (in case I need more than one) **or** each jar should be in each own bundle? – Cratylus Sep 25 '12 at 20:18
  • I think the best way to make bundles from jars is to just add the Manifest entries. So each jar will be its own bundle. This has the advantage that your maven depdendency structure matches the bundles. Btw. if you have to create bundles take a look at bnd and the maven bundle plugin. – Christian Schneider Sep 26 '12 at 05:56
3

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.

Robin
  • 24,062
  • 5
  • 49
  • 58
  • But if I use the `import package` that means that the `jar` is somewhere in the `OSGi` container on deployment right?So how do I know which jars are already available?E.g. how would I know that `log4j` is already offered? And how would I use `apache commons`?Is that also already included?How is this possible? – Cratylus Sep 24 '12 at 17:17
  • Also I mean there are cases that I would need some jar not already offered as bundle, right? – Cratylus Sep 24 '12 at 17:20
  • Deployment of bundles for an application is implementation specific. In eclipse, your target platform determines what bundles are available. As for non bundled jars, you can simply create bundles for them with eclipse by creating a new plugin project form existing jar. You could also include it within the bundle, but I prefer the bundle approach. – Robin Sep 25 '12 at 16:54
  • Yes this comes back to my original question.If I create a new plugin project from existing jar as you point out, should I include **all** my needed jars in that project **or** create a different bundle project for *each* jar needed? – Cratylus Sep 25 '12 at 20:15
  • I always go with the bundle per jar as it keeps things nicely componentized, which is what OSGi is all about. It gets kind of ugly if one bundle is exporting unrelated packages, not to mention the fact that each of those jars will have it's own version, but the bundle will only have a single version. – Robin Sep 26 '12 at 13:39
  • `The examples you have mentioned are available as OSGi bundles`.I can not seem to find `org.apache.log4j` as part of Indigo's Imported Packages.Why is this?Do you mean something different here? – Cratylus Sep 30 '12 at 08:16
  • I opened a separate thread for this: http://stackoverflow.com/questions/12660074/proper-way-to-include-log4j-in-an-eclipse-4-rcp-swt-osgi-application – Cratylus Sep 30 '12 at 15:14
3

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,

sailor
  • 753
  • 1
  • 6
  • 17
  • 2
    +1 This bundle stuff is adding an unbearable overhead, especially when developing the JAR and the Eclipse plugin in parallel. Annoying, and at every iteration, it consumes time, kicks off you form the flow... I **vigorously hate Eclipse** for shunning Maven form the plugin development process. Yeah, there is Tycho, but I'd rather smack my own head with my freshly severed arm I just bit off my own shoulder until I feel comfortable than use that cryptic, undocumented band aid designed for the gaping septic wound that is Eclipse plugin legacy JAR dependency usage. Agile, NOT! – ppeterka Nov 08 '14 at 11:52