wildcards in the Private-Package header—make the regular expression too general,
and bnd will package up the entire classpath into a single bundle. (This brings us
neatly back to the importance of double-checking the bundles produced by bnd in
case of disaster!)
WARNING: WRONG VERSION? WRONG CLASSPATH Bnd's automatic versioning
of package imports is incredibly useful, but if you get things wrong it can leave
you with bundles that won't start when you deploy them in production. If you
compile against a package with version 1.1.0, bnd will (correctly) set the min-
imum version for that package import as version 1.1.0. What happens if you
then deploy into an environment where that package is only available at ver-
sion 1.0.0? The OSG i framework will refuse to start your bundle because its
minimum requirements aren't met, even if all your code really needed was ver-
sion 1.0.0. You can fix this problem by manually specifying the version range
for the import in your bnd.bnd file, but a cleaner solution is to make sure that
what you're compiling against lines up with what you're deploying against.
You'll want to compile against the lowest compatible version of a bundle.
Let's look in more depth at what can go into a bnd configuration file.
MAKING THE MOST OF THE BND FILE
The bnd file is an extremely flexible and powerful configuration tool. As well as the
wildcards we've already seen, it supports variable substitution, macros, inheritance,
and even Declarative Services.
The Import-Package , Export-Package , and Private-Package headers all allow
wildcards. This means bundle exports can be specified concisely. For example, if you
adopt a naming convention that assumes packages ending with .impl are private, the
following .bnd snippet will automatically export only what it should:
Export-Package: !*.impl, *
If the same package is included in both Export-Package and Private-Package , the
export takes precedence.
One nice thing about the variable substitution is you can include as much or as lit-
tle detail as you like. You can specify nothing but * , or copy and paste whole import
declarations from existing manifests, or add in package versions or other package
directives where needed. Even if you do explicitly list out a bundle's package imports,
it's a good idea to add a catch-all * at the end of the list to import anything you've for-
gotten—or didn't even know you needed. If you don't import everything you need,
then bnd will issue warnings to tell you so. If you choose to continue from there, then
you expose yourself again to the dreaded NoClassDefFoundError .
So far all the bnd functionality we've seen has been about generating manifests—
better, smarter, cleaner manifests, but still manifests. Bnd can also use the information
in the bnd.bnd file to generate other types of resources. In particular, it can be used
for Declarative Services.