Eclipse: How to include dependencies in osgi bundle export? - maven

Using Eclipse, I have a (sort of) working OSGI bundle. It uses Maven to pull a lot of dependencies.
If I do right-click > Run As "Maven Build" and select the "package" as the goal, I end up with a jar with all my dependencies (good), but if I do "Export > OSGI Bundle" the dependencies are missing.
The issue is that I have another project (WebSphere Liberty Feature Project) that includes the bundle, but when it pulls it, it is also missing dependencies, so the resulting .esa file also misses the dependencies.
Is there a way to have eclipse process the dependencies so I don't have to manually package it outside eclipse or write a maven project exclusively for the purpose?
Thank you!

I was having the same issue when I came across your post.
I assumed that the jars would be included in the exported jar and be found at runtime.
Originally, I had created a seperate "lib" directory and added the libraries to it, but they would not be included when exporting either as Bundle export or Liberty feature export (ESA)
I solved the problem first be using the "Java Archive into OSGi Bundle" import wizard.
You can select a jar dependency and add it to you bundle of your choice with the wizard. What I noticed when I used this, is that the jars were added to the "BundleContent" folder in the chosen bundle.
As I had a number of libraries to include, I simply moved them all to the "BundleContent" folder, updated the build time and runtime classpaths and then when exporting, the dependencies were all included and at runtime, the classes could then be found when they previously were not.

In your POM, have you used maven-bundle-plugin and its usage-details for creating a bundle. If not, you can use it to define creation of your bundle and can also define dependencies to be embedded when the bundle is created.

Related

maven-bundle-plugin include non existing dependencies

I have a stange problem with the "maven-bundle-plugin" in a Eclipse Plugin Project.
When I compile the project, i see on the Manifest.xml, on the "Import-Package" section a lot of java packages imports for a lot of packages that doesn't exists on my classpath, for Example:
Import-Package:
COM.newmonics.PercClassLoader,
android.os,
bitronix.tm,
bitronix.tm.jndi,
bitronix.tm.resource.common,
bitronix.tm.resource.jdbc,
bitronix.tm.resource.jms,
bsh,
com.arjuna.ats.arjuna.common,
com.arjuna.ats.arjuna.recovery,
com.arjuna.ats.internal.jdbc,
com.arjuna.ats.internal.jta.recovery.arjunacore,
com.arjuna.ats.jbossatx.jta,
All of this packages don't exists on my project or in my dependencies, but maven-bundle-plugin add it to the Manifest, and I have no idea why. Any idea or suggestion? Thanks.
The bundle plugin generates Import-Package for the packages that are referred to by your project. These are the packages that should be exported by other bundles, so that your bundle can use them runtime. My first guess is that your classes refer to these packages, so check your source code first.
If your project really doesn't refer to those packages, please check if your pom.xml has specified these packages in an <Import-Package> directive in the plugin configuration. Perhaps it was copy/pasted from another project?
It could also be that you have embedded dependencies in your bundle jar that refer to the packages. To find out, you can unpack your jar (e.g. using the rjar tool) and grep the class files recursively for e.g. bitronix/tm.

Why third party dependency is required exclusively from OSGi container even if I have it in my maven dependencies?

I want to know why OSGi do not respect the maven dependenceis.
I want to create one app in OSGi(AEM). I want to communicate(CRUD) to the database with the help of JPA(eclipselink).
I created maven project with aem-archetype.
Added all required dependencies(of JPA) into my maven project's pom file.
No errors in Eclipse, I built the project via mvn clean install and installed it into AEM(CQ5) via mvn sling:install. All good till now. No Errors.
But when I go and see my bundle in the felix console, I see that it is not Active but in Installed state.The error reported is that it could not resolve the javax.persistence package.
I was puzzled, I searched and I read about it here -
You have to make sure that you place the same version in another
bundle and deploy first. https://forums.adobe.com/thread/2325007
I converted JPA jar to OSGi bundle and installed in my OSGi container, and the error was gone. Great!
But why OSGi is not watching out for the dependencies I wrote in pom.xml of my maven project. Why it needs JPA strictly from OSGi bundle?
Maybe this is due to any architectural benefit, but could anyone please explain me here about this behaviour of OSGi? And why/how this feature of OSGi is useful ?
The <dependency> section of your Maven POM only covers your compile time dependencies. That means when you run Maven to build your project those dependencies are used to compile the source code and build your bundle. Maven itself is not aware of AEM or OSGi or any other platform or framework (e.g. Spring).
Maven just compiles your code.
You, as a developer, are responsible that all those required compile time dependencies are also available at runtime.
What we usually do is to create an AEM content package Maven module and put all of our required third party dependencies (e.g. JPA bundles) into it. This content package is then deployed by Maven so that those dependencies are also available at runtime.
Reason is: what you are adding as dependency is getting added in build path of your project and being available for your classes.When you run mvn install,it checks presence of all dependency and creates a bundle/jar for you.By default this bundle has only your project classes not other dependencies.
You need to check in depfinder whether external dependencies are already there in OSGi container,if not you have to load them in OSGi container either by embedding external dependencies in your bundle with the help of maven-bundle-plugin present in pom.xml or by making a bundle of jar file(I wont recommend that)which you have done.
I hope this helps!

