116 Application Admin Specification

116.1 Introduction

The OSGi Application Admin specification is intended to simplify the management of an environment with many different types of applications that are simultaneously available. A diverse set of application types are a fact of life because backward compatibility and normal evolution require modern devices to be able to support novel as well as legacy applications. End users do not care if an application is an Applet, a Midlet, a bundle, a Symbian, or a BREW application. This specification enables applications that manage other applications, regardless of application type. These applications are called application managers. This specification supports enumerating, launching, stopping and locking applications. This specification does not specify a user interface or end-user interactions.

The OSGi Framework is an excellent platform on which to host different Application Containers. The class loading and code sharing mechanisms available in the OSGi Framework can be used to implement powerful and extendable containers for Java based application models with relative ease. Native code based application models like Symbian and BREW can be supported with proxies.

116.1.1 Essentials

  • Generic Model - The Application Admin specification defines how all applications, regardless of type, can be launched and destroyed. This application-type neutral model allows a screen or desktop manager access to all executable content in a uniform manner.

  • Schedule - A mechanism that allows the launching of applications at a predefined time, interval, or event.

  • Dynamic - Detects installations and uninstallations of applications in real time.

  • Locking - Allows applications to be persistently locked so that they cannot be launched.

  • Exit Value - Provide a return value for an application that has exited.

116.1.2 Entities

  • Application - A software component, which has well-defined entry and exit criteria. Applications can be started and destroyed, and usually are designed for user interaction. Applications may be of various types, each having their own specification. Applications and application instances are visible through the their Application Descriptor services and Application Handle services.

  • Application Container - An implementation of a runtime environment for one or more application types. It provides specialized Application Descriptor and Application Handle services that correspond to the supported application type and their instances. The design of a particular Application Container is defined by other specifications. For example, an Application Container which implements MIDlets must follow the appropriate JSR specifications for MIDP.

  • Application Handle - A service that represents an instance of an application. This service is available in the OSGi service registry as long as the application instance exists.

  • Application Instance - The actual application that has been launched. Registered in the service registry as long as the application is running.

  • Application Descriptor - A service that represents an installed Application and provides information about the application as well as launching, scheduling and locking features. An Application Descriptor must be registered for each application as long as the Application is installed

  • Application Manager - A bundle that manages a number of applications.

  • Scheduled Application - An information record for a scheduled application.

Figure 116.1 Application Management Diagram org.osgi.service.application package

Application Management Diagram org.osgi.service.application package

116.1.3 Synopsis

Different types of applications can be accommodated in the Application Admin specification using a model of Application Containers. An Application Container typically follows an external specification, for example, the MIDP specification. In an OSGi environment, the implementer of such a specification can allow its applications (MIDlets in the previous example) to participate in the OSGi Application Model by registering an Application Descriptor service for each of its installed applications, and an Application Handle service for each of its running instances.

This model leverages the capabilities of the OSGi service registry. Installed applications and running applications can be found by enumerating the appropriate services, possibly using a filter if a specific application is sought. The service registry provides necessary isolation of the clients of the applications and their implementers. Typical clients of this specification are desktop/screen managers that provide the end user access to the installed applications.

116.2 Application Managers

An application manager (a bundle or application that manages other applications) must be able to discover the available applications, present them to an end user and launch applications on demand. A bundle that maintains the display of a mobile phone is a typical client of this specification.

116.2.1 Discovery

The primary means of discovery is the Application Descriptor service. An Application Container must register an Application Descriptor service for each of its applications. An application manager can detect the installation and uninstallation of applications by listening to service events.

Service properties on the Application Descriptor carry most of the information that an application manager requires to present the application to the end user. The properties as defined in the following table.

Table 116.1 Service Properties for an Application Descriptor

Key Name

Type

Default

Description

service.pid

String

must be set

Unique identifier of the application. It is recommended to set a value generated from the vendor's reverse domain name, e.g. com.acme.application.chess. The service.pid service property is a standard Framework property.

application.version

String

empty string

Specifies the version of the application. The default value is an empty string

service.vendor

String

empty string

Specifies the vendor of the application.

application.container

String

must be set

A unique identifier (like a PID) of the container implementation that registered this application descriptor.

application.location

String

must be set

The identifier of package that contains the application corresponding to this descriptor. It represents the installation unit that contains the corresponding application. It should be a URL. For applications installed as bundles, it should be the location of the bundle. For others, it is defined by the container implementation.

application.visible

Boolean

true

Specifies whether the application should be visible for the user. For example, some applications may provide features to other applications but nothing directly to the user. In this case the application should not be revealed to the user to start it individually.

application.launchable

Boolean

false

Specifies whether the application is ready to be launched. If the value is true, it means that all the requirements of the application are fulfilled.

application.locked

Boolean

false

Specifies whether the represented application is locked to prevent launching it.


Specialized application descriptors can offer further service properties and method. For example, a MIDP container can register a property that describes that the MIDLet comes from a specific JAD file, thereby allowing a MIDLet aware Application Manager to group these MIDLets.

Application Descriptor services must not be declarative. That is, they can be obtained from the service registry at any time without accidentally initializing a class loader.

The following example shows how to track all visible, launchable, and unlocked applications. These tracked applications are the ones that can be started.

public class TrackLaunchables {
    final static String filter=
        "(&(objectclass="
    +   ApplicationDescriptor.class.getName()
    + ")(application.launchable=true)"
    + "(application.visible=true)"
    + "(application.locked=false))";
    static ApplicationDescriptor[] EMPTY = 
        new ApplicationDescriptor[0];  
    ServiceTracker tracker;

    public void init(BundleContext cntxt) throws Exception {
        tracker = new ServiceTracker(cntxt, 
            cntxt.createFilter(filter), null);
        tracker.open();
    }

    public ApplicationDescriptor[] getActive() {
        Object [] result = tracker.getServices();
        List list = Arrays.asList(result);
        return (ApplicationDescriptor[]) list.toArray(EMPTY);
    }
}

The code is quite simple because the Service Tracker does the actual tracking. The most important part is therefore the filter. The filter selects all the Application Descriptor services that are visible, launchable, and not locked. The getActive method converts the Object[] that the Service Tracker maintains into an array of Application Descriptors.

116.2.2 Application Descriptor Properties

The Application Descriptor object has an additional number of properties that are not available as service properties. These descriptor properties can be localized. The getProperties(String) method therefore takes a locale String object. This is a standard locale string as defined by the java.util.Locale class. The order for the locale constituents is:

  • language

  • country

  • variant

For example, the following files provide manifest translations for English, Dutch (Belgium and the Netherlands) and Swedish.

en          nl_BE           
nl_NL       sv

It returns a Map object containing localized versions of the properties. This is a copy of the original objects so changes to this Map object are not reflected in the Application Descriptor properties.

If the locale string is null, the localization will be based on the default locale, as specified by the java.util.Locale.getDefault method. If the locale is the empty String object (""), no localization must be used. This will contain the raw values that are usually used as keys. If a specific locale has no appropriate translations, a less specific locale must be used, as described in the Locale class. As last resort, the raw values must be returned.

The key names in the Map object are case-sensitive. Application Containers can add additional properties to this Map object, however, they must avoid key names starting with application. They should use key names that have a prefix that does not collide with other Application Containers.

