You can send a mail to bndtools users or mail me.
Sometimes bnd reports imports that seem plain wrong. Believe me, they are almost always right. bnd does a thorough analysis of the byte codes in your class files and when it imports something it is almost sure to be a reference in your code. How can you find the culprit? Bndtools has tooling to drill down into your code. bnd also can print out the JAR and look at the [USEDBY]
section to find the package(s) that cause the import.
If there is no package using the imported package, then look at the following places for imports:
In the likely case the import is real but unwanted, look at Unwanted Imports.
This usually indicates that:
If you have an unwanted import than you can remove it from the Import-Package manifest header with the ‘!’ operator:
Import-Package: !com.unwanted.reference.*, *
A usually better way is to make the imports optional:
Import-Package: com.unwanted.reference.*;resolution:=optional, *
Note the end at the Import-Package statement, that wildcard ‘*’ is crucial for remaining imports, see No Imports Show Up.
The imports that show up in your Import-Package manifest header are controlled by the bnd file’s Import-Package instruction. In bnd, the list is a set of patterns that are sequentially applied to your imports as calculated by bnd from the classes, resources, and headers in the JAR.
The default Import-Package bnd instruction is:
Import-Package: *
This imports all referred packages. The most common reasons imports do not appear in the manifest is that the default is overridden and the overrider forgot to add the wildcard ‘*’ at the end. For example, the following is wrong:
Import-Package: com.example; version=1.2
This will create an import for com.example but it ignores all other imports.
Another reason is the exclude operator (‘!’) that will remove imports. If this is too wild, then no imports are left to insert in the manifest. So the following leads to no imports for any package starting with com.example.
Import-Package: !com.example.*, *
Last but not least, look at the [USEDBY]
section of the JAR print out, make sure there are actually references.
Many people are surprised that bnd does not automatically calculate the Bundle-Activator. Basically, there are the following issues:
That said, it is possible to automate the Bundle-Activator:
Bundle-Activator: \
${classes;IMPLEMENTS;org.osgi.framework.BundleActivator}
However, if there are multiple Bundle-Activators you will get an error.
@Reference
automatically sets the bind method but how is the unbind method set? Simple, you use a method with a similar name:
bind | unbind |
---|---|
setX | unsetX |
addX | removeX |
For example:
@Reference
protected void setFoo(LogService l) { ... }
protected void unsetFoo(LogService l) { ... }
If you want to override this, use
@Reference(unbind="IRefuseToCallMyMethodUnFoo");
protected void foo(LogService l) {}
protected void IRefuseToCallMyMethodUnFoo(LogService l) {}
Unfortunately Java has no method references so it is not type safe.A non existent @UnReference
annotation is not very useful because that still requires linking it up symbolically to the associated @Reference
.
Inspired by the osgi-dev thread Why default version for Export-Package is 0.0.0, not bundle version? I’m just a little bit confused about the bnd approach with the file naming “packageinfo”. The JLS already defines “package-info.java” for package relevant infos. Wouldn’t it be simplier (less complex) to have only one file for package definitions? So, the bnd tool could manage the package version in “package-info.java”, too.
You can use either file. The reason there are two options is that one constituency thinks annotations are the only solution and the other is running pre Java 5 … Basically if I would have to choose it would be packageinfo because that works anywhere but I expect that you probably would not like that :-)
Annotations are not inherited form the component’s super classes. The problem is that bnd cannot in all cases can see super classes (and interfaces) because the super class does not have to be available in the build. In runtime you are sure the super class is there, at build time you do not have that luxury. So to make sure, always define your annotations on the actual component class.
If no explicit export version is specified in the bnd file then bnd will look in the following places.
There was a mis-feature in an older version of the maven plugin that appended the pom version to the exported packages. It looked professional but it was baloney. Versioning a bundle should not version a package automatically, try it and feel the pain. So if you can’t find the source of an exported package version you might have an old maven bundle plugin.
No. It creates unnecessary complexity, it is slower, and it is not necessary. It will also not be compatible with techniques like PojoSR, something that the OSGi is looking into standardizing.
Just use Private-Package and Export-Package, know what goes into your JAR. If you really need to wrap one or more JARs, use the Include-Resource instruction, it has an option to unroll a JAR resource (see @ option. This will copy all its contents in the target JAR. The -exportcontents can then be used to export selected packages. Even better is of course to know
The [Best Practices section[1] provides some good tips about how you setup workspaces that share some information.
If an entry is wrong, send a mail with the JAR that has the problem. Preferably as small as possible.