My answer here is about the Equinox runtime which is used in Eclipse and is the reference implementation of the OSGi spec.
Installing into the OSGi Runtime
Every plug-in (or bundle, I use the terms interchangeably), must be installed into the OSGi runtime before you can even think about it running. There are two main ways to install a bundle: programmatically through the BundleContext API, or declaratively through the osgi.bundles property in the config.ini file.The osgi.bundles property is read at startup. It is a list of bundles that are automatically installed and optionally started once the framework is up and running. The format of each entry is
<URL | simple bundle location>[@ [<start-level>] [":start"]]
Starting your bundles
It is not enough to simply have your plug-in installed, it must also be started. When the OSGi framework starts up, it increments through the start levels starting bundles as it goes. A bundle won't be started until its start level is reached, and to get started it must be marked as such, or be marked as lazy start. A lazy start bundle will be started when something tries to load a class from that bundle (and once the start level has been reached for that bundle).[Edit:] In most cases, marking a bundle as Lazy-Start is sufficient and one need not worry about starting bundles explicitly. See Neil's comment attached to this post.
The default start level for bundles is 4.
Managing installed bundles
There are 2 strategies here, one is to list all of your bundles on the osgi.bundles list, the other is to list only a few bundles that can bootstrap the rest of the application. I will call this kind of bootstrap bundle a "configurator".
If you list all your plug-ins on the osgi.bundles property, then it can be painful to maintain and add new plug-ins to your application. I won't try to make arguments for or against any particular way of managing your system, but it a large way it often comes back to the differences between the old update manager and the new p2 provisioning system.
Update Configurator
In Eclipse 3.3 and earlier, there was the update configurator (org.eclipse.update.configurator). It was installed on the osgi.bundles list and started at level 3. It would scan the plugins directory and automatically install everything it found there.
This is where the magic ability to just copy things into the plugins directory and have them work came from. However, update configurator is essentially forcing the found bundles into the framework with no regard to any conflicts or unresolved dependencies that may result.
Simple Configurator
In Eclipse 3.4, with the advent of p2, update configurator is replace with simple configurator (org.eclipse.equinox.simpleconfigurator). As the name suggests, it is quite simple: it installs everything it finds listed in its configuration file (specified by the org.eclipse.equinox.simpleconfigurator.configUrl property, usually bundles.info).Editing the bundles.info file to add plug-ins to your product is not really any easier than editing the osgi.bundles list. The difference here is that p2 manages bundles.info for you. In fact, if your product is p2 enabled for updating and installing plug-ins, then any changes made manually are likely to be lost when p2 updates or installs new software.
Dropins
Whatever the other problems update has with respect to avoiding conflicts and ensuring that dependencies are satisfied, it is hard to ignore the simplicity of just copying new bundles into your install. p2 has support for dropins (provided by org.eclipse.equinox.p2.reconciler.dropins).Like the update configurator, the dropins reconciler will automatically watch a directory and install things it finds there. However, unlike the update configurator, it will ensure that the bundles found will not conflict with others in the system and that all dependencies are satisfied.