Framework Architecture

This document describes the basic modules of the mBS framework.

Contents:


System Architecture

The framework implementation of the mBS is composed of modules each providing separate functionality.

Framework Architecture Model
Figure 1: mBS framework architecture.


Startup

The Startup module executes the essential initialization and loading of the framework and its modules:


Boot

The Boot module is responsible for installing a predefined set of bundles at framework startup.

By default, the Boot module takes the initial bundle set from a boot INI file, which contains bundle intallation instructions (like install, start, stop) in XML format. The boot INI file may also contain the initial start level and required permissions of startup bundles.

The logic of the boot process can be customized by defining a boot extension - such an extension can perform its own installation process instead of the default one. A boot extension can also be used to preserve the default boot logic implying the use of a boot INI, but to load the boot INI from a remote URL since the framework initially locates the boot INI as a resource in the local file system.

Refer to the "Boot INI and Boot Extension" document to get more information on the boot INI features and format.

The Boot module might be disabled by setting the mbs.boot.disableProcessing system property to true.


Start Level

The mBS framework supports bundle start levels, as defined in the OSGi Start Level Specification. Briefly, the framework starts those bundles which have a start level less or equal to the framework active level. Similarly, it stops installed bundles in level descending order.

The framework active start level is determined through the mbs.startlevel system property at startup. Runtime framework and bundle start levels can be changed with the startlevel text command or with the mConsole.

Bundle start levels at framework startup are specified in a boot INI, which sets 5 as initial bundle start level. The framework considers the bundles from the boot INI as system bundles, and all bundles installed after installing those boot bundles - as application bundles. Such application bundles are associated with a special , more restrictive, start level, which is determined as the value of the mbs.applicationBundleStartLevel system property (default is (<highest_level_from_boot_ini>+1)).

Management bundles can use the OSGi Start Level service of the System Bundle to dynamically change the framework active level and the start levels of bundles.


Bundle Manager

The Bundle Manager manages the installation and the life cycle of bundles. It loads bundles from the ready storage if available or installs the bundles defined in the boot INI file. Next, loaded bundles are activated according to their start level.


Bundle Loader

The Bundle Loader module implements the com.prosyst.mbs.framework.classloader.ClassProvider interface and the framework uses it for loading the classes of bundles.

There are modifications of the bundle loader for security mode of the framework, and for working with bundles packed in JXE files and in Tao native format.

You can define a custom bundle loader by providing a class that implements the com.prosyst.mbs.framework.classloader.ClassProvider interface and extends the java.lang.ClassLoader class. The loader class must have a constructor with a single argument com.prosyst.mbs.impl.framework.BundleLoader. Your bundle loader implementation can call the generic BundleLoader to retrieve useful bundle management utilities.

Finally, to make the framework use your loader, set the mbs.loader.type system property to custom and use the mbs.loader.class one to specify the name of the class implementing ClassProvider.

Note: As the BundleLoader class interface is considered as internal and is not included in the API documentation, contact ProSyst for more information on their structure and usage.


Package Manager

The Package Manager module manages package dependencies between the bundles in the framework.

Tip: There are some useful issues about the Package Manager in the "Issues" document.


Service Manager

The Service Manager handles service-related operations in the framework, such as service registration and retrieval.


Event Manager

The Event Manager manages the listener registration and cares to send events synchronously or asynchronously (in a separate event delivering thread).


Handlers Manager

The Handlers Manager module implements the OSGi URL Handlers Service Specification. It is responsible for extending the Java runtime with new URL schemes and content-types, provided, respectively, by URL Stream Handler and Content Handler services in the framework.

Due to differences between the URLStreamHandler class in JDK 1.2.x, JDK1.3.x and CDC/Foundation, to enable the correct work of the Handlers Manager:

Note: In addition, the Framework Professional Edition Package provides framework implementations designed for specific VMs:


ProSyst Security Manager

The ProSyst Security Manager extends java.lang.SecurityManager to make native libraries work on JDK1.1 compatible VMs. This manager is also needed by the Security module.

The ProSyst Security Manager also has some additional functions not related directly to the Java security model:

The features of the ProSyst Security Manager are available in the following cases:


Security

The Security module is responsible for security-related operations. It works with the security models of Java 2 and PersonalJava. The security module is activated if the ProSyst Security Manager is on (if one of the system properties mbs.sm or mbs.resman.enabled has value true) and the mbs.security property has value different from none.

In addition, this module implements the following services of the System Bundle:

You can develop a custom Security module by implementing the com.prosyst.mbs.framework.security.Security interface, setting the mbs.security system property to custom and declaring the implementation class through the mbs.security.class system property.


Certificate Manager

