What is "fat bundle"? - osgi

I hear the slang term "fat bundle" in OSGi context so I am wondering what is the difference between it and the ordinary OSGi bundle?

A fat bundle is a bundle that contains all its dependencies. Since a bundle has an internal classpath you can take an application and run it inside a bundle. Once you have this "fat" bundle you can carve out pieces and make the more modular.

Related

Order of deployment of bundles

I have a question about OSGI bundles deployment.
I have 7 bundles which I need to deploy in a strict order otherwise I get no class found error. Part of the bundles are used as static libraries, part of them export OSGI services.
In OSGI applications how this problem is usually solved?
This problem is solved by not solving it (at least, not in the way you have asked).
That is: don't have bundles that must to install/start in a strict order! This implies your bundles are very poorly designed. Instead, change your bundles so that they can start in any order.
If you have difficulties with this then please modify your question so that we can see why you think you need the start ordering.
If I understand your issue correctly, it is just a matter of providing the correct dependencies chain to be resolved by OSGi.
Your libraries should export packages that your services will import.
If BundleA requires classes from BundleB and OtherBundle, adding Import-Package and Export-Package metadata in the MANIFEST.MF of all bundles should be sufficient.
BundleA MANIFEST.MF
Import-Package: my.required.package.from.b, other.package.in.b, other.package
BundleB MANIFEST.MF
Export-Package: my.required.package.from.b, other.package.in.b
OtherBundle MANIFEST.MF
Export-Package: other.package
Then install all bundles, they will be in INSTALLED state. Start the main one (BundleA in this example).
OSGi will resolve all dependencies (just be careful not to have cycles) and bundles will go in RESOLVED state (dependencies available) and then ACTIVE.
You don't need to manually add those dependencies, tools like maven-bundle-plugin can be easily configured.
Also this question What is the natural start order for package-dependent OSGI bundles may be useful.
I agree that the best approach, as Neil Bartlett mentioned, is avoiding it. However sometimes ordering the start of the bundles is necessary. Even using Equinox or Felix you can have it using bundle start-level. It will ensure that your bundles will start in a specific order.
"A start level is associated with every bundle. The start level is a positive integer value that controls the order in which bundles are activated/started. Bundles with a low start level are started before bundles with a high start level. Hence, bundles with the start level, 1, are started first and bundles belonging to the kernel tend to have lower start levels, because they provide the prerequisites for running most other bundles." - Red Hat JBoss Fuse Documentation
Hope it helps.

CICS Explorer bundle could not be resolved

I am working on a simple Java-DB2 insert program connected to cics region via CICS explorer. I created a plugin for an external jar(com.ibm.db2.jcc), exported the plugin as a deployable plugin and added this in the build path of the program. The package has also been added in the dependencies (import-package) of the program. But installing the bundle in the cics region, I am getting an exception.
The bundle ABC could not be resolved. Reason:Missing constraint:Import-package:com.ibm.db2.jcc;version="0.0.0".
Can someone help me trace the problem?
I'm assuming the program you're writing is in an OSGi bundle that's being deployed into a CICS JVM Server as your OSGi environment, using CICS's OSGi CICS bundle parts. It sounds like you're taking an existing binary dependency and rebundling it as an OSGi bundle, and want to have your program resolve it using OSGi.
Based on these assumptions, it sounds like you're having to add the bundle to your build path automatically, which I don't think you should have to do. Once you've set up your target platform (http://pic.dhe.ibm.com/infocenter/cicsts/v5r1/index.jsp?topic=%2Fcom.ibm.cics.ts.java.doc%2Ftopics%2Fdeveloping_sdk.html) any dependencies should then be resolved either from OSGi bundles in your workspace, or your target platform. It should then just be a case of adding an OSGi bundle part for each of your bundles, and exporting your CICS bundle to your region. Explorer should take care of exporting all of your relevant dependencies to CICS.
If you wanted, it should be possible to add the DB2 jar file as a lib without rebundling as an OSGi bundle, by adding the library to your Bundle-Classpath manifest declaration, but you might already have considered this!

Packing multiple OSGi bundles in the same jar

I am very new to the OSGi platform.
Having an OSGi bundle B1 that has a dependency to another bundle B2, which is very probably not provided by the container, can I package both bundles in the same jar?
If yes: howto do that? what would happen if the jar is installed and the bundle is already installed?
Yes you can do this... kind of.
Normally OSGi bundles are JAR files because they need to have a META-INF/MANIFEST.MF. The OSGi framework cannot directly read your "multi-bundle" JAR.
However, installing bundles in OSGi involves calling the BundleContext.installBundle method. This method has two flavours, one of them takes an InputStream as a parameter; this InputStream should supply the content of the OSGi bundle. Therefore you can take your big JAR and read it with a JarInputStream, passing the individual entries to the installBundle method.
Although OSGi doesn't directly support multiple bundles in the same jar, there is a standard for multiple bundles in the same archive, which solves the distribution problem you're trying to address. Unfortunately, it may introduce an extra problem in your scenario, because it's part of enterprise OSGi, rather than core OSGi, so it wouldn't be part of a bare bones Equinox or Felix framework. If you have more control over the starting platform your users are using, it may do what you need.
The basic idea is that you package all your bundles into a zip with a .esa extension, along with a simple manifest. You can then distribute the esa file. This tutorial includes lots more detail:
http://coderthoughts.blogspot.co.uk/2013/04/osgi-subsystems.html?m=1

