Make OSGI bundle require JAR dependency - maven

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.

Related

How to convert a maven jar into an OSGI bundle?

How to convert a maven jar into an OSGI bundle? For this jar file, it also has dependencies on other external jar files. I tried maven-bundle-plugin, but how to write Import-Package is a disaster for me...... Can anyone help me out?
More specifically, what I want to transform is ProvToolbox https://lucmoreau.github.io/ProvToolbox/, which has several prov packages. So I need to transform them one by one.
Adding import packages is easy using the UI from Eclipse - just open the manifest, and in the Dependencies tab, you can add them.
This explains how to transform a JAR into an OSGi bundle:
link
Here you have a perfect example to create a fat bundle with all transitiv dependecies.
https://github.com/apache/jackrabbit/blob/2.18/jackrabbit-bundle/pom.xml
Notice the following tag:
<Embed-Transitive>true</Embed-Transitive>

Eclipse: How to include dependencies in osgi bundle export?

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.

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!

no osgi ready dependencies

Currently I'm working with osgi and karaf.
My problem is the no "osgi ready" dependencies , which means a jar that is not ready to be deployed as a bundle into karaf for example.
I tried two solutions in order to deal with this kind of problems :
I tried to to use "Embed-Dependency" which will include the jar
dependency with the project... I don't think this could be a solution
because when I try to embed the jar , it will ask me to include other
jars that the first jar depend on , and so on ..
I tried to convert the no "osgi ready" jars into bundles using bnd tool or from "Plug-in from Existing JAR Archive" from eclipse project.
And this led to the same result , each jar will call another jar that it depend on it..
I am not sure if I'm doing it the wrong way or what is the problem exactly.
Any tips how to deal with no osgi ready dependencies ?
The simplest way to start is to use the wrap: protocol to auto create a jar. Behind the scenes it uses bnd to create a bundle on the fly. Simply prepend wrap: to the mvn url of the jar.
When you try to install the jar using bundle:install -s wrap:mvn:... karaf will tell you which imported packages are missing. Install jars that provide these packages in the same way. The pom of the jar can give you a hint what is missing.
This can mean to install lots of jars if your initial jars has lots of dependencies.
Once you have a list of jars that are installable together you can either create a feature using wrap protocol or you can make bundles from the individual at build time.
In any case you should take a look are the servicemix bundles. It provides OSGi ready bundles for many libraries.

Which way is the best to go for building a webapp as osgi bundle via maven and start them with webstart?

I am looking for a way to reach my vision. What is the best way to go?
Here is my vision:
I would like to build a captain casa app via maven (as a war file).
Then i would like to create a osgi bundle from the builded war via maven.
Next i would like build a artifact which could be downloaded and started via java webstart (jnlp).
The jnlp file should be download the osgi environment with web container support (maybe jetty osgi service), next download osgi bundled war. Then the osgi container and the jetty service should be started and my war should be deployed. Finally the app is running local in a osgi environment.
There are many questions to be answered:
How can i build a captain casa app via maven to a war?
Which maven plugin should be used to build the osgi bundle (pax, maven-bundle-plugin, tycho, ...) What are the differnce?
How to build a jnlp artifact via maven which can deployed on a site?
How must be modified the osgi bundle to support java webstart?
Known informations:
Blog entry to prepare osgi bundle for java webstart.
many pages to maven plugins, such as pax, maven-bundle-plugin, tycho, bnd, ...
It might be worth asking this as 3 separate questions, but when building Web application Bundles I use the maven-bundle-plugin version 2.2.0 (currently unreleased, so you'll need to depend on a snapshot).
Then I use the following file structure:
src/main/java - any .java files
src/main/resources - any non .java files that should be on the classpath
src/main/webapp - static content, images, html files jsps and so on
Then inside the pom once you have configured the normal data for the maven-bundle-plugin you specify the following:
<_wab>src/main/webapp</_wab>
this will cause the static content to be pulled into the bundle and the bundle to be structured with the classes and resources in the WEB-INF/classes directory.

Resources