The Certificate Manager module provides means for checking the trust of certificates against a certificate storage. The Certificate Manager is available only if the mbs.certificates system property is true.

For more information about the functionality that the Certificate Manager offers, refer to the "Certificate Manager" document.


System Bundle

The System Bundle registers as services modules that are part of the framework and can be used by management bundles for execution of administration operations. The bundleID of the System Bundle is always 0. Its lifecycle cannot be managed as conventional bundles, because its state is tightly bound to the state of the framework. For example, to stop the System Bundle means to shut down the framework and to update it - to restart the framework (possible through the mBedded System Agent).

It is possible via system properties to add to the System Bundle export-packages, activators and configurations, placed in the framework JAR or added to the classpath. This saves great part of the resources, consumed for activation of bundles, as no bundle objects and class loaders are created.

For more details about the features of the System Bundle, refer to the "System Bundle" document.


Storage

The Storage module is responsible for the operations with files - ZIPs, JARs, native libraries, and for providing a java.io.File object when a bundle calls getDataFile from BundleContext.

The Storage module has three implementations:

Storage on top of java.io

Operates on the standard I/O library from the java.io package. This storage works with ZIP files through the java.util.zip API. You can use the ProSyst ZIP implementation as well, which is pure Java.

This type of storage is activated through the mbs.storage.impl system property with value com.prosyst.mbs.impl.framework.module.storage.file.StorageImpl.

With this type of storage you can benefit from the following features:

Storage on top of java.io with Connector Support

Uses the I/O facilities from the java.io package and supplies a Connection Factory for the Connector Version of the framework. This storage works with ZIP files through the API from the java.util.zip package. You can use the ProSyst ZIP implementation as well, which is pure Java.

This type of storage is activated through the mbs.storage.impl system property with value com.prosyst.mbs.impl.framework.module.storage.file.StorageImpl.

Storage on top of MMFS with Connector Support

Uses the MMFS module of the framework and provides a Connection Factory for the Connector Version of the framework. You activate the Storage on top of MMFS with Connector Support by setting the mbs.storage.impl system property to com.prosyst.mbs.impl. framework.module.storage.mm.StorageImpl.

The storage on top of MMFS uses the ProSyst support of ZIP files.

You can disable the support of native libraries by setting value false to property mbs.storage.mm.nativelibs.

Custom Storage

You can provide a custom storage by implementing the com.prosyst.mbs.framework.storage.Storage interface and declaring it with the mbs.storage.impl system property. Developers may contact ProSyst in order to receive more details about storage implementation.


Memory Model File System

The MMFS is intended mainly for gateway platforms that are not capable of persistent storage, do not have hierarchical file system, or provide incomplete support of the java.io package. You should specify appropriate values to the system properties mbs.storage.mm.cluster.count and mbs.storage.mm.cluster.size, which determine the number and size of data clusters to segment an MMFS into.

All currently supported MMFS modifications can load data from a remote built storage represented as a storage.mbs file. The remote URL, where the corresponding storage.mbs is accessible, should be specified with the mbs.storage.url system property.

There are two implementations of MMFS, which are described below.

File

All information is kept in a single java.io.RandomAccessFile object, which is physically situated on an external data bearer - Hard Disk Drive, flash, etc. You activate it by setting file to the mbs.storage.mm.type system property.

The File MMFS uses a locally stored storage.mbs. The name/location of this file can be altered with the mbs.storage.mm.file.name system property.

RAM

Storage on RAM memory which is persistent only for the current framework session, that is on framework restart data is lost. You activate this MMFS implementation by setting value ram to the mbs.storage.mm.type system property.

Custom MMFS

You can use ProSyst's MMFS, but change the way in which the external bearer is accessed. In such case implement the com.prosyst.mbs.impl.services.mm.logic.MemoryModel interface. Then set the mbs.storage.mm.type system property to custom and declare the implementation class with the system property mbs.storage.mm.impl. For more details, you can contact ProSyst.


Flash Manager

The mBS framework offers a flash manager, which can be used for transferring bundle data files from a flash file system, which is persistent but with slow write access, to a temporary storage on a RAM file system, which is not persistent but is with much faster access. After the operations with files on the RAM are done, they can be flushed from the RAM to the flash storage overwriting the original files. In this way the benefits of both flash and RAM storage can be used.

The flash manager is available as a System Bundle service in the Standard Version of framework. It can be configured with the mbs.storage.ramroot, mbs.storage.flashmgr.replace, mbs.storage.flashmgr.flatram and mbs.storage.norename system properties. Note that the flash manager service is registered only if the mbs.storage.ramroot property is set.


Framework Loader

The framework contains own class loader, called the Framework Loader, which should be used when working with extension bundles.