What is the intended use case for Bundle-Classpath in OSGI bundles

I am trying to understand the intended use case for Bundle-Classpath in OSGI bundles.
Here is my understanding, please help me understand if this is correct.
Let's say I am working on creating an OSGI bundle which will be deployed in an ecosystem of other bundles. The bundle I am working on needs some other bundles, but they are not loaded/exported in this ecosystem, and I do not have control on what the ecosystem exports. In such a scenario, I can put these bundles inside some directory (say 'lib') which becomes part of my bundle. These bundles should also be referenced from the Bundle-Classpath, so they can be loaded.
Is this a correct use case for Bundle-Classpath ?
Will these additional bundles also be loaded in the OSGI container and will packages exported by them be available to other bundles ?
Bundle-ClassPath is intended for including dependencies in our bundle, so that our bundle can be deployed standalone.
Let's take an example. Suppose the code in my bundle uses a library, e.g. Google Guava. I have two choices for packaging my bundle:
Simply create my bundle with only my own code inside it. The bundle will now have the Import-Package statements that declare a dependency on Guava, and anybody who wants to deploy my bundle into his application will also have to deploy Guava.
Alternatively I can include a copy of Guava inside my bundle and reference it from my Bundle-ClassPath. Whoever deploys my bundle can deploy just my bundle, and doesn't need to worry about where to get Guava from. In fact, the existence of Guava inside my bundle is an implementation detail, and the deployer doesn't even need to know that I am using it.
The choice between these two options is a trade-off. Option 2 has the advantage that my bundle is easier to deploy because it is standalone -- everything it needs is right there inside it. On the other hand my bundle is much bigger than it needs to be, which could become a problem if lots of other bundles also embed their own copy of Guava.
A more severe problem with option 2 is that all of the dependencies of the library now become my dependencies as well. Actually Guava is a rare example of a Java library with no dependencies of its own... but many other Java libraries drag in a huge tree of transitive dependencies. If you use this approach with, say, Hibernate then your own bundle will also have that large dependency set. This gets very ugly, very quickly.
So, you should be cautious not to overuse Bundle-ClassPath/Embed-Dependency. You should only consider using it if the dependency is (a) small, and with no transitive dependencies, and (b) your bundle uses the library as an internal implementation detail, i.e. it is not part of your public API.
UPDATE
I forgot to answer your second question about the exports. The answer is NO, the exports of any "bundles" you put on your Bundle-ClassPath will NOT become exports of your own bundle. In fact the JARs we put on Bundle-ClassPath are not treated as bundles at all, they are just JARs.
You can choose to export packages that come from within the JARs on your Bundle-ClassPath but you have to do this in the MANIFEST.MF of your own bundle.
The most common use case for this header is the packaging of external libraries. Let's say you have some library foo.jar, and want to use its classes in your bundle.
You put the jar into your bundle like so,
/
com/company/Activator.class
foo.jar
META-INF/MANIFEST.MF
In you manifest, you can now use
Bundle-ClassPath: foo.jar,.
Remember to include the . on the classpath, or you will not be able to find the classes in your bundle.
When classes are on the Bundle-ClassPath, you can use them like any other class: use them in your code, or export them.
I think you may be a bit off here.
A Bundle-Classpath is an ordered, comma-separated list of relative
bundle JAR file locations to be searched for class and resource
requests.
What this means is that when some bundle class needs another class in
the same bundle, the entire bundle class path of the containing bundle
is searched to find the class.
From OSGI in Action.
Let's consider a concrete case. Imagine a bundle (JAR file) with the following structure:
src/a/A.class
src2/b/B.class
src3/c/C.class
if you wanted a.A, b.B and c.C to be available to each other, you'd have to define src, src2 and src3 as pertaining to the bundle classpath. That would mean you'd have to add to your manifest file the following line:
Bundle-ClassPath: src,src2,src3

Run nutch in OSGI environment

I am new to OSGI framwork So this question might seem silly.
Can we run Apache Nutch 1.4 in OSGI framework. I want to create an OSGI bundle of nutch. I am using eclipse indigo to compile the Nutch source code. So i think there should be some kind of plugin which can create OSGI bundle instead of jar after the compilation. I just need the OSGI bundle of Nutch.
I don't even know if it is possible.
You need to look for a bundle that implements Nutch. A quick google turned up this. If this particular bundle doesn't meet your needs, you can just embed the Nutch dependency into one of your own bundles, using the Embed-Dependency field in your bundle's manifest.
A bundle which already implements Nutch, as the other answer suggests, is your best bet. More generally, you can easily convert an existing jar into an OSGi bundle (without having the source code) using the wrap function of the bnd tool. If you do have the source code and want to recompile, maven's bundle plugin and the bundle packaging will generate bundles.
In the interests of modularity, which is one of OSGi's main drivers, I'd suggest using a separate Nutch bundle rather than embedding the dependency.

Resources