If no locale specific value of an application property is available then the default one must be returned. The following case-sensitive key names are treated as standard for locale specific values in the Map object. Additional elements may also be stored in the Map object. The specified properties are explained in the following table.

Table 116.2 Descriptor localized properties

Key Name

Type

Default

Description

application.name

String

must be set

The name of the application.

application.icon

URL

No Icon

A URL an icon's image resource. A compliant implementation of this specification must support the [1] PNG Image Format.

application.version

String

0.0.0

The version of the application

service.vendor

String

The vendor of the application

application.visible

Boolean

true

application.launchable

Boolean

true

If the application can be launched

application.locked

Boolean

true

If the application is locked

application.description

String

A description of the application

application.documentation

String

Document

application.copyright

String

A Copyright statement

application.license

String

A URL to the license related to the application

application.container

String

must be set

The PID of the associated container

application.location

String

The URL of the location of the corresponding JAR file of the application, if exists.


116.2.3 Launching

The Application Descriptor provides the launch(Map) methods for application managers to launch an application. Launching consists of creating the specific application object, starting it, registering an Application Handle service that represents that instance and return the Application Handle service.

The Map object parameter is application specific. Applications should use unique names for the keys in this map, for example com.acme.ringsignal. This specification does not specify any keys for this map except for:

  • org.osgi.triggeringevent - This property is set to the Event object that cause the application to be launched (if any).

When an application is started successfully the corresponding Application Handle service will be registered with the service registry.

116.2.4 Application States

An Application Handle service represents an instance of an application. The application handle is registered by the Application Container after successfully launching a new application instance.

An Application Handle service can be used to query the state and manipulate the application instance. It is the responsibility of the Application Handle service to maintain the application instance life cycle state by interacting with the implementation object of the application.

A running instance can have the following state according to this specification:

  • RUNNING - This is the state of the Application Handle when it gets registered. It indicates that the application instance is active.

  • STOPPING - The application is stopping. This is a transient state.

Application Containers can extend the number of states.

The Application Handle service maintains the service properties as listed in the following table. Specialized application handles may offer further service properties, but the key names specified in the table below must not be used for other purposes.

Table 116.3 Application Handle service properties

Key Name

Type

Default

Description

service.pid

String

must be set

The Application Instance ID as returned by the getInstanceId method.

application.state

String

must be set

Contains the current state of the application instance represented by this application handle. These states can be application model specific.

application.descriptor

String

must be set

The PID of the associated Application Descriptor service


Specialized application handles may offer further application states. The name of additional states must be qualified names (dotted); non-qualified names are reserved for future specifications.

116.2.5 Destroying an Application Instance

An application instance can be stopped with its associated Application Handle using the destroy() method. This first turns the state of the Application to STOPPING. The application instance may save its persistent data before termination and it must release all the used resources. The application instance's artifacts should not be reused any more. The Application Admin implementation and the application container should ensure (even forcefully) that all allocated resources are cleaned up.

If the application instance has completely stopped, then its Application Handle must be unregistered.

116.2.6 Getting the Exit Value of an Application

Many application containers allow an application to specify a value when the application is stopped. This value is called the exit value. The Application Handle can therefore return the exit value when this is supported by the underlying application model. It is possible to find out if the underlying container support exit values because not all application containers support exit values.

The Application Descriptor has a special service property that it must set when it supports exit values. This service property name is defined on the ApplicationHandle class as APPLICATION_SUPPORTS_EXITVALUE. Setting this property to any value signals that the application instance supports an exit value return.

The getExitValue(long) method on the ApplicationHandle class returns the exit value object from the underlying application container. If the application container does not support exit values, then this method must always throw an Unsupported Operation Exception.

The method takes a time out value which allows it to wait for the application instance to finish. This time-out can take the following values:

  • negative - When the time-out is negative, there is no waiting. If the application instance has finished, the exit value will be returned. Otherwise an Application Exception must be thrown with the error code set to APPLICATION_EXITVALUE_NOT_AVAILABLE.

  • zero - The method will wait indefinitely until the application is finished.

  • positive - The method will wait for the application to finish the given number of milliseconds. If after that time the application instance is still not finished, an Application Exception must be thrown with the error code set to APPLICATION_EXITVALUE_NOT_AVAILABLE.

The type of the exit value is undefined, it is a generic Java object. It is up to the application container to define the actual type for this Object.

116.2.7 Locking an Application

Applications represented by the application descriptors can be locked. If an application is locked then no new instance of the represented application can be started until it is unlocked. The locking state of the application has no effect on the already launched instance(s). The Application Descriptor provides the methods lock and unlock to set, unset the locking state. Locking and unlocking an application represented by an Application Descriptor requires the proper Application Admin Permission. The methods to lock, unlock, and query the locked status of an application are implemented as final methods of the abstract application descriptor class to ensure that an application container implementation will not be able to circumvent this security policy.

116.2.8 Scheduling

Scheduling can be used to launch an a new application instance in the future when a specific event occurs, if needed on a recurring basis.

The Application Descriptor service provides the schedule(String,Map,String,String,boolean) method to schedule an application to be launched when an specific event occurs. The parameters to this method are:

  • Schedule Id - ( String) An id for this application that identifies the schedule, even over system restarts. Ids must be unique for one application. This id will be registered as service property on the Scheduled Application service under the name of SCHEDULE_ID. The name must match the following format:

        scheduleId ::= symbolic-name 
                   // See General Syntax Definitions in Core
  • Arguments - (Map) These arguments will be passed to the application in the launch method. The keys in this map must not be null or the empty string.

  • Topic - (String) The topic of the event that must trigger the launch of the application.

  • Filter - (String) A filter that is passed to the Event Admin for subscribing to specific events, can be null. The syntax of the string is the same as an OSGi Framework filter.

  • Recurring - (boolean) Repeatedly launch the application when the specified events occur until the schedule is canceled.

The schedule method must register a Scheduled Application service with the service registry and return the Schedule Application service object.

For example, the invocation

appDesc.schedule(
    null,       // System generates schedule id
    null,       // No arguments
    "org/osgi/application/timer",
    "(&(hour_of_day=0)(minute=0))",
    true) 

Schedules the application to be launched when a timer event is received and the hour_of_day and minute properties are zero.

The Scheduled Application service must have the following properties:

  • APPLICATION_PID - (String) The PID of the Application Descriptor service.

  • SCHEDULE_ID - (String) a unique id (within the schedules for one application).

The list of active Scheduled Application services can be obtained from the service registry. A non-recurrent Scheduled Application service is unregistered once the application is successfully launched.

The timer used to start an application from a schedule has a resolution of one minute. It is therefore possible that an application is delayed up to a minute before it is started.

116.2.9 Application Exceptions

Exceptional conditions that arise during processing of application requests. The Exception identifies the actual error with an integer code. The following codes are supported:

116.2.10 Application Events

