Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Anchor
top
top

In This Section

Table of Contents
maxLevel2

...

Plugin versus OSGi bundle

A plugin is an OSGi bundle that XperienCentral is capable of dealing with. A plugin implements the OSGi specification but also implements XperienCentral-specific logic not defined by the OSGi specification. It is important to understand the differences between a plugin and OSGi bundle:

  • A plugin is an OSGi bundle, however,  an OSGi bundle not necessarily a plugin. A plugin is a specific type of OSGi bundle.
  • An OSGi bundle is unaware of the concept of components, unlike a plugin.
  • A plugin exists only within the active state of the OSGi bundle. In other words, the API that makes the OSGi bundle a plugin can only be accessed as long as the OSGi bundle is in an active state.

 

Back to Top

 

...

Lifecycle of an OSGi Bundle

OSGi bundle states

An OSGi bundle can be in one of the following states:

...

PropertyPurpose
Installed

The bundle has been successfully installed.

Resolved

All Java classes that the bundle needs are available. This state indicates that the bundle is either ready to be started or has stopped.

Starting

The bundle is being started, the BundleActivator.start method has been called, but the start method has not yet returned.

Active

The bundle has successfully started and is running.                         

Stopping

The bundle is being stopped. The BundleActivator.stop method has been called but the stop method has not yet returned.

Uninstalled

The bundle has been uninstalled. It cannot move into any other state.

OSGi Bundle Lifecycle

The lifecycle of an OSGi bundle is depicted in the figure below. The lifecycle starts with the installation of the bundle. If all Java classes that the bundle depends on are available, the OSGi bundle proceeds to the resolved state. From there the bundle can be started or uninstalled. When started, the bundle becomes active unless some runtime error occurs during the starting of the bundle. If that happens, the bundle remains resolved. An active bundle can be stopped in which case the bundle proceeds to the resolved state. When a resolved bundle is uninstalled it proceeds to the uninstalled state and stays there.

 

 

Back to Top

 

...

Lifecycle of a Plugin

A plugin exists only within the active state of the OSGi bundle, therefore the API that makes an OSGi bundle a plugin can only be accessed during the active state of the OSGi bundle. The API methods of a plugin that affect the lifecycle of the plugin are available on a component bundle, which is only available when the bundle is active. These methods are:

...

The lifecycle of a plugin is depicted below.

 

 

Bundle Manager Workflow

The workflow for each of the Bundle Manager methods is described below.

installBundle()

  1. installBundle() is invoked.
  2. The validity of the plugin is checked. If the platform version is not within the plugin’s platform version range (if specified), the install stops. If the platform is valid, the OSGi bundleContext.installBundle method is invoked.
  3. The bundle is installed.

update()

  1. update() is invoked.
  2. A check is done to see whether the version number of the plugin or bundle has been incremented and is higher than the currently installed version. If the version number is not correctly incremented, the update stops. If the version number is correctly incremented, the platform validity is checked.

    Note

    If the setting enable_wcb_development_mode in the XperienCentral Setup Tool (/web/setup) is set to “false”, this check is skipped.

  3. If the platform version is not valid, the update stops. If the platform is valid, the OSGi method bundle.update is invoked

start()

  1. start() is invoked.
  2. start() invokes the OSGi bundle.start method.
  3. The Dependency Manager invokes the ComponentBundleImpl.start() method.
  4. A check is done to determine whether the plugin is being started for the very first time. If it is the very first time the plugin has been started, the ComponentManager method installBundle is invoked. Proceed to step 6.
  5. If the plugin is not being started for the very first time, a check is done to see whether the WCB has been modified (updated). If the plugin has been modified, the ComponentManager method updateBundle is invoked.
  6. A check is done to see whether the service dependencies for the bundle are available.
  7. The services for the bundle are registered with the OSGi.

stop()

  1. stop() is invoked.
  2. The OSGi method bundle.stop is invoked.
  3. The bundle’s services are unregistered from the OSGi.
  4. uninstall() is invoked.
  5. Should the plugin be purged? If yes, the ComponentManager.purgeBundle method is invoked.
  6. If the plugin is not purged, the ComponentManager.uninstallBundle method is invoked.
  7. The OSGi method bundle.uninstall is invoked.

uninstall()

  1. uninstall() is invoked.
  2. Should the plugin be purged? If yes, the ComponentManager.purgeBundle method is invoked.
  3. If the plugin is not purged, the ComponentManager.uninstallBundle method is invoked.
  4. The OSGi method bundle.uninstall is invoked.

purge()

  1. purge() is invoked.
  2. The ComponentManager.purgeBundle method is invoked.

 

Plugin Lifecycle Methods

The plugin lifecycle methods make it possible for a plugin to respond to OSGi bundle.install, bundle.update, bundle.start, bundle.stop and bundle.uninstall methods. These methods are invoked within the plugin after the OSGi method is executed. This gives you extra flexibility to perform other tasks in response to a change in a plugin’s lifecycle.

...

LifecyclePurpose
onStart()

Allows a component to attach logic to a start event. For example:

 

Code Block
themeEclipse
public void onStart() {
   LOG.log(Level.INFO, “onStart() invoked!");
}


Dependencies: onStart() is invoked after onInit() and before onInstall() and onUpdate(), therefore onStart() should not depend on logic contained within onInstall() and onUpdate():

onInit()

onStart()

onInstall()

-----------

onInit()

onStart()

onUpdate()

onInstall()

Allows a component to attach logic to an install event. For example:

 

Code Block
themeEclipse
public void onInstall() {
   LOG.log(Level.INFO, “onInstall() invoked!");
}


Dependencies: onInstall() is invoked after onInit() and onStart():

onInit()

onStart()

onInstall()

onStop()

Allows a component to attach logic to a stop event. For example:

 

Code Block
themeEclipse
public void onStop() {
   LOG.log(Level.INFO, “onStop() invoked!");
}


Dependencies: onStop() is invoked before onDestroy(), therefore it should not depend on logic contained within onDestroy():

onStop()

onDestroy()

onUpdate()

Allows a component to attach logic to an update event. For example:

 

Code Block
themeEclipse
public void onUpdate() {
   LOG.log(Level.INFO, “onUpdate() invoked!");
}


Dependencies: onUpdate() is invoked after onInit() and onStart():

onInit()

onStart()

onUpdate()

onUninstall()

Allows a component to attach logic to an uninstall event. The plugin containing the component must be in an active state in order for the onUninstall() method to be invoked. For example:

 

Code Block
themeEclipse
public void onUninstall() {
   LOG.log(Level.INFO, “onUninstall() invoked!");
}


Dependencies: onUninstall() is invoked before onStop() and onDestroy(), therefore it should not depend on logic contained within onStop() and onDestroy():

onUninstall()

onStop()

onDestroy()

onPurge()

Allows a component to attach logic to a purge event.

Note

The plugin containing the component must be in an active state in order for the onPurge() method to be invoked.

 

 

Code Block
themeEclipse
public void onPurge() {
   LOG.log(Level.INFO, “onPurge() invoked!");
}


Dependencies: onPurge() has no dependencies.

onInit()

Allows a component to attach logic to an init event. For example:

 

Code Block
themeEclipse
public void onInit() {
   LOG.log(Level.INFO, “onInit() invoked!");
}


Dependencies: onInit() is always invoked first, therefore it should not depend on logic from any other method.

 onDestroy()

Allows a component to attach logic to a destroy event. For example:

 

Code Block
themeEclipse
public void onDestroy() {
   LOG.log(Level.INFO, “onDestroy() invoked!");
}


Dependencies: onDestroy() has no dependencies:

onStop()

onDestroy()

 

Back to Top

 

...

Plugin Management Console

Another XperienCentral specific tool for plugin management is the Plugin Management console. This is a plugin available from the Configuration > Plugins option in XperienCentral. While the Felix shell TUI provides access to the OSGi bundles only (and is unaware of plugin specific functionality), the Plugins Management Console provides access to plugin-specific lifecycle methods, like purge. For more information on the Plugin Management Console, refer to the XperienCentral online help. The Plugins Management Console appears as follows:

 

 

 

Back to Top

 

...

Felix Shell TUI

Felix, the OSGi implementation that XperienCentral uses, comes with a shell tool which integrates with Apache Tomcat in order to provide command line access to the OSGi bundles. The tool can be installed by installing the org.apache.felix.shell.tu JAR file the same way you install other plugins.

...

Other commands that can be used can be found on http://felix.apache.org/site/apache-felix-shell-tui.html.

Managing Plugins from the Felix Shell TUI

In addition to the functionality available for managing plugins from the XperienCentral Plugins Management Console, there are equivalent commands available in the Felix Shell TUI that you can invoke directly from the command line. You must first install the XperienCentral-felix-shellcommands-10.x.x.jar using the Plugins Management Console or by copying it to the <XperienCentral-root>\work\deploy directory. You can find XperienCentral-felix-shellcommands-10.x.x.jar in the <XperienCentral-root>\backend\WEB-INF\bundles directory.

...

CommandPurpose
wmstart [id]

Registers services that each component within the bundle exposes if all required service dependencies are available. For each component, at the very least a component service is registered

wmstop [id]

Stops all services registered by the component.

wmupdate [id]

Updates the plugin to a newer version. If a problem is encountered during the update, the plugin is automatically rolled back to the existing version. The following describes a typical plugin update scenario:

  1. The plugin developer creates a 1.1 version of a plugin and gives it to a system administrator.
  2. The system administrator copies the updated plugin to the machine running XperienCentral. If XperienCentral is running in a clustered environment, the updated plugin is copied to the machine running the master XperienCentral instance.
  3. The system administrator determines the ID of the plugin in the Felix Shell TUI.
  4. The system administrator executes the wmupdate method, specifying the ID of the plugin to update and the absolute path of the JAR file containing the updated plugin. For example:

    wmupdate 59 file:/home/deploy/helloworld_1_1.jar

  5. The plugin is updated to the new version and is set to the active state. In a clustered environment, the plugin is also automatically updated on all slave instances.
wmpurge [id]

Removes all content that was created during and after the installation of the component.

wmuninstall [id]

Removes all content that was created during the installation of the component.

Note
  • A plugin must be in the active state before you can uninstall it.
  • If a plugin has dependencies with another plugin, you must first uninstall the dependent plugin.
  • A plugin must be in the active state before you can purge it.

 

Back to Top

 

...

Service Dependencies

A plugin may depend on services exposed by the platform or other plugins. Examples are using the Entity Manager, Data Source Manager or Configuration Management service in a plugin. To use these services a service dependency must be defined in the Activator in order to get the service injected into the component of the plugin. In the dependency you can define whether the availability of the service is required or not. When a component defines a required dependency on a service that is not available, the component will not be started at all. When the dependency is not required, the component will be started but the service will not be injected.

...

Using service dependencies as described here is a required guideline for level 1 certification, see guideline /wiki/spaces/PD/pages/24721296 of the development guidelines.

 

Back to Top

 

...

Using Services in Static Methods
Anchor
using_services_in_static_methods
using_services_in_static_methods

The service dependencies described in the previous section are always injected on instance fields (non-static). In static methods however, a non-static field cannot be accessed and so such a service dependency cannot be used. Static service injection is not supported, therefore using services acquired from a service dependency cannot be used in a static method.

...