In this and the following article, part 4 of the OSGi Demystified series, Ivan presents a collection of OSGi hors d’oeuvres. They may not be worthy of a full meal each, but they are important in their own right and make it into our roundup of best practice. If this is the first time you’ve seen Invoke Ivan’s series on OSGi Demystified, check out his previous blogs here.
- Using common OSGi bundles
- Accessing Properties files in an OSGi bundle
Using common OSGi bundles
Inevitably, at some point in larger applications, you’ll realise that some of your OSGi bundles provide common services to a number of applications. Or that you use third-party libraries in multiple applications. Either way, you may find the OSGI_BUNDLES option of the JVM profile and concluded that it allows you to install a list of common/library OSGi bundles. The OSGi bundles in that list are automatically installed when the OSGi JVM server goes enabled. However, you may also have realised that the same OSGi bundles can be installed as CICS bundle parts in a CICS bundle. So what’s the difference?
Ultimately both routes achieve the same result, so it is a matter of preference and architecture. By adding the OSGi bundles to the OSGI_BUNDLES option you have a simpler mechanism to install libraries that does not require CICS bundle packaging. The library bundles are guaranteed to be available by the time the first application runs, and they are guaranteed to be unchanged for the duration of the JVM server’s enable status. Conversely, an OSGi bundle installed using a CICS bundle provides more flexibility, an independent life-cycle (managed by the CICS bundle) and the potential to be updated at runtime. However, the install ordering of CICS bundles relies on you to ensure that libraries are installed before applications. It also requires a more complex deployment process to ensure the libraries are installed regardless of the CICS start-up procedure – whether that be CSD group, warm restarts, SPI or initial start.
We often refer to the OSGI_BUNDLES installed libraries as middleware bundles. If you are confident these OSGi bundles will not need to be dynamically updated or to have independent life-cycling, then use of this option can reduce the complexity of deployment and the burden of ordering the install sequence.
For more information: JVM server profile options
Properties files and OSGi
A common approach to configuring applications is to use a properties file. In the most basic case, a properties file resides in a hard-coded location outside of your application. A refinement to that basic approach is to pick up a system property that instructs your application where to find the properties file. Despite offering a little more flexibility, the configuration is still entirely separate from your application – and can lead to errors.
File file = new File("/u/ibm/test.properties"); FileInputStream fileInput = new FileInputStream(file); Properties properties = new Properties(); properties.load(fileInput); fileInput.close();
A natural evolution for OSGi is to place the properties file inside the OSGi bundle so that the application and configuration remain together. However, by placing the properties file inside the bundle, you are no longer in control of the actual file-system location of the file when the bundle is installed. To combat this problem, you can use use the bundle’s classloader in conjunction with the getResourceAsStream() method to find and load the properties, as shown below:
InputStream inputStream = getClass().getResourceAsStream("/test.properties"); Properties props = new Properties(); props.load(inputStream);
Ultimately you might wish to look at using the OSGi Configuration Admin service. The OSGi Configuration Admin service defines a mechanism for managing, creating, and passing configuration settings to an OSGi bundle. Put simply, configuration is a list of name-value pairs which can be created and managed by a management application. The management application, perhaps a GUI front-end for configuring properties, creates or updates the configuration and passes it to the Configuration Admin Service. The Configuration Admin Service acts like a central hub and persists/distributes the configuration to interested parties. Interested parties, such as your OSGi bundle, register as ManagedService services and declare their interest in the configuration (via a unique ID).