The event mechanism of the Application Admin specification is based on the OSGi service registry event model. Both Application Descriptor and Application Handle are services. Bundles can listen to these events registering a ServiceListener object with a Bundle Context or they can listen to events from the Event Admin, see for more information Service Event.

  • Application Descriptor service

    • REGISTERED - A new application has become available. Depending on its properties, this application could be launched.

    • MODIFIED - The visibility, launchable or locked status is changed.

    • UNREGISTERING - The application is no longer available. All running instances of this application must be destroyed before this event is delivered.

  • Application Handle service

    • REGISTERED - A new instance is created and started running.

    • MODIFIED - The application instance is changed its state. This specification only specifies the STOPPING state but application containers are free to add additional states. Transitions between all these states must be signaled with the MODIFIED service event.

    • UNREGISTERING - The application instance is no longer running.

116.3 Application Containers

Application Containers provide the implementation of a specific application model like MIDP, BREW,.NET, or Symbian. Application Containers can be implemented inside the OSGi environment or run externally, in another VM or as native code. When the container runs externally, it is necessary to run a proxy inside the OSGi environment that communicates with the external container. This is shown in Figure 116.2.

Figure 116.2 Application Container Model with Proxy

Application Container Model with Proxy

116.3.1 The Application Descriptor

The first responsibility of the Application Container is to register an Application Descriptor for each available application. The Application Container must therefore extend the ApplicationDescriptor base class that is provided by the Application Admin implementer and provided in the org.osgi.service.application package. The base class is defined as an abstract class in this specification with only minimal implementation code. Implementers of the Application Admin implementation can replace this class with an implementation that enforces their desired policies.

The Application Container must override the methods that have a Specific suffix. These methods are:

  • ApplicationDescriptor(String) - The Base class Application Descriptor takes the PID of the Application Descriptor as argument.

  • getPropertiesSpecific(String) - Return the properties (including service properties) based on a specific locale. See the locale rules at Application Descriptor Properties. The Application Container must fill the returned Map object with the properties listed in Table 116.2 on page as well as other service properties. Non-localized data is returned if the corresponding application container doesn't support the localization of application properties. Changes in the Map object must not be reflected in Application Descriptor properties.

  • launchSpecific(Map) - Launch a new instance and return its handle. The container must ensure that the application is started in a doPrivileged block I.e. the permissions of the caller must not influence the capabilities of the started application.

  • lockSpecific() - Do the specific locking of the Application Descriptor.

  • unlockSpecific() - Do the specific unlocking of the Application Descriptor.

  • isLaunchableSpecific() - This method must return true when the application can be launched. This method can be called by the Application Descriptor implementation to find out if an application can be launched according to the container.

The specific methods must be made protected because the specific Application Descriptor is registered as a service and is intended to be used by a wide array of clients. These clients can call public methods so care should be taken to ensure that no intrusion can take place this way. The Application Admin implementer must provide the implementation for the public methods and perform the appropriate security checks.

The specific Application Descriptor must be registered for each possible application with the set of service properties listed in Table 116.1 on page .

An application is launched with the launchSpecific method. This method is called by the Application Admin implementation, as implemented in the ApplicationDescriptor base class. The implementation of the launchSpecific method must return expediently. The Application Descriptor must perform the following steps (in the given order):

  1. Create a new instance of the associated application

  2. Start the application in another process or thread.

  3. If the application cannot be started, an appropriate Exception must be thrown.

  4. Register an Application Handle for this running application. The registration of the Application Handle must be accompanied by the service properties from Table 116.3 on page .

  5. Return the new Application Handle.

116.3.2 The Application Handle

The Application Handle represents the running instance. The Application Container must extend the provided base class and implement the following methods:

  • ApplicationHandle(String,ApplicationDescriptor) - The constructor of the base class takes the executable id and the Application Descriptor as parameter.

  • destroySpecific() - Clients of the Application Admin specification use the destroy method on the Application Handle service to make an application instance quit. The Application Admin implementer must at an appropriate time call the destroySpecific method. The Application Container must destroy the application instance (if it had not destroyed already) and clean up.

  • getApplicationDescriptor() - Return the Application Descriptor that belongs to this Application Handle.

  • getInstanceId() - A unique id for this instance.

  • getState() - Returns the state for the instance. The Application Admin specification only specifies two states: RUNNING and STOPPING. Application Containers can add new states to represent for example PAUSED. States are strings and must be qualified to prevent conflicts. For example, the Midlet state for paused could be MIDLET.PAUSED.

The most important method is destroySpecific. This method must perform the following actions in the given order:

  1. Set the state to STOPPING

  2. Modify the service properties of the Service Handle to reflect the new state. This sends out a service event.

  3. If the application instance is active, use any proprietary mechanism to stop it. Any errors and problems should be logged.

  4. Using proprietary means, clean up any resources on the system that were used by the application: locks, open files, etc.

  5. Unregister the Application Handle service.

The Application container should monitor the progress of its instances. If an instance stops, for example due an exception or it quits voluntarily, the Application Container must call the destroy method on the Application Handle itself and handle the fact correctly that the instance is already stopped in the destroySpecific method.

116.3.3 Certificates

The following method on the Application Descriptor provides access to the certificate chain that was used to sign the application. This method is used by the Application Permission.

  • matchDNChain(String) - Verifies that the given pattern matches one or more of the certificates that were used to sign the application. This method is primarily used by the Application Admin Permission to verify permissions. Matching certificates is described in Certificate Matching of OSGi Core Release 7.

116.3.4 Application Descriptor Example

This is an Application Container that scans a directory for executables. Each executable is registered as an Application Descriptor. The example assumes that there is a bundle activator that creates the Application Descriptor services. This activator must also ensure that when it is stopped no handles remain.

The example is not an robust implementation, its only intention is to show the concepts of the Application Admin specification in practice.

The (simple) Application Descriptor could look like:

public class SimpleDescriptor extends ApplicationDescriptor{
    ServiceRegistration registration;
    File                executable;
    SimpleModel         model;
    boolean             locked;
    static URL          genericIcon = SimpleDescriptor.class
                                            .getResource("icon.png");

    SimpleDescriptor(SimpleModel model, File executable) {
        super("com.acme." + executable.getName());
        this.model = model;
        this.executable = executable;
    }

    public Map getPropertiesSpecific(String locale) {
        Map map = new Hashtable();
        map.put(APPLICATION_ICON, genericIcon);
        map.put(APPLICATION_NAME, executable.getName());
        return map;
    }

    protected ApplicationHandle launchSpecific(
        final Map args) throws Exception {
        final SimpleDescriptor descriptor = this;

        return (ApplicationHandle) AccessController
                .doPrivileged(new PrivilegedExceptionAction() {
                    public Object run() throws Exception {
                        SimpleHandle handle = 
                            new SimpleHandle(descriptor, args);
                        handle.registration =
                            model.register(handle);
                        return handle;
                    }
                });
    }

    Dictionary getServiceProperties() {
        Hashtable p = new Hashtable();
        p.put(APPLICATION_LAUNCHABLE, Boolean.TRUE);
        p.put(APPLICATION_LOCKED, Boolean.valueOf(locked));
        p.put(Constants.SERVICE_PID, getApplicationId());
        return p;
    }

    protected void lockSpecific() { locked = true; }
    protected void unlockSpecific() { locked = false; }
    public boolean matchDNChain(String arg) { return false; }
    protected boolean isLaunchableSpecific() { return true; }
}

The associated Application Handle must launch the external executable and track its process. If the process dies autonomously or is stopped via the destroy method, it must unregister the Application Handle service. The class could be implemented like:

