One of the primary authors of bnd has always objected to startlevels. His motivation was twofold:
With this disclaimer out of the way, there are actually cases where startlevels are quite important to improve the non-functional aspects.
Run configurations in bnd are described in bndrun files. The list of bundles to run are listed in the -runbundles
instruction. The runbundles
instruction has a startlevel
attribute that specifies the startlevel of each bundle.
Since the -runbundles
instruction is frequently calculated by the resolver support in bnd it is not possible to manually
assign the startlevel
attributes to specific bundles. For this reason there is a decorator support in bnd for some selected
instructions. A decorator is a header with the same name but ending with a plus sign (+
). This instruction acts like a selector
and can be used to assign startlevel
attributes on the -runbundles
.
For example:
-runbundles: \
org.apache.servicemix.bundles.junit;version='[4.13.0,5)',\
org.apache.felix.log, \
demo;version='[1.0.0,1.0.1)'
-runbundles+: \
demo;startlevel=11,\
*;startlevel=99
The launcher is responsible for installing the bundles after starting or communicating with a framework. The
default bnd launcher will assign each bundle a startlevel, where bundles that do not have a specified startlevel
are
assigned one level higher than the maximum specified levels.
The launcher supports narrow managed mode or all via the [-launcher
] instruction. In narrow mode, the start levels
will only be assigned to the scope, the set of bundles listed in the run bundles. In the all mode, all bundles
that are installed at launch time will be assigned the default start level.
The default launcher will then move the framework start level to 2 higher than the highest specified start level.
The resolve support in bnd can automatically assign startlevel
attributes to the -runbundles
based on different ordering
strategies. There are two strategies that use the dependency graph. This graph can be sorted in topological order.
This means that a resource is always listed ahead of any of its dependencies when there are no cycles.
The -runstartlevel instruction controls the ordering and assigned start levels.
At the time of this writing it is not yet clear what the best strategy is, and it may depend.
Ordering by the topological sort (a resource is followed by its dependencies) will start something like the log service last and any applications bundles first. Although at first sight this feels wrong (the log service should be started first to capture the events at startup) it does solve the jojo problem because one of the last bundles started will be the Service Component Runtime that will activate all components. At that time all initialization should have taken place.
Reversing the topplogical sort will start the something like SCR and log first because they have few or no dependencies. Application bundles are then started latest.
Traditionally start levels are managed by an application bundle. Shell commands can increase and decrease start levels. For this reason, start levels often use nice numbers.
Using the resolver the need for nice numbers is diminished since bnd is now taking care. The basic default model is to assign bundles sequentially in selected order from an initial level stepping with 10. The -runstartlevel instruction can provide the initial level and the step if desired.
The launcher will by default move the framework then to a start level that includes any used start levels. This
default behavior can be blocked by specifying the org.osgi.framework.startlevel.beginning
property. If this
property is set bnd will assume that there is an agent that will handle the runtime start levels.
A quick way to disable the start level handling by the launch is to set the property used to convey the default
start level, launch.startlevel.default
to 0. This will disable the complete start level handling regardless
of other settings.