OSGi manifest entry "bundleRequiredExecutionEnvironment" can be used to specify JRE on which given bundle can be used on, but it seems like this is a strict check such that if I specify value of "J2SE-1.5", bundle could not be used on 1.6 or above. This seems strange; my assumption was that this would just be the baseline, not exact match.
But if the semantic of property are exact match, what would be the way to indicate "1.5 or higher"? Or could this be a bug of OSGi container in question misinterpreting requirement?
It appears you have to specify all of the valid JRE environments.
Bundle-RequiredExecutionEnvironment: J2SE-1.5, JavaSE-1.6
When Java 1.7 becomes available, you'll have to add that as well.
Related
In a gradle file it's possible to specify a dependency with a dynamic version, like:
compile 'some.dependency:name:1.+'
This is documented to resolve the "newest" matching version. I have two questions:
[1] What does "newest" mean? Suppose the available versions are:
1.0
1.1-beta
1.1
Is the "newest" one 1.1-beta or 1.1? Does it depend at all on when the versions were published, or is it purely based on the version strings? If purely based on the strings, what ordering is used, because if it's just alphabetical then I think 1.1-beta would end up being "newer" than 1.1.
[2] As a publisher of a module, is there a sensible way of publishing a beta build such that developers who are depending on your module and using dynamic versions wont automatically pick it up? Is there a standard or recognized way of doing this?
Thanks!
[I'm aware using dynamic versions is discouraged. These questions are from the point of view of someone providing a module, and wanting to ensure that developers who do use it and ignore this advice still don't end up pulling in something unexpected]
I' m guessing you are publishing to maven, and as I know, there should be an xml file named maven-metadata.xml which holds the information of the latest upload to the corresponding artifact. So I guess it does not depend on your naming convention but what you upload the latest. If you would upload 1.0.0.1 the latest then it would be downloaded not 1.1-beta or 1.1 versions.
For more info check here.
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.
I am looking for a way to ensure that all the features I deploy in Karaf require dependencies that are of the same version. The project is composed of more than 40 bundles which makes it difficult to verify manually.
I am thinking of developping a Maven plug-in that would make the check, but before I would like to be sure that such a solution do not exist yet.
If you want to be sure you use the same versions then create a parent project and define versions of dependencies only there. So you can be sure all your modules have the same dependencies. Of course this only makes sense if all these modules are very closely related (e.g. belong to the same application / release unit).
Why would you even want to do this? Each bundle should depend on the versions of the package it needs, and that dependency should be a range. So if you compile against and API package version 1.0.0, and you are a consumer of that API, then you should import with the range [1.0.0, 2.0.0). Refer to the OSGi Core Release 5 specification, section 3.7.3 ("Semantic Versioning") for details.
At runtime the OSGi Framework will ensure that your bundle is wired to a package version that is within its permitted range. Obviously if you have non-overlapping version ranges from different importers then the Framework will not be able to satisfy them with a single exporter.
This might be a bit of a weird question, so bear with me.
I've got a Tycho/Eclipse plug-in that only contains a lib folder containing a third-party-library. The library has version 1.17.0, so in an attempt to make the process more transparent, the plug-in has, too.
It exports all the packages of the lib and everything is fine. At least it was, because now I realized it would have been much, much better if I exported the packages with a version. Plug-in 1.17.0 is already released (I know, Tycho doesn't normally release, just assume I don't want to re-use a version that has been stable for a year).
As an OSGi bundle, I am not allowed to take the version 1.17.0.1 or 1.17.0B or something, but I can't just use the version 1.17.1, because it would imply the third-party library is 1.17.1 as well, and it isn't. Updating the third-party library is not possible at the moment, because time is critical.
I tried 1.17.01 just now and nobody complains, but I'm not sure how Maven and OSGI sort this version relative to 1.17.0 and 1.17.1. The Maven manual does not really talk about zeros, but I guess it would force the string comparison, yielding in completely screwed up version sorting.
So... what version can I use safely?
You could just use something like "1.17.0.p1" which indicates a "patch 1" - it should be ok with OSGi as "the qualifier can be any string, sorted lexicographically" (quote taken from your OSGi link). "p1" is similar to qualifiers like "beta1" or "RC1" or...
major.minor.micro.qualifier
This should work for Maven as well. Moreover, we can assume that you would not provide a series of more than ten patches (at least I assume).
Personally, I would avoid leading zeros, as this looks quite odd to me. A series of HotFix or Patch versions should lead to an increment of a higher version number once in a while.
I'm not sure about Tycho but the OSGI framework treats the first three parts of the version as numbers and converts them to int using Integer.parseInt (see org.osgi.framework.Version).
So '01' will be treated exactly the same as '1'.
For the new bundle version, you need to make sure that is is larger in terms of the OSGi semantics - the Maven semantics don't really matter here. So you either need to increase the numeric value of one of the first three segments (e.g. 1.17.1) or add a fourth segment. The fourth segment, the so-called qualifier, is a string, and OSGi considers a version with qualifier to be larger than the same version without a qualifier. So you could e.g. use 1.17.0.a.
One word of warning for the change that you want to introduce with the new bundle version, which is to add versions to the exported packages. It absolutely makes sense to export the packages with a version, but is is crucial that you pick the right version for the packages.
Experience has shown that using the library version as package version is a bad idea: When we built an OSGi wrapper for javax.mail 1.4.1, we also used the version 1.4.1 for the exported packages. But when Sun released javax.mail as OSGi bundle in version 1.4.2, they decided that the packages fulfill the 1.4 API contract and hence exported them as version 1.4. So our older version of the library pretended that its exported packages were better, and the OSGi resolve would therefore prefer it over the newer library version.
To make things worse, we in the meantime also had lots of other bundles that required the javax.mail packages with a minimum version of 1.4.1, so they couldn't even be forced to use the newer library version. In the end, it took us more than a year to clean up the mess we had gotten ourselves with the bad choice of package version in the OSGi wrapper.
Conclusion: Only use very small package version numbers when converting a library that you don't own to an OSGi bundle. When using package version numbers with zero as major version, e.g. 0.1.17, you should be on the safe side that the versions that you invented yourself are smaller than all future "official" version.
One of our bundle has 'imports' on joda-time/2.2.0 but when I start it,it always picks up the joda-time/1.6.2 available in the system folder of Karaf. I am not sure how can that happen? is there a way to tell the karaf not to pick the system bundle over the one specified by us? please note that we drop bundles to deploy folder to get them installed.
First of all, make sure you really need two versions of this bundle. Yes, you can make that work but in general, unless you really need different versions of bundles to be present within your application, avoid it. Check what bundles consume joda-time and what version ranges they specify in their Import-Package statement.
I'm not sure if you're aware of this, but if you import a package, you always, either implicitly or explicitly specify a version range you are compatible with:
If you don't specify any version, you effectively state you're compatible with a version range from zero to infinity.
If you specify only one version, you state you're compatible with that version and anything higher than that, up to infinity.
If you specify two versions, you state you're compatible with that range and you can either use square or round brackets to state if this includes or excludes the borders.
Not specifying a range explicitly is considered bad practice. OSGi has a whitepaper on semantic versioning that explains this in more detail.
So, make sure you understand what versions your bundles that consume joda-time use, see if you can deploy just one implementation of joda-time and ensure that your own bundle also uses a version range that is compatible with that.
Just add the version you need to import after the package you are importing like this.
Import-Package: org.xx.xx;version=1.5.0
Refer this