public class SimpleHandle extends 
    ApplicationHandle implements Runnable {

    ServiceRegistration registration;
    Process             process;
    int                 instance;
    String              state = RUNNING;
    static int          INSTANCE = 0;
    Thread              thread;

    public SimpleHandle(SimpleDescriptor descriptor, 
        Map arguments) throws IOException {
        super(descriptor.getApplicationId() 
            + ":" + (INSTANCE++), descriptor);
        String path = descriptor.executable.getAbsolutePath();
        process = Runtime.getRuntime().exec(path);
        thread = new Thread(this, getInstanceId());
        thread.start();
    }

    public String getState() {  return state; }

    protected void destroySpecific() throws Exception {
        state = STOPPING;
        registration.setProperties(getServiceProperties());
        thread.interrupt();
    }

    // Wait until process finishes or when
    // interrupted
    public void run() {
        try {
            process.waitFor();
            destroy();
        }
        catch (InterruptedException ie) {
            process.destroy();
            try {
                process.waitFor();
            }
            catch (InterruptedException iee) {
                // Ignore
            }
        }
        catch( Exception e ) {
            .. logging
        }
        registration.unregister();
    }

    Dictionary getServiceProperties() {
        Hashtable p = new Hashtable();
        p.put(APPLICATION_PID, getInstanceId());
        p.put(APPLICATION_STATE, state);
        p.put(APPLICATION_DESCRIPTOR,
            getApplicationDescriptor().getApplicationId());
        return p;
    }
}

The Application Container must create the Application Descriptor services from some source. Care should be taken to optimize this scanning so that the initialization time is not significantly increased. Running application instances should be stopped if the Application Container is stopped. The following code shows a possible implementation:

public class SimpleModel implements BundleActivator{
    BundleContext context;
    Set           handles = new HashSet();

    public ServiceRegistration register(SimpleHandle handle){
        handles.add(handle);
        return context.registerService(
            ApplicationHandle.class.getName(),
            handle, handle.getServiceProperties());
    }

    public void start(BundleContext context) throws Exception 
    {
        this.context = context; 

        File file = new File("c:/windows");
        final SimpleModel me = this;

        file.list(new FilenameFilter() {
            public boolean accept(File dir, String name) {
                if (name.endsWith(".exe")) {
                    SimpleDescriptor sd = new SimpleDescriptor(me,
                        new File(dir, name));
                    sd.registration = me.context.registerService(
                            ApplicationDescriptor.class.getName(),
                                sd, sd.getServiceProperties());
                }
                // We ignore the return anyway
                return false;
    }});}

    public void stop(BundleContext context) throws Exception{
        for (Iterator handle = handles.iterator();
            handle.hasNext();) {
            SimpleHandle sh = (SimpleHandle) handle.next();
            try {
                sh.destroy();
            }
            catch (Exception e) {
                // We are cleaning up ...
            }
}}}

116.4 Application Admin Implementations

116.4.1 Implementing the Base Classes

The OSGi specified org.osgi.service.application package that is delivered with the specification in a JAR file is a dummy implementation. The intention of this package is to be replaced by an Application Admin implementation. This implementation can then enforce policies by intercepting the calls from any Application Managers to the Application Containers.

The Application Admin implementer must re-implement the following methods in the ApplicationDescriptor class:

  • launch(Map) - The method can perform any checks before it must call the launchSpecific(Map) method. This must be a protected method. The implementation must perform any security checks. If these succeed, the launchSpecific method must not be called in a doPrivileged block.

  • lock() - Must call the lockSpecific method.

  • unlock() - Must call the unlockSpecific method.

  • schedule(String,Map,String,String,boolean) - Register a new Scheduled Application service with the given arguments, thereby scheduling the application for launching when the topic and filter match an event. A virtual event is defined for timer based scheduling, see Virtual Timer Event.

The Application Admin implementer must also implement the following method in the ApplicationHandle class:

  • destroy() - The Application Admin implementer should call the protected destroySpecific() method after which it should perform any possible cleanup operations.

Implementers must not change the signature of the public and protected parts of the ApplicationDescriptor and ApplicationHandle classes. Adding fields or methods, either public or protected is explicitly forbidden.

116.4.2 Exception Handling

The implementation of the container must ensure that Security Exceptions are only thrown during the invocation of any of the Application Descriptor methods when the required permissions are lacking. If the Application Descriptor is not valid, an Illegal State Exception must be thrown and never a Security Exception.

116.4.3 Launching

The launch method of the Application Descriptor must be implemented by the Application Admin implementer. Launching must be performed in the following steps:

  1. Verify that the caller has the appropriate permissions, see Security.

  2. Verify that the Application Descriptor is not locked and launchable

  3. Perform any policy actions that are deemed necessary before the application is really launched.

  4. Call the protected launchSpecific method. If the method throws an Exception, then this exception should be logged, and must be re-thrown.

  5. Otherwise, return the received Application Handle

116.4.4 Destroying

The implementation of the ApplicationHandle destroy method must follow the following steps:

  1. Verify that the caller has the appropriate permissions, see Security.

  2. Call the destroySpecific method. If an Exception is thrown, then this should be logged but must be further ignored.

  3. Perform any cleanup deemed necessary.

116.4.5 Scheduling

Application Descriptor services can be scheduled by calling the schedule method, as described in Scheduling. This method must be implemented by the Application Admin implementer.

Application Admin implementations must make a reasonable effort to launch scheduled applications in a timely manner. However, launching is not guaranteed, implementations can drop and forget events if it is necessary in order to preserve the stability and integrity of the device. The granularity of the timer should also be taken into account, this granularity is one minute so the actual time an application will be launched can be shifted up to 60 seconds.

If an event would launch multiple applications then the order of launching is not defined, it is implementation specific.

Launching a scheduled application is constrained by the same rules as application launching. Thus, attempting to launch a locked application on the specified event must fail to launch. Launching can only succeed when the application is unlocked.

If the scheduling is non-recurring and launching a new instance fails then when the specified event occurs again launching the application must be attempted again until it succeeds. Non recurring schedules must be removed once the launch succeeds.

The triggering event will be delivered to the starting application instance as an additional item identified by the org.osgi.triggeringevent argument in its startup parameters. This property must not be used for other purposes in the startup parameters. To ensure that no events are leaked to applications without the appropriate permission, the event is delivered in a java.security.GuardedObject, where the guarding permission is the Topic Permission for the topic to which the event was posted.

Scheduling and unscheduling an application, or retrieving information about scheduled applications requires the Application Admin Permission for the target application to be scheduled. If the target is the unique identifier of the scheduling application itself then it can schedule itself. In addition, the scheduling entity must have Topic Permission for the specified topic.

116.4.6 Virtual Timer Event

The application scheduler can use a virtual timer event for time scheduled applications. This event is not actually sent out by the Event Admin; this virtual event is only used for the syntax to specify a recurring launch.

The topic name of this virtual timer event is:

org/osgi/application/timer