Add non-osgi jars to RCP4 project

I am building an RCP4 application.
I have two non-osgi jars called a.jar and b.jar. Both jars have tons of non-osgi dependencies. One of the dependencies of a.jar is b.jar. So the hierarchy looks like this:
My application
|--a.jar
|----aDependency1.jar
|----aDependency2.jar
|----aDependencyN.jar
|----b.jar
|------bDependency1.jar
|------bDependency2.jar
|------bDependencyN.jar
Some of the bDependencyN.jars are different versions of the aDependencyN.jars
(An example is commons-logging-1.0.4.jar vs commons-logging-1.1.2.jar)
I need to directly reference a.jar and b.jar from my RCP4 application. In other words, when I write code, I will import packages from a.jar and b.jar)
Which is the best approach:
Use bnd 2.4 via command-line to turn all non-osgi jars into osgi ones. I then add every jar to my project via target file
Create a new project "Plug-in from existing JAR archives", and select a.jar and all of its dependencies and export it as a "deployable plugin and fragment" called a.with.libs.jar. I do the same with b.jar and create b.with.libs.jar. I then add those 2 new jars to my project via target file
Create a new project "Plug-in from existing JAR archives", and select a.jar and all of its dependencies, and b.jar and all of its dependencies and export it as a "deployable plugin and fragment" called ab.with.libs.jar. I then add the new jar to my project via target file
Is there a better approach than the suggestions above?
One option is to use bnd-platform (I am also the author) to manage third party dependencies and create OSGi bundles from them. You can use it with both dependencies retrieved from Maven repositories and local Jars (see the README). When you configure a Maven dependency it will also include the transitive dependencies. Under the hood it uses bnd. If needed you can also customize how the Jars are wrapped. bnd-platform is a plugin for Gradle, you can easily start with this template - just add your dependencies and provide the configuration as described in the project README (bundle symbolic names, versions) and run gradlew bundles. The created bundles can then be added to the target platform. You can also use bnd-platform to build a p2 repository / update site.

Make OSGI bundle require JAR dependency

I know that when creating an OSGI Bundle I can declare that it needs other bundles to work correctly (in this situation other bundles need to export things that I will import in mentioned bundle).
But what if I need a jar file for a bundle to work?
Is it possible to write this information in MANIFEST.MF? I have the bundle and for some legacy reasons of other bundles that are used my bundle requires usage of a few jar files.
For building this bundle I use maven plugin for creating OSGI bundles (maven-bundle-plugin).
You cannot use normal JARs as dependency of a bundle. You can use only bundles (JARs with OSGI maniifest) as the dependency of a bundle.
You have the following options:
you embedd such jars into your bundle (http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html chapter titled "Embedding dependencies"). This means that that JAR will be inside your bundle, and the manifest will instruct the OSGI container to load the classes from that JAR as well.
try to find the OSGI version of your dependency jar. You can give a try to Spring EBR or to ServiceMix bundles
you create a bundle for each such jar with embedding (1. point) and then you add them as imported package or required bundle (imported package should be favoured).
I would prefer the second point, if not found, then the third.

IntelliJ: Including jars in a jar artifact

Developing on the Mac with IntelliJ 9.0.2 Community Edition.
I have a program which depends on two library jars. I have figured out how to get IntelliJ to make me a jar of my source (with the Artifact tab), and even to include the two jars in it.
However, if I get a listing of the jar file it produces, it looks like this:
com/acme/MyClass1.class
com/acme/MyClass2.class
...
mylib1.jar
myLib2.jar
And, no surprises, if I double-click the jar file, it gets a NoClassDefFoundError the first time it tries to access a class in one or other library jar.
It seems I need to tell IntelliJ to "inline" the library jars -- but this menu option is always greyed out!
Does anyone have any idea how to get jars inlined in a jar artifact?
IDEA doesn't support it yet, you can use Ant integration to package your jar (either by unpacking all the jars into the temp folder and then packaging the project output plus this temp folder into the single jar or by using some Ant task like jarjar).
If you want this feature to appear in the future IDEA versions, please vote for the request.
Having the dependency JARs included in your JAR should allow yoru code to run successfully. You probably don't have the JARs on your classpath.
I will use Maven Assembly plugin. Its simple and will give you a neat little jar file..

Resources