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



2 November 2012 22:28
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




2 November 2012 22:06
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

2 November 2012 21:36
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



2 November 2012 17:42
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:


2 November 2012 17:19
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

Reply via email to