The properties of the virtual timer event are:

  • year - (Integer) The year of the specified date. The value is defined by Calendar.YEAR field.

  • month - (Integer) The month of the year. The value is defined by Calendar.MONTH field.

  • day_of_month - (Integer) The day of the month. The value is defined by the Calendar.DAY_OF_MONTH field.

  • day_of_week - ( Integer) The day of the week. The value is defined by the Calendar.DAY_OF_WEEK field.

  • hour_of_day - (Integer) The hour of the day. The value is defined by the Calendar.HOUR_OF_DAY field.

  • minute - (Integer) The minute of the hour. The value is defined by the Calendar.MINUTE field.

The timer has a resolution of a minute. That is, it is not possible to schedule per second.

A property that is not included into the filter matches any value. Not including a field implies that it always matches. For example, if the minute=0 clause from the filter is missing, the timer event will be fired every minute.

The following examples are filters for the timer event to specify certain time in the device local time. The topic is always org/osgi/application/timer.

Noon every day:

(&(hour_of_day=12)(minute=0))

Every whole hour, on every Sunday:

(&(day_of_week=0)(minute=0))

Every whole hour:

(minute=0)

116.5 Interaction

116.5.1 Application Installation

Figure 116.3 shows how an application manager can be notified about the installation of a new application. The actual installation may be done prior to the notification or may be done by the application container. At the end of the successful installation the application container must register a specialized Application Descriptor service which properly represents the installed application. If the installed application's dependencies are fulfilled (which are container specific) then the application descriptor's application.visible and application.launchable properties should be set to true.

Figure 116.3 Installing a bundle that is managed by an Application Container

Installing a bundle that is managed by an Application Container

116.5.2 Launching an Application

Firstly the appropriate Application Descriptor service on which the operation will be made is fetched from the service registry. This Application Descriptor is a container specific sub-class of the Application Descriptor class. Its launch method is called which is in the base class.

The application instance may not receive the startup arguments if its application container does not support startup arguments. The launch method checks if the a new application instance can be launched, for example, that the necessary rights are granted, the application is not locked and the application is not a singleton that already has an instance.

If the application can be launched then the launchSpecific method, which is in the subclass, will create and start a new application instance according to its application container. It will create a specific application handle and associate the newly created application instance to it. The launchSpecific method will register the application handle with proper service properties. The value of application.state service property must be RUNNING. The call chain returns the application handle.

Figure 116.4 Launching an application

Launching an application

116.5.3 Destroying an Application Instance

To destroy an application, the proper application handle has to be fetched from the service registry to call its destroy() method. It checks if the instance can be destroyed, for example that the necessary permissions are granted, it then calls the destroySpecific method to let its implementation destroy the instance in an application container specific way. First, it sets the application.state service property to STOPPING then stops the application instance. Finally it unregisters the application handle.

116.6 Security

The Application Admin specification is an interaction of the:

  • Application Container implementers

  • Applications

  • Application Managers

There are two permissions used in the security model of the Application Admin specification. The first is the Service Permission that grants access to getting or registering the Application Descriptor and Application Handle services. The second security is specific for the Application Admin specification and is the Application Permission.

The Application Container must be very powerful because it starts the application code, which should be able to perform almost any function.

The security checks are performed in the ApplicationDescriptor and ApplicationHandle base classes.

116.6.1 Application Admin Permissions

This ApplicationAdminPermission class implements permissions for manipulating applications and their instances. The permission must be held by any bundle that manipulates application descriptors or application handles.

The target of the Application Admin Permission is an OSGi filter that matches a number of properties. This is similar to the Admin Permission in the Framework. Alternatively, instead of the filter the pseudo target <<SELF>> can be used.

The following properties can be tested in the filter:

  • signer - A Distinguished Name chain that is used to sign the application. The matching of this property must be done according to the rules described for DN matching in OSGi Core Release 7. The Application Admin Permission must use the ApplicationDescrptor class' matchDNChain method. Matching DN's is described in Certificate Matching of OSGi Core Release 7.

  • pid - The PID of the target application.

The pseudo target <<SELF>> indicates that the calling application is allowed to manipulate its own descriptors and handlers.

The following actions can be granted:

  • SCHEDULE_ACTION - The caller is allowed to schedule an application., i.e. call the ApplicationDescriptor schedule method. This action implies LIFECYCLE_ACTION.

  • LIFECYCLE_ACTION - The caller is allowed to manipulate the life cycle state of an application instance: launch and destroy.

  • LOCK_ACTION - The caller is allowed to the lock and unlock methods.

116.6.2 Service and Package Permissions

116.6.2.1 Application Admin Implementation

The Application Admin implementation must have the following permissions:

ServicePermission  ..ScheduledApplication         REGISTER
ServicePermission  ..ApplicationDescriptor        GET
ServicePermission  ..ApplicationHandle            GET
PackagePermission  org.osgi.service.application   EXPORTONLY
ServicePermission  ..ApplicationDescriptor        GET
ServicePermission  ..ApplicationHandle            GET
ApplicationAdminPermission *                      *

116.6.2.2 Application Container

ServicePermission  ..ApplicationDescriptor        REGISTER
ServicePermission  ..ApplicationHandle            REGISTER
PackagePermission  org.osgi.service.application   IMPORT

Additionally, an Application Container requires all the permissions that are needed to run the applications. This is likely to be All Permission.

116.7 org.osgi.service.application

Version 1.1

Application Package Version 1.1.

Bundles wishing to use this package must list the package in the Import-Package header of the bundle's manifest. This package has two types of users: the consumers that use the API in this package and the providers that implement the API in this package.

Example import for consumers using the API in this package:

Import-Package: org.osgi.service.application; version="[1.1,2.0)"

Example import for providers implementing the API in this package:

Import-Package: org.osgi.service.application; version="[1.1,1.2)"

116.7.1 Summary

116.7.2 public class ApplicationAdminPermission
extends Permission

This class implements permissions for manipulating applications and their instances.

ApplicationAdminPermission can be targeted to applications that matches the specified filter.

ApplicationAdminPermission may be granted for different actions: lifecycle, schedule and lock. The permission schedule implies the permission lifecycle.

116.7.2.1 public static final String LIFECYCLE_ACTION = "lifecycle"

Allows the lifecycle management of the target applications.

116.7.2.2 public static final String LOCK_ACTION = "lock"

Allows setting/unsetting the locking state of the target applications.

116.7.2.3 public static final String SCHEDULE_ACTION = "schedule"

Allows scheduling of the target applications. The permission to schedule an application implies that the scheduler can also manage the lifecycle of that application i.e. schedule implies lifecycle

116.7.2.4 public ApplicationAdminPermission(String filter, String actions) throws InvalidSyntaxException

filter to identify application. The value null is equivalent to "*" and it indicates "all application".

comma-separated list of the desired actions granted on the applications or "*" means all the actions. It must not be null. The order of the actions in the list is not significant.

Constructs an ApplicationAdminPermission. The filter specifies the target application. The filter is an LDAP-style filter, the recognized properties are signer and pid. The pattern specified in the signer is matched with the Distinguished Name chain used to sign the application. Wildcards in a DN are not matched according to the filter string rules, but according to the rules defined for a DN chain. The attribute pid is matched with the PID of the application according to the filter string rules.

If the filter is null then it matches "*". If actions is "*" then it identifies all the possible actions.

InvalidSyntaxException– is thrown if the specified filter is not syntactically correct.

NullPointerException– is thrown if the actions parameter is null

ApplicationDescriptor, org.osgi.framework.AdminPermission

116.7.2.5 public ApplicationAdminPermission(ApplicationDescriptor application, String actions)

The target of the operation, it must not be null.

The required operation, it must not be null.

This constructor should be used when creating ApplicationAdminPermission instance for checkPermission call.

NullPointerException– If any of the arguments is null.

116.7.2.6 public boolean equals(Object with)

116.7.2.7 public String getActions()

Returns the actions of this permission.

the actions specified when this permission was created

116.7.2.8 public int hashCode()

116.7.2.9 public boolean implies(Permission otherPermission)

the implied permission

Checks if the specified permission is implied by this permission. The method returns true under the following conditions:

  • This permission was created by specifying a filter (see ApplicationAdminPermission(String, String))

  • The implied otherPermission was created for a particular ApplicationDescriptor (see ApplicationAdminPermission(ApplicationDescriptor, String))

  • The filter of this permission matches the ApplicationDescriptor specified in the otherPermission. If the filter in this permission is the <<SELF>> pseudo target, then the currentApplicationId set in the otherPermission is compared to the application Id of the target ApplicationDescriptor.

  • The list of permitted actions in this permission contains all actions required in the otherPermission

Otherwise the method returns false.

true if this permission implies the otherPermission, false otherwise.

116.7.2.10 public ApplicationAdminPermission setCurrentApplicationId(String applicationId)

the ID of the current application.

This method can be used in the java.security.ProtectionDomain implementation in the implies method to insert the application ID of the current application into the permission being checked. This enables the evaluation of the <<SELF>> pseudo targets.

the permission updated with the ID of the current application

116.7.3 public abstract class ApplicationDescriptor

An OSGi service that represents an installed application and stores information about it. The application descriptor can be used for instance creation.

116.7.3.1 public static final String APPLICATION_CONTAINER = "application.container"

The property key for the application container of the application.

116.7.3.2 public static final String APPLICATION_COPYRIGHT = "application.copyright"

The property key for the localized copyright notice of the application.

116.7.3.3 public static final String APPLICATION_DESCRIPTION = "application.description"

The property key for the localized description of the application.

116.7.3.4 public static final String APPLICATION_DOCUMENTATION = "application.documentation"

The property key for the localized documentation of the application.

116.7.3.5 public static final String APPLICATION_ICON = "application.icon"

The property key for the localized icon of the application.

116.7.3.6 public static final String APPLICATION_LAUNCHABLE = "application.launchable"

The property key for the launchable property of the application.

116.7.3.7 public static final String APPLICATION_LICENSE = "application.license"

The property key for the localized license of the application.

116.7.3.8 public static final String APPLICATION_LOCATION = "application.location"

The property key for the location of the application.

116.7.3.9 public static final String APPLICATION_LOCKED = "application.locked"

The property key for the locked property of the application.

116.7.3.10 public static final String APPLICATION_NAME = "application.name"

The property key for the localized name of the application.

116.7.3.11 public static final String APPLICATION_PID = "service.pid"

The property key for the unique identifier (PID) of the application.

116.7.3.12 public static final String APPLICATION_VENDOR = "service.vendor"

The property key for the name of the application vendor.

116.7.3.13 public static final String APPLICATION_VERSION = "application.version"

The property key for the version of the application.

116.7.3.14 public static final String APPLICATION_VISIBLE = "application.visible"

The property key for the visibility property of the application.

116.7.3.15 protected ApplicationDescriptor(String applicationId)

The identifier of the application. Its value is also available as the service.pid service property of this ApplicationDescriptor service. This parameter must not be null.

Constructs the ApplicationDescriptor.

NullPointerException– if the specified applicationId is null.

116.7.3.16 public final String getApplicationId()

Returns the identifier of the represented application.

the identifier of the represented application

116.7.3.17 public final Map getProperties(String locale)

the locale string, it may be null, the value null means the default locale. If the provided locale is the empty String ( "")then raw (non-localized) values are returned.

Returns the properties of the application descriptor as key-value pairs. The return value contains the locale aware and unaware properties as well. The returned Map will include the service properties of this ApplicationDescriptor as well.

This method will call the getPropertiesSpecific method to enable the container implementation to insert application model and/or container implementation specific properties.

The returned java.util.Map will contain the standard OSGi service properties as well (e.g. service.id, service.vendor etc.) and specialized application descriptors may offer further service properties. The returned Map contains a snapshot of the properties. It will not reflect further changes in the property values nor will the update of the Map change the corresponding service property.

copy of the service properties of this application descriptor service, according to the specified locale. If locale is null then the default locale's properties will be returned. (Since service properties are always exist it cannot return null.)

IllegalStateException– if the application descriptor is unregistered

116.7.3.18 protected abstract Map getPropertiesSpecific(String locale)

the locale to be used for localizing the properties. If null the default locale should be used. If it is the empty String ("") then raw (non-localized) values should be returned.

Container implementations can provide application model specific and/or container implementation specific properties via this method. Localizable properties must be returned localized if the provided locale argument is not the empty String. The value null indicates to use the default locale, for other values the specified locale should be used. The returned java.util.Map must contain the standard OSGi service properties as well (e.g. service.id, service.vendor etc.) and specialized application descriptors may offer further service properties. The returned Map contains a snapshot of the properties. It will not reflect further changes in the property values nor will the update of the Map change the corresponding service property.

the application model specific and/or container implementation specific properties of this application descriptor.

IllegalStateException– if the application descriptor is unregistered

116.7.3.19 protected abstract boolean isLaunchableSpecific()

This method is called by launch() to verify that according to the container, the application is launchable.

true, if the application is launchable according to the container, false otherwise.

IllegalStateException– if the application descriptor is unregistered

116.7.3.20 public final ApplicationHandle launch(Map arguments) throws ApplicationException

Arguments for the newly launched application, may be null

Launches a new instance of an application. The args parameter specifies the startup parameters for the instance to be launched, it may be null.

The following steps are made:

  • Check for the appropriate permission.

  • Check the locking state of the application. If locked then throw an ApplicationException with the reason code ApplicationException.APPLICATION_LOCKED.

  • Calls the launchSpecific() method to create and start an application instance.

  • Returns the ApplicationHandle returned by the launchSpecific()

The caller has to have ApplicationAdminPermission(applicationPID, "launch") in order to be able to perform this operation.

The Map argument of the launch method contains startup arguments for the application. The keys used in the Map must be non-null, non-empty String objects. They can be standard or application specific. OSGi defines the org.osgi.triggeringevent key to be used to pass the triggering event to a scheduled application, however in the future it is possible that other well-known keys will be defined. To avoid unwanted clashes of keys, the following rules should be applied:

  • The keys starting with the dash (-) character are application specific, no well-known meaning should be associated with them.

  • Well-known keys should follow the reverse domain name based naming. In particular, the keys standardized in OSGi should start with org.osgi..

The method is synchronous, it return only when the application instance was successfully started or the attempt to start it failed.

This method never returns null. If launching an application fails, the appropriate exception is thrown.

the registered ApplicationHandle, which represents the newly launched application instance. Never returns null.

SecurityException– if the caller doesn't have "lifecycle" ApplicationAdminPermission for the application.

ApplicationException– if starting the application failed

IllegalStateException– if the application descriptor is unregistered

IllegalArgumentException– if the specified Map contains invalid keys (null objects, empty String or a key that is not String)

116.7.3.21 protected abstract ApplicationHandle launchSpecific(Map arguments) throws Exception

the startup parameters of the new application instance, may be null

Called by launch() to create and start a new instance in an application model specific way. It also creates and registers the application handle to represent the newly created and started instance and registers it. The method is synchronous, it return only when the application instance was successfully started or the attempt to start it failed.

This method must not return null. If launching the application failed, and exception must be thrown.

the registered application model specific application handle for the newly created and started instance.

IllegalStateException– if the application descriptor is unregistered

Exception– if any problem occurs.

116.7.3.22 public final void lock()

Sets the lock state of the application. If an application is locked then launching a new instance is not possible. It does not affect the already launched instances.

SecurityException– if the caller doesn't have "lock" ApplicationAdminPermission for the application.

IllegalStateException– if the application descriptor is unregistered

116.7.3.23 protected abstract void lockSpecific()

This method is used to notify the container implementation that the corresponding application has been locked and it should update the application.locked service property accordingly.

IllegalStateException– if the application descriptor is unregistered

116.7.3.24 public abstract boolean matchDNChain(String pattern)

a pattern for a chain of Distinguished Names. It must not be null.

This method verifies whether the specified pattern matches the Distinguished Names of any of the certificate chains used to authenticate this application.

The pattern must adhere to the syntax defined in org.osgi.service.application.ApplicationAdminPermission for signer attributes.

This method is used by ApplicationAdminPermission.implies(java.security.Permission) method to match target ApplicationDescriptor and filter.

true if the specified pattern matches at least one of the certificate chains used to authenticate this application

NullPointerException– if the specified pattern is null.

IllegalStateException– if the application descriptor was unregistered

116.7.3.25 public final ScheduledApplication schedule(String scheduleId, Map arguments, String topic, String eventFilter, boolean recurring) throws InvalidSyntaxException, ApplicationException

the identifier of the created schedule. It can be null, in this case the identifier is automatically generated.

the startup arguments for the scheduled application, may be null

specifies the topic of the triggering event, it may contain a trailing asterisk as wildcard, the empty string is treated as "*", must not be null

specifies and LDAP filter to filter on the properties of the triggering event, may be null

if the recurring parameter is false then the application will be launched only once, when the event firstly occurs. If the parameter is true then scheduling will take place for every event occurrence; i.e. it is a recurring schedule

Schedules the application at a specified event. Schedule information should not get lost even if the framework or the device restarts so it should be stored in a persistent storage. The method registers a ScheduledApplication service in Service Registry, representing the created schedule.

The Map argument of the method contains startup arguments for the application. The keys used in the Map must be non-null, non-empty String objects. The argument values must be of primitive types, wrapper classes of primitive types, String or arrays or collections of these.

The created schedules have a unique identifier within the scope of this ApplicationDescriptor. This identifier can be specified in the scheduleId argument. If this argument is null, the identifier is automatically generated.

the registered scheduled application service

NullPointerException– if the topic is null

InvalidSyntaxException– if the specified eventFilter is not syntactically correct

ApplicationException– if the schedule couldn't be created. The possible error codes are

SecurityException– if the caller doesn't have "schedule" ApplicationAdminPermission for the application.

IllegalStateException– if the application descriptor is unregistered

IllegalArgumentException– if the specified Map contains invalid keys (null objects, empty String or a key that is not String)

116.7.3.26 public final void unlock()

Unsets the lock state of the application.

SecurityException– if the caller doesn't have "lock" ApplicationAdminPermission for the application.

IllegalStateException– if the application descriptor is unregistered

116.7.3.27 protected abstract void unlockSpecific()

This method is used to notify the container implementation that the corresponding application has been unlocked and it should update the application.locked service property accordingly.

IllegalStateException– if the application descriptor is unregistered

116.7.4 public class ApplicationException
extends Exception

This exception is used to indicate problems related to application lifecycle management. ApplicationException object is created by the Application Admin to denote an exception condition in the lifecycle of an application. ApplicationExceptions should not be created by developers. ApplicationExceptions are associated with an error code. This code describes the type of problem reported in this exception. The possible codes are:

116.7.4.1 public static final int APPLICATION_DUPLICATE_SCHEDULE_ID = 5

The application scheduling failed because the specified identifier is already in use.

116.7.4.2 public static final int APPLICATION_EXITVALUE_NOT_AVAILABLE = 6

The exit value is not available for an application instance because the instance has not terminated.

1.1

116.7.4.3 public static final int APPLICATION_INTERNAL_ERROR = 3

An exception was thrown by the application or the corresponding container during launch. The exception is available from getCause().

116.7.4.4 public static final int APPLICATION_INVALID_STARTUP_ARGUMENT = 7

One of the specified startup arguments is invalid, for example its type is not permitted.

1.1

116.7.4.5 public static final int APPLICATION_LOCKED = 1

The application couldn't be launched because it is locked.

116.7.4.6 public static final int APPLICATION_NOT_LAUNCHABLE = 2

The application is not in launchable state, it's ApplicationDescriptor.APPLICATION_LAUNCHABLE attribute is false.

116.7.4.7 public static final int APPLICATION_SCHEDULING_FAILED = 4

The application schedule could not be created due to some internal error (for example, the schedule information couldn't be saved due to some storage error).

116.7.4.8 public ApplicationException(int errorCode)

The code of the error

Creates an ApplicationException with the specified error code.

116.7.4.9 public ApplicationException(int errorCode, Throwable cause)

The code of the error

The cause of this exception.

Creates a ApplicationException that wraps another exception.

116.7.4.10 public ApplicationException(int errorCode, String message)

The code of the error

The associated message

Creates an ApplicationException with the specified error code.

116.7.4.11 public ApplicationException(int errorCode, String message, Throwable cause)

The code of the error

The associated message.

The cause of this exception.

Creates a ApplicationException that wraps another exception.

116.7.4.12 public Throwable getCause()

Returns the cause of this exception or null if no cause was set.

The cause of this exception or null if no cause was set.

116.7.4.13 public int getErrorCode()

Returns the error code associated with this exception.

The error code of this exception.

116.7.5 public abstract class ApplicationHandle

ApplicationHandle is an OSGi service interface which represents an instance of an application. It provides the functionality to query and manipulate the lifecycle state of the represented application instance. It defines constants for the lifecycle states.

116.7.5.1 public static final String APPLICATION_DESCRIPTOR = "application.descriptor"

The property key for the pid of the corresponding application descriptor.

116.7.5.2 public static final String APPLICATION_PID = "service.pid"

The property key for the unique identifier (PID) of the application instance.

116.7.5.3 public static final String APPLICATION_STATE = "application.state"

The property key for the state of this application instance.

116.7.5.4 public static final String APPLICATION_SUPPORTS_EXITVALUE = "application.supports.exitvalue"

The property key for the supports exit value property of this application instance.

1.1

116.7.5.5 public static final String RUNNING = "RUNNING"

The application instance is running. This is the initial state of a newly created application instance.

116.7.5.6 public static final String STOPPING = "STOPPING"

The application instance is being stopped. This is the state of the application instance during the execution of the destroy() method.

116.7.5.7 protected ApplicationHandle(String instanceId, ApplicationDescriptor descriptor)

the instance identifier of the represented application instance. It must not be null.

the ApplicationDescriptor of the represented application instance. It must not be null.

Application instance identifier is specified by the container when the instance is created. The instance identifier must remain static for the lifetime of the instance, it must remain the same even across framework restarts for the same application instance. This value must be the same as the service.pid service property of this application handle.

The instance identifier should follow the following scheme: <application descriptor PID>.<index> where <application descriptor PID> is the PID of the corresponding ApplicationDescriptor and <index> is a unique integer index assigned by the application container. Even after destroying the application index the same index value should not be reused in a reasonably long timeframe.

NullPointerException– if any of the arguments is null.

116.7.5.8 public final void destroy()

The application instance's lifecycle state can be influenced by this method. It lets the application instance perform operations to stop the application safely, e.g. saving its state to a permanent storage.

The method must check if the lifecycle transition is valid; a STOPPING application cannot be stopped. If it is invalid then the method must exit. Otherwise the lifecycle state of the application instance must be set to STOPPING. Then the destroySpecific() method must be called to perform any application model specific steps for safe stopping of the represented application instance.

At the end the ApplicationHandle must be unregistered. This method should free all the resources related to this ApplicationHandle.

When this method is completed the application instance has already made its operations for safe stopping, the ApplicationHandle has been unregistered and its related resources has been freed. Further calls on this application should not be made because they may have unexpected results.

SecurityException– if the caller doesn't have "lifecycle" ApplicationAdminPermission for the corresponding application.

IllegalStateException– if the application handle is unregistered

116.7.5.9 protected abstract void destroySpecific()

Called by the destroy() method to perform application model specific steps to stop and destroy an application instance safely.

IllegalStateException– if the application handle is unregistered

116.7.5.10 public final ApplicationDescriptor getApplicationDescriptor()

Retrieves the ApplicationDescriptor to which this ApplicationHandle belongs.

The corresponding ApplicationDescriptor

116.7.5.11 public Object getExitValue(long timeout) throws ApplicationException, InterruptedException

The maximum time in milliseconds to wait for the application to timeout.

Returns the exit value for the application instance. The timeout specifies how the method behaves when the application has not yet terminated. A negative, zero or positive value may be used.

  • negative - The method does not wait for termination. If the application has not terminated then an ApplicationException is thrown.

  • zero - The method waits until the application terminates.

  • positive - The method waits until the application terminates or the timeout expires. If the timeout expires and the application has not terminated then an ApplicationException is thrown.

The default implementation throws an UnsupportedOperationException. The application model should override this method if exit values are supported.

The exit value for the application instance. The value is application specific.

UnsupportedOperationException– If the application model does not support exit values.

InterruptedException– If the thread is interrupted while waiting for the timeout.

ApplicationException– If the application has not terminated. The error code will be ApplicationException.APPLICATION_EXITVALUE_NOT_AVAILABLE.

1.1

116.7.5.12 public final String getInstanceId()

Returns the unique identifier of this instance. This value is also available as a service property of this application handle's service.pid.

the unique identifier of the instance

116.7.5.13 public abstract String getState()

Get the state of the application instance.

the state of the application.

IllegalStateException– if the application handle is unregistered

116.7.6 public interface ScheduledApplication

It is allowed to schedule an application based on a specific event. ScheduledApplication service keeps the schedule information. When the specified event is fired a new instance must be launched. Note that launching operation may fail because e.g. the application is locked.

Each ScheduledApplication instance has an identifier which is unique within the scope of the application being scheduled.

ScheduledApplication instances are registered as services. The APPLICATION_PID service property contains the PID of the application being scheduled, the SCHEDULE_ID service property contains the schedule identifier.

116.7.6.1 public static final String APPLICATION_PID = "service.pid"

The property key for the identifier of the application being scheduled.

116.7.6.2 public static final String DAY_OF_MONTH = "day_of_month"

The name of the day of month attribute of a virtual timer event. The value is defined by java.util.Calendar.DAY_OF_MONTH.

116.7.6.3 public static final String DAY_OF_WEEK = "day_of_week"

The name of the day of week attribute of a virtual timer event. The value is defined by java.util.Calendar.DAY_OF_WEEK.

116.7.6.4 public static final String HOUR_OF_DAY = "hour_of_day"

The name of the hour of day attribute of a virtual timer event. The value is defined by java.util.Calendar.HOUR_OF_DAY.

116.7.6.5 public static final String MINUTE = "minute"

The name of the minute attribute of a virtual timer event. The value is defined by java.util.Calendar.MINUTE.

116.7.6.6 public static final String MONTH = "month"

The name of the month attribute of a virtual timer event. The value is defined by java.util.Calendar.MONTH.

116.7.6.7 public static final String SCHEDULE_ID = "schedule.id"

The property key for the schedule identifier. The identifier is unique within the scope of the application being scheduled.

116.7.6.8 public static final String TIMER_TOPIC = "org/osgi/application/timer"

The topic name for the virtual timer topic. Time based schedules should be created using this topic.

116.7.6.9 public static final String TRIGGERING_EVENT = "org.osgi.triggeringevent"

The key for the startup argument used to pass the event object that triggered the schedule to launch the application instance. The event is passed in a java.security.GuardedObject protected by the corresponding org.osgi.service.event.TopicPermission.

116.7.6.10 public static final String YEAR = "year"

The name of the year attribute of a virtual timer event. The value is defined by java.util.Calendar.YEAR.

116.7.6.11 public ApplicationDescriptor getApplicationDescriptor()

Retrieves the ApplicationDescriptor which represents the application and necessary for launching.

the application descriptor that represents the scheduled application

IllegalStateException– if the scheduled application service is unregistered

116.7.6.12 public Map getArguments()

Queries the startup arguments specified when the application was scheduled. The method returns a copy of the arguments, it is not possible to modify the arguments after scheduling.

the startup arguments of the scheduled application. It may be null if null argument was specified.

IllegalStateException– if the scheduled application service is unregistered

116.7.6.13 public String getEventFilter()

Queries the event filter for the triggering event.

the event filter for triggering event

IllegalStateException– if the scheduled application service is unregistered

116.7.6.14 public String getScheduleId()

Returns the identifier of this schedule. The identifier is unique within the scope of the application that the schedule is related to.

the identifier of this schedule

116.7.6.15 public String getTopic()

Queries the topic of the triggering event. The topic may contain a trailing asterisk as wildcard.

the topic of the triggering event

IllegalStateException– if the scheduled application service is unregistered

116.7.6.16 public boolean isRecurring()

Queries if the schedule is recurring.

true if the schedule is recurring, otherwise returns false

IllegalStateException– if the scheduled application service is unregistered

116.7.6.17 public void remove()

Cancels this schedule of the application.

SecurityException– if the caller doesn't have "schedule" ApplicationAdminPermission for the scheduled application.

IllegalStateException– if the scheduled application service is unregistered

116.8 References

[1]PNG Image Formathttp://www.libpng.org/pub/png/