Configuring iPOJO Extender

This page presents how the iPOJO's extender can be configured.

Extender

The iPOJO Extender starts with the iPOJO bundle (in fact, it's the iPOJO's BundleActivator). It is basically a BundleTracker that will discover iPOJO's components, instances, etc from the ACTIVE bundles.

ThreadPool

In Apache Felix iPOJO 1.10, the extender has been refactored to take advantage of multi-threading capabilities of modern machines. There is now an ExecutorQueueService service, based on a ThreadPoolExecutor that enable asynchronous (and concurrent) activation of Bundles. All activation activities (search for IPOJO-Components and IPOJO-Extensions Manifest headers, creation of factories and instances, binding) are done through job submissions. Respectively, deactivation is always done asynchronously (if bundle is stopped when we would perform actions on it, that the ideal way to Exceptions).

By default, the ThreadPool size is set to 1 (asynchronous, but not concurrent executions), to mimic the pre 1.10 behavior.

ThreadPool's size can be configured either with System properties or through ConfigurationAdmin. With Config Admin, the Configuration object has to target the service with org.apache.felix.ipojo.extender.ExecutorQueueService as its Service PID. Property names are identical for System properties and ConfigAdmin.

Function Property Name Supported Type(s) Default Value Description
Number of Threads org.apache.felix.ipojo.extender.ThreadPoolSize Integer 1 The size of the thread pool. The default value is 1. Increase in case of a large amount of bundle's to manage (bundles with iPOJO's components/instances inside).

Synchronous / Asynchronous processing

By default, Apache Felix iPOJO process the Bundles in an asynchronous way. It's better in term of performances and more aligned with OSGi spec recommendations. However, in some situations, like when running in Google App Engine (GAE), the underlying platform imposes limitations. For example GAE imposes mono-threading. That means that no asynchronous processing can be done by the application itself.

In other situations, it can be useful to be sure that components and instances contained in a given Bundle will be synchronously started.

iPOJO's Extender can be configured to support mono-threaded bundle processing to support such use cases.

System wide

General synchronous processing can be configured through System properties or iPOJO's own Manifest attributes (requires a dedicated iPOJO bundle build).

Mean Property Name Supported Type(s) Default Value Description
System Property ipojo.processing.synchronous Boolean false Whether the Bundles processing should be performed synchronously. The default value is false. Set it to true when running in GAE for example.
Manifest IPojo-processing-synchronous Boolean false Whether the Bundles processing should be performed synchronously. The default value is false. Set it to true when running in GAE for example. Notice that case is ignored (IPOJO-PROCESSING-SYNCHRONOUS works as well as IPojo-Processing-Synchronous).

Per-Bundle

The synchronous behavior can be selected per-bundle (given that it does not conflict with existing system wide configuration). Synchronous/Asynchronous behavior can be expressed in the Bundle's Manifest (case is not significant, but an uppercase first letter is recommended):

IPOJO-Queue-Preference SYNC

3 values are supported:

If no header (or invalid value) is provided, the fallback behavior is DEFAULT (use system wide preference).

QueueService Insights

Apache Felix iPOJO provides a mechanism that stores Job events of the QueueService in use (synchronous, multi-threaded, ...) for replay. This is very useful to see where time is spent during the bootstrap and take actions accordingly.

This mechanism is available when the org.apache.felix.ipojo.extender.BootstrapQueueDebug system property is set to true. When activated, a new OSGi service is registered under the org.apache.felix.ipojo.extender.queue.debug.QueueEventProxy interface (see below).

QueueListener has to be registered in this service, when added, they'll be invoked with all stored events. After that, the proxy simply forward the queue events to registered listeners.

/**
 * This service record events from a {@link org.apache.felix.ipojo.extender.queue.QueueService}.
 * When a listener is added, all recorded events are replayed into the listener.
 */
public interface QueueEventProxy {
    /**
     * Add a {@link org.apache.felix.ipojo.extender.queue.QueueListener} that will be notified on events
     * relative to the observed {@link org.apache.felix.ipojo.extender.queue.QueueService}.
     * @param listener added listener
     */
    void addQueueListener(QueueListener listener);

    /**
     * Remove a {@link QueueListener} from the observed {@link org.apache.felix.ipojo.extender.queue.QueueService}.
     * @param listener removed listener
     */
    void removeQueueListener(QueueListener listener);
}

Event Dispatcher

Apache Felix iPOJO provides a way to circumvent the so-call event storm happening when starting large OSGi applications (chained services apparitions). It is a dedicated Event dispatcher that mimics a service registry partition logic based on registered service interfaces (Constants.OBJECTCLASS). It is not enabled by default (rely on the framework's own service registry).

Mean Property Name Supported Type(s) Default Value Description
System Property ipojo.internal.dispatcher Boolean false Whether the EventDispatcher should be enabled. The default value is false. Set it to true when running large-scale applications.
Manifest IPOJO-Internal-Dispatcher Boolean false Whether the EventDispatcher should be enabled. The default value is false. Set it to true when running large-scale applications. Notice that case is ignored (IPOJO-INTERNAL-DISPATCHER works as well as IPOJO-Internal-Dispatcher).