Yes you're correct that
bnd does not NEED the packages referred to. If the bytecode in the JAR
contains a reference to package "org.example" then that will be added as
an Import-Package, irrespective of whether bnd can actually see
"org.example" somewhere.
However, if bnd CAN see that package somewhere, it does its best to use
all the information available. So if you put the JAR containing
"org.example" on the buildpath, and if that JAR happens to be a bundle
with an Export-Package header that exports "org.example" as (say)
version 1.0, then bnd will use that information to generate an
Import-Package that with version range [1.0,2.0) or [1.0,1.1), depending
on whether your bundle is a consumer or a produce of the API in
question.
If you're building your bundles from source then you basically always
have the dependency JARs around, because javac needs them. Therefore if
you can arrange for your dependencies to be bundles rather than plain
JARs, and if you pass the same buildpath to bnd that you gave to the
javac compiler, then the version ranges will be inferred.
Because of this capability, I hardly ever have to manually override the
Import-Package statement in my own bundles. It's only really necessary
when I'm wrapping a pre-compiled binary JAR from somewhere else.
Regards
Neil
Hello,
If there's a
solution for bnd to determine the version range, then that sounds
like the solution I'm looking for. However, I can't see how to do this...
I use BND in two ways, either at the command line with a ".bnd" file,
and using the Ant task. The only way I can see to set the classpath is
for the class files that I want BND to pull into the output JAR. After reading
various sources (including "osgibook_preview_20091217.pdf"), I was under
the impression that BND determines the imports by inspecting the bytecode
of the classes that make up the bundle, and doesn't actually require
(or have any way of specifying) the packages and JAR files referred to.
So
I can't see how to tell it to inspect other JAR files to extract the version
of different Export-Package headers. Could you point me to an example
of how I can make a ".bnd" file and the Ant task add versioning information
to the Import-Package header without me actually specifying it?
Thanks, Christopher
The requirement for the
trailing star has never changed, as far as I remember.
If you use Bndtools it will nag you that the trailing star is missing,
and offer a quick-fix to put it there. Of course it can only be a
warning because there are scenarios where the user really does know best
and wants to explicitly define every import on the bundle.
For the version issue, it's best if you can build your bundle against
other bundles that have versioned exports. If you do this then bnd will
automatically apply Semantic Versioning rules to set the correct import
range.
Regards
Neil
Hello,
I didn't
have the wildcard at the end. That enabled all Import-Package statements.
Did
this change at some point in bnd's history? If I remember correctly, when
I started building OSGi projects with bnd 0.0.384, it helpfully complained
when I defined the Import-Package statement and forgot some imports.
Now,
it will tell me (with an explicit Import-Package header) when I've included
an import for something I don't use (like "javax.*") but it won't tell
me when I've forgotten. So by adding the "catch-all", it works with the
caveat that I don't getted nagged to remind me (with a detailed build failure)
that I might also want to specify a version range... The risk is that
if the bundle gets deployed with a different version of the package, the
dependency might be satisfied but because it can match any version of the
package, I might get LinkageErrors...
The trailing "*" means
that more discipline is required to think about checking the
generated MANIFEST.MF and watching commits from all contributors. It
also means that I catch things needing optional resolution only when
deploying, not when building.
Given then that BND can indicate
"things I imported but didn't need to", it would be very nice when
using non-default import headers if it could also warn that "there
are things you should import but didn't".
Thanks for the
feedback. Christopher
Did you remember the catch-all "*" at the end of the
import-package statement?
-- Neil
Bartlett Sent from a phone
On Friday, 2 November 2012 at 17:19,
Christopher BROWN wrote:
Hello,
Using
current builds of BND (GitHub/Cloudbees), and referring to the documentation
for BND, I'm observing odd behavior.
It seems that BND only adds
"javax" packages automatically to the MANIFEST.MF when the ".bnd"
file contains NO "Import-Package" directive. However, I need to add
explicit headers because BND can't guess the version ranges, so I add
the headers manually with the version ranges. And suddenly, BND
doesn't seem to detect and add the "javax" packages any more.
Therefore,
I'm getting ClassNotFoundExceptions from Apache Felix at runtime (with
the helpful message telling me that the JDK and Felix export it) because
there's no Import-Package header. This is similar to "classic" classpath
problems in Java in that the failure occurs only when a specific code
path is executed...
I can test this by adding a dummy line such
as: javax.sql.DataSource = null;
...anywhere in the bundle.
This only fails when the JVM reaches this code, it doesn't prevent
the bundle loading. Apache Felix obviously can't detect the problem
when resolving the bundle because it's not explicitly imported, because
BND isn't adding it.
However, if I put say "javax.foobar.*" in
my directive, BND gives me a warning.
Is this a bug in BND ?
Is there a way to make it "grumpy" so that it'll refuse to build my
bundle if my imports are wrong?
Thanks, Christopher
|