It is not needed to restart the framework when installing framework extension bundles - the classes from the extension are internally added to classpath of the framework. Yet, in the case of a boot classpath extension, the requirement to restart framework remains. In this case, when the Framework Loader is enabled, the framework will add the extension to the bootclasspath and will restart itself automatically by using the proper command line from the JVM-specific starting script.

To make the framework use the Framework Loader for loading framework core and extension classes, prior to starting the framework set the mbs.customFrameworkLoader system propery to true in the framework starting script (see "Starting the Framework"). The scripts in the Framework Professional Edition Package distribution activate the Framework Loader by default.

Additionally, to have support of extension bundles, the properties org.osgi.supports.framework.fragment, org.osgi.supports.framework.extension and org.osgi.supports.bootclasspath.extension should also be set to true in the starting script or in framework properties file (default.prs).

Tip: The framework writes the locations of bootclasspath extension bundles into a script file, called bootcp.set, in the working directory (i.e. in bin/vms/<vm_name>) and on startup includes the script file content in the bootclasspath.

Tip: Use the mbs.noFwRestart system property to prevent the framework from restart when installing or updating bootclasspath extension.

Note: If you have launched the framework by writing a custom command line, the automatic restart feature of the Framework Loader will not be available.


Fault Manager

The Fault Manager module can be used to signal fault situations which depending on the Fault Manager implementation may be resolved through device reset, restart of the framework process, etc., so as to avoid further damage.

The Fault Manager is a customizable module - different implementations can exist, each reflecting a specific fault solution method.

By default, there is no active Fault Manager implementation in the framework. Such can be specified with the mbs.fm.class system property.

The default Fault Manager implementation that the framework contains is com.prosyst.mbs.impl.framework.module.fm.FaultManagerImpl. It records fault messages in a file.

The active Fault Manager implementation can be accessed as a System Bundle service. To reduce development efforts, bundles can conveniently use the log reference utility of the ProSyst Util Bundle to indicate fault situations.


Tracer

Bundles as well as the framework itself can use the Tracer module to send log messages about their current status or about the operations being executed to a remote visual application, such as the mConsole, or to preserve the messages for future reviewing.The remote visual application can then filter the information according to user preferences.

The Tracer is able to send message in synchronous and asynchronous manner. It is available as a System Bundle service and can be used to provide tracing information about a module. Nevertheless, it is recommended that bundles use the Tracer module through the log reference utility of the ProSyst Util Bundle.

By default, the Tracer module is turned off. It can be activated by setting the mbs.tracer.impl system property to default.

Tracer Transport

Messages are carried to their remote destination over a tracer transport - TCP, UDP, etc. Initially, TCP is supported.

It is possible to provide a custom Tracer transport - it must implement the com.prosyst.mbs.framework.tracer.TraceRemoteLogger interface and then set it with the mbs.tracer.transport system property.

Custom Tracer

You can provide a custom Tracer. In such case it is necessary to implement the org.osgi.framework.ServiceFactory interface by providing a default constructor and instances of com.prosyst.mbs.framework.tracer.TraceService in the getService method. Then, the ServiceFactory implementation class should be specified with the mbs.tracer.impl system property.


Bundle Requirements

Bundles operating in the context of the mBS framework can define bundle requirements for system resources, permissions and runtime platforms. Refer to the "Bundle Requirements" document for more details.


Resource Management

The mBS framework provides means for enhanced management of system resources required and consumed by bundles. Refer to the "Resource Management" document for more details.


Framework Access

The Framework Access module provides access to some of the framework's powerful features, such as:

This module is available as a service of the System Bundle and is intended mainly for internal use.


Framework Measurement

The Framework Measurement module is capable of measuring consumption of specific memory type on Java level and on OS native level. See the "Framework Measurement" document for further details.


Transaction Manager

The Transaction Manager module provides transactional behavior to applications. It allows applications to manage transactions (begin, commit, rollback, etc.) as well as to add transactional logic to existing transactions. The Transaction Manager is available as a service under the org.mbs.services.transaction.TransactionManager interface in case the mbs.tm.class system property is set to a Transaction Manager implementation class name. The default implementation of the Transaction Manager is com.prosyst.mbs.impl.framework.module.transaction.TransactionManagerImpl.

You can implement your own Transaction Manager (org.mbs.services.transaction.TransactionManager) and specify its class name under the mbs.tm.class property prior to starting the framework.


Additional Features

Update Modes

When a bundle is updated or uninstalled, there are two ways to handle the bundles that depend on it ( bundles that import packages from this bundle):

The update mode can be changed at runtime from the framework console through the updatemode command. See "Framework Commands" for more details about the commands available in the framework console.

Resolving Bundles

The framework allows you to control the way in which bundles export packages and are resolved - after installing a bundle or before a bundle is started. This is done through the system property mbs.bundles.resolve. If this property is set to true (the default is false), after installing a bundle the framework will try to resolve it (this includes exporting its packages in the framework).

A resolve check can be made in three other cases:

  1. The bundle's start method is called.
  2. The bundle's manifest headers have been processed and the framework tries to resolve another bundle that imports a package with the same definition as a package exported by this bundle.
  3. The bundle's manifest headers have been processed and the getState method for the bundle is called.

Factory and Dynamic Storage

The Storage on top of java.io is capable of using factory and dynamic storage.

A factory storage keeps an initial set of bundles with their archives, native libraries and data files, which cannot be changed by mBS's OSGi framework. In this way, the framework can easily restore its initial state in case of a fault.

Dynamic storage (default) is defined to include data for bundles installed or updated through the OSGi Framework API. As this storage is supposed to keep frequently changing data, it can be placed on a special R/W file system (e.g. RAM or flash).

Benefits from Using Factory and Dynamic Storage

How the Framework Treats Bundles from Factory Storage

mBS's OSGi framework treats bundles included in a factory storage as installed from file as their JARs remain at their original location, and only their manifests and related data files are copied to the framework storage. The factory storage keeps the original locations of its bundles in a file (f.st) so that they can be located at startup. Bundles can be placed in a common directory or in different ones depending on the system requirements.

In addition, if explicitly specified and if the installed bundle JAR file is originally located in a directory called bundles, the bundle's manifest and data files may be saved to the parent directory of the bundles one within a subdirectory, called data, and not be placed in the default framework storage location.

If a bundle changes its data files or is updated through the OSGi Framework API, the changes are written into dynamic storage and thereafter the data from dynamic storage is used. The bundle is not considered as installed from file anymore, but as regularly installed one.

Dynamic storage is with higher priority than factory storage – if there is data in both storages for a bundle, the framework will use the one from dynamic storage. If a bundle is uninstalled, its data will be deleted from dynamic storage.

How to Install a Bundle for Factory Storage

Factory storage should be explicitly modeled by adding installed from files bundles to the framework, which as a result will produce the appropriate storage structure and content. Installing bundles from factory storage should be done in a special way not defined by the OSGi Framework Specification - at framework runtime through an option of the fw.install command and at framework startup through the boot INI file.

Storage Tamper Protection

When started with Storage on top of java.io, the framework supports a mechanism for tamper protection of its storage. In order to avoid tampering with stored bundles and specially with extension bundles, when a bundle is installed in the framework and is stored outside a "trusted" directory, the framework calculates its CRC checksum and saves it persistently. When the framework is restarted, it recalculates the checksum and compares the new value with the stored one. Bundles whose old checksums do not match the new ones, are removed from the framework.

The trusted storage directory is determined as the value of the mbs.storage.trustedRoot system property.

JXE Support

If you are using the J9 VM and the Standard Version of the framework, you can convert the framework JAR to a JXE file and pack your bundles in JXE files, instead of in JARs. This increases the size of the framework and bundles, but makes them faster to load.

Tip: For more details about starting the framework via its JXE, refer to "Starting the Framework on J9".

To be able to use JXE bundles, before starting the framework set the system property mbs.loader.type to jxe22 for J9 2.2 and J9 2.3.

Watchdog

The main goal of watchdog feature is to prevent from the following situation - if during initial framework startup/shutdown a bundle from the initially-loaded set hangs in the start or stop method of its activator, the whole framework will not start or stop correctly. The watchdog enables initial startup and shutdown of the framework in a separate thread with defined timeout (mbs.core.timeout) for starting and stopping of each bundle. The watchdog can be turned on (default) and off by using the mbs.watchdog system property.

Restricting the Number of the Bundles, Services and Listeners

It is possible to limit the number of installed bundles, registered services and listeners (defined in the OSGi Framework Specification). These limits take effect when the following methods are invoked:

The number of bundles, services and listeners are respectively defined with the mbs.bundle.count, mbs.service.count and mbs.listener.count system properties. By default, no limits are imposed.

Redirecting the Framework Output and Input

Some platforms do not offer a console, or the console has a small buffer. On such platforms it is better to redirect the system output of the framework to a file or to a remote console.

The remote console is a simple application that opens a TCP/IP socket on port 2000 and writes in the System.out all data received from the framework as well as forwards all data entered in the System.in back to the framework. Tune the input and output settings through the input and output system properties.

Log Dispatcher

The framework contains a dispatcher for log messages which prints in the system output logs by arranging them in a queue. This allows the framework and bundles to log information in the runtime console by means of non-blocking method calls. The use of the log dispatcher in the framework can be activated with the mbs.usedispatcher system property.


References


Framework Concepts