Product extension
We can write our own Liberty features, and install them onto an existing Liberty profile server, or we can package them for delivery to the users.
The Liberty profile provides various SPIs we can leverage to extend the runtime environment.
Product extension
A product extension is a directory on disk that is structured like the Liberty profile installation directory...
${wlp.install.dir}
It is defined to the Liberty installation through file...
${wlp.install.dir}/etc/extensions/extension-name.properties
The contents of the product extension directory are used to extend the Liberty profile. Multiple product extensions can be installed together but they must have unique names; this is enforced through the naming of the properties files. The default product extension location...
${wlp.user.dir}/extension
...does not require a properties file; content under this location is automatically detected, and is known to the runtime as the "usr" product extension.
Product extensions usually contain one or more Liberty features but can have any content that extends the Liberty profile environment, for example scripts or resources.
Install product extensions into directories not affected by updates to the Liberty profile environment.
The product extension file has the following properties:
com.ibm.websphere.productId=your_product_id
com.ibm.websphere.productInstall=absolute_or_relative_file_path
When a relative file path is used, it must be a peer of the ${wlp.install.dir} value.
For example:
com.ibm.websphere.productId=org.acme.supergui
com.ibm.websphere.productInstall=supergui/wlp-ext
Feature
A Liberty feature consists of a definition file (feature manifest), and a collection of OSGi bundles that provide classes and services corresponding to a particular capability in the Liberty profile runtime environment.
Scenarios for using a Liberty feature instead of a regular application
Implementing a function as a Liberty feature instead of as an application might be appropriate in a number of scenarios.
- Features are controlled through feature manager configuration, so they are separate from user application management.
- Feature code has access to the Liberty profile SPI, which allows deeper integration with the runtime environment.
- Features can receive user-specified configuration from server.xml, and expose their configuration settings in the development tools without the tools having to be changed.
- Features can expose classes and services to each other and to user applications.
- Features can be lightweight, with no application container dependencies.
- Features can be used to augment a particular programming model. For example, a User Feature can add support for custom Blueprint namespace handlers or Blueprint annotations to the OSGi Application programming model.
Features cannot generally be directly portable to other application servers; if portability is important we should use specification-compliant applications.
Develop a simple feature
See...
- Develop a Liberty feature manually
- Create a Liberty feature using developer tools
- Liberty feature manifest files
Use a feature in the server
To use a user-written feature in the Liberty profile server, install it into a product extension directory. This might be the predefined "user product extension" location or an extension located outside the Liberty profile installation directory. Then we can add the feature name into the server configuration.
The user product extension is a predefined directory where the server looks for additional features. The feature definition .mf file must be copied into...
${wlp.user.dir}/extension/lib/features
...and the bundle .jar files must be copied into...
${wlp.user.dir}/extension/lib
User-written features are added to the server configuration in the same way as product features. To avoid name clashes with features from different providers, features that are part of a product extension must be prefixed with the extension name. For features in the...
usr/extension/lib
...the default prefix is usr.
For example, if we have installed a feature called simple-1.0 into...
${wlp.user.dir}/extension/lib
...configure that feature into the server.xml as follows:
<featureManager> <feature>usr:simple-1.0</feature> </featureManager>
If we have installed a feature called myFeature into our own location, and defined a product extension in...
${wlp.install.dir}/etc/extensions/myExt.properties
...configure that feature into server.xml as follows:
<featureManager> <feature>myExt:myFeature</feature> </featureManager>
When we start the server, the feature is detected by the feature manager and the bundles are installed into the OSGi framework and started.
See also Add and remove Liberty features and Feature management.
Programmatically using a feature from applications
Features can expose classes and services to applications.
To expose Java classes for application use, we must list the class packages in the IBM-API-Package header in the feature manifest. Listing the class packages in the IBM-API-Package header makes the classes visible to the application class loaders. Visibility of API packages can be controlled through the API visibility type. See Specify API and SPI packages for a Liberty feature project.
To allow services to be used by OSGi applications, we must list them in the IBM-API-Service header in the feature manifest. A feature provides OSGi services so that we can refer to those services programmatically from the applications.
Services should generally be registered into the OSGi Service Registry (SR) to allow applications (or other features) to locate them. OSGi applications and other features can perform a direct lookup from the SR, or can use capabilities such as Blueprint or OSGi Declarative Services to inject their service dependencies. Java EE applications are more likely to locate services through JNDI; in the Liberty profile there is a federation of the SR and JNDI that allows Java EE applications to use JNDI to locate services in the SR.
See Work with the OSGi service registry.
Exposing a feature as a web application
To expose a Liberty feature as a web application, we can publish the OSGi bundles in the feature as web application bundles (WABs). In addition to the OSGi headers that a bundle requires, we can specify the web application context path using the Web-ContextPath header.
For example:
Web-ContextPath: myWABapp
Bundle-ClassPath: WEB-INF/classes
Configuration injection and processing
A major benefit of using features is that they can be configured by the user in server.xml (and included files). The configuration files are monitored and parsed by the Liberty profile kernel and the resulting sets of properties can be injected into the relevant component each time they change.
Liberty profile configuration is managed by the OSGi Configuration Admin (CA) service in the kernel and can be accessed according to that specification. Sets of configuration properties are identified by a persisted identity (PID) used to associate the element in server.xml with the component that registers to receive the properties.
For example, if you register the feature with the CA service using a PID of com.acme.console, a user can specify the following configuration in server.xml:
<com.acme.console color="blue" size="17"/>
...and your feature will receive the properties:
- color="blue"
- size="17"
We can optionally provide metadata that describes your configuration properties using OSGi Metatype descriptors. The use of descriptors causes the configuration metadata to be included in the configuration schema generated by the Liberty profile and is used by the Developer Tools, so the configuration properties are automatically presented to application developers as they configure their server.
For more details on receiving and describing configuration properties, see Enable a service to receive configuration data.
Declarative Services in the Liberty profile
Larger or more complex features often benefit from the use of OSGi Declarative Services (DS) to enable the feature to be composed of multiple services, and to manage the injection of dependencies and configuration properties. The use of DS allows lazy activation of services, deferring the loading of Java classes until the service is used, and ordering the activation of services based on dependencies. Most of the features in the Liberty profile product are managed by DS.
See also Composing advanced features using OSGi Declarative Services.
Parent topic: WebSphere Application Server Liberty Core: OverviewTasks:
Develop a Liberty feature Develop a custom TAI as a Liberty profile feature Develop a custom user registry Develop a custom thread identity service Describing configuration using the OSGi Metatype service Reference:
Single versus multiple configuration instances Extensions to the OSGi metatype service