Sun Java Solaris Communities My SDN Account
 
Article

An Overview of JSR 124: J2EE Client Provisioning

 

What is Provisioning?

JSR 124, the J2EE Client Provisioning Specification, provides a framework and APIs for making applications available on a J2EE server. Provisioning servers are often compared to vending machines. Like their snack- and drink-dispensing counterparts, provisioning servers allow clients to pick and choose from an array of tempting software treats. Like cans of soda in a vending machine, client application bundles are packaged for immediate delivery and consumption. Provisioning servers have some features, though, that today's soda machines can only dream about. The provisioning specification allows the server to offer software based on what the client can support. The server keeps a list of supported platforms and their capabilities. These capabilities can be anything from screen size and bit depth to supported network protocols and APIs. Rather than just offering all software to every client and letting the poor user figure out what's actually going to work, the server filters the list of available choices on a per-client basis. It's like a snack machine that knows you're allergic to nuts and simply doesn't offer you any snacks containing them.

If users will simply download JAR files, a web server alone will probably suffice, but if your need is to offer applications to large numbers of users on many different devices, J2EE with client-provisioning support is a better alternative. Many mobile devices can use browser-based applications, and these can be updated without touching the client because the browser doesn't store the application locally. Applications deployed on the client can offer a richer set of features to both developer and end user, and have the added benefit of being useful even when not connected to the network, but updates are more difficult because there are so many different client platforms. A centrally managed repository of content and applications solves the problem of deploying to a wide variety of platforms. JSR 124 is the architecture for such a repository.

While this JSR is not specific to any single client technology, it is particularly useful to J2ME developers deploying Mobile Device Information Profile (MIDP) applications. The specification doesn't limit or specify the client platform, but for the first release the focus has been on client devices supporting MIDP, and on desktop clients deployed using the Java Network Launching Protocol (JNLP), which is used primarily by Java Web Start.

Figure 1: Client Provisioning Architecture
Figure 1: Client Provisioning Architecture
(Click image to enlarge.)

Figure 1 illustrates the main concepts of the Client Provisioning Specification and the API it defines. This API also includes several XML schemas for key XML files you'll need when configuring the provisioning framework. The specification also defines a special file format called a Provisioning Archive (PAR) to use for deploying provisioning applications. The developers who will use the specification are the ones who must create a provisioning application on the server. This application is the actual vending machine. The provisioning application provides the user interface and talks directly to the clients. The user interface for the server allows clients to browse and search for available applications. It also manages the repository, making bundles available from PAR files and removing bundles from the repository.

The Provisioning APIs

The three packages proposed for the final release of the JSR are listed in Table 1. These APIs are used by the developer of the provisioning application, not by the developers of the client applications that will be provisioned, and not by the clients that will come to the server looking for new applications. One of the goals of the JSR is to separate the tasks of those developing the content, the client application bundles, from the tasks of those developing the provisioning server. The aim is to leave the application developer free to concentrate on client issues while the provisioning server developer focuses on delivery.

In general, a provisioning application will contain one or more custom servlets that enable users to discover bundles that are available for download. The servlets will then use the provisioning framework to deliver the bundles to the users' devices.

Table 1: J2EE Client Provisioning Packages

Package Name Description
javax.provisioning Base set of interfaces and classes representing devices, bundles, and other deliverables.
All the APIs needed to write a provisioning application.
javax.provisioning.adapter Interfaces for defining provisioning adapters.
All the APIs needed to extend the provisioning server to provision a new device.
javax.provisioning.matcher Interfaces and classes for customizing and extending the capability-matching engine.
All the APIs needed to alter the basic matching policies in the repository (for advanced developers)

The provisioning application relies on three configuration files: devices.xml and adapters.xml provide information about supported devices and adapters, and matchers.xml configures customized provisioning matchers, components the provisioning server uses to match bundle requirements against device capabilities.

The provisioning process can be broken down into three tasks:

  • Stocking: managing the repository; adding and removing client application bundles
  • Discovery: finding out what bundles are available for delivery from the provisioning server
  • Delivery: delivering the application bundle to the client

The remainder of this article discusses how the Client Provisioning Specification manages each of these tasks.

Stocking

Stocking involves managing the bundles within a repository. The repository is a directory that contains all of the client bundles for a particular provisioning server. In most cases these are in the form of PAR files. The provisioning application implements interfaces from the javax.provisioning package to interact with the repository. This interaction includes adding and deleting client application bundles, querying device capabilities, and delivering bundles to the client (I'll talk about delivery later).

Depending on how the provisioning application is written, the stocking procedure may perform pre-verification on the client bundles (calling preverify() on a MIDlet JAR for example). This step might also include checking signatures, or checking for viruses, to ensure the integrity of every bundle.

PAR Files and the Provisioning Descriptor

A PAR allows an application developer to "package once, stock anywhere." Client applications are packaged into a PAR file for deployment to the provisioning server. Like a JAR, a PAR is just a zip file, but containing one or more client bundles. Besides the bundles, you must include a provisioning descriptor file named /META-INF/provisioning.xml. A simple PAR file containing the game Hearts in the form of a MIDlet might have a directory structure like this:

META-INF/provisioning.xml
/Hearts.jar
/hearts.jad
/hearts.gif
/hearts.wbmp
/hearts.wbmp
/hearts.agree.txt

The provisioning.xml file might look something like this:

<provisioning-archive> 
   <client-bundle>
   <bundle-name>CardsGame</bundle-name>

   <tool-descriptions>
         <description>A fun card game</description>
      <display-name>Cards for Java (Hearts)</display-name>
      <user-descriptions>
         <display-name>ACME Hearts</display-name>

         <description>Watch out for the Queen of Spades! </description>
         <icon mime-type="image/gif">/hearts.gif</icon>
      </user-descriptions>
      <descriptor-file mime-type="text/vnd.sun.j2me.app-descriptor">
         /games/hearts.jad
      </descriptor-file>

      <bundle-type>APPLICATION</bundle-type>
      <version>12.7</version>
      <device-requirement>
         <requirement-name>
            SoftwarePlatform.JavaPlatform
         </requirement-name>

         <requirement-value>MIDP/1.0</requirement-value>
      </device-requirement>
      <vendor-info>
         <vendor-name>ACME Games Inc</vendor-name>
      </vendor-info>

      <catalog-property>
         <property-name>Portal_U-Go:User-Categories</property-name>
         <property-value>
            Entertainment.Games, Entertainment.Fun, Entertainment.Family
         </property-value>
         <property-name>Portal_U-Go:Age-Limits</property-name>

         <property-value>All Ages</property-value>
         <property-name>Portal_U-Go:BillingScheme</property-name>
         <property-value>Monthly Gold Plan</property-value>
      </catalog-property>

      <copyright>/hearts.agree.txt<copyright>
   </client-bundle>
</provisioning-archive>

The specification defines the format of the provisioning descriptor file. Notice the MIME type and location of the JAD file, the device requirements (MIDP 1.0), and the miscellaneous catalog properties. The spec doesn't define the descriptor files for the client bundles, however. Anything specific to MIDlet JAD and JAR files is defined in the MIDP specification, and is encapsulated within the MIDP adapter.

Note well that the client applications needn't reside on the provisioning server - they can be downloaded from other servers. The resources of a bundle can reside on other servers, with the provisioning server simply providing the discovery mechanism. The provisioning descriptor file defines external resources just like other bundles, except that it specifies the resources with Uniform Resource Identifiers (URIs) rather than relative pathnames. This example shows how you can provision a third-party application, in this case the Road Pizza game, on your server:

...
<client-bundle>
   <application-id>
      http://www.zeroindex.co.uk/files/RoadPizza
   </application-id>
   ...
   <descriptor-file>

      http://www.zeroindex.co.uk/files/RoadPizza.jad
   </descriptor-file>             
   <icon>
      http://www.zeroindex.co.uk/images/RoadPizza1.png
   </icon>   
   <device-requirement>
      <requirement-name>HardwarePlatform.ScreenSize</requirement-name>

      <requirement-value>96x100+</requirement-value>
   </device-requirement>
      ...
</client-bundle>
...

Notice that device requirements, icons, descriptions, and anything else pertaining to a bundle can reside on other servers as well.

Now that you have stocked the provisioning server with content, you probably want clients to begin finding out what's available on your server. That process is called discovery.

Discovery

The discovery process simply presents a list of available applications based on a query from a client. Often a client will simply request a list of all applications that will run on the device it calls home. If the provisioning application supports parameters for discovery, the client's query can narrow the search. These parameters might specify the type of program (game, financial application, etc.), or a price range. Discovery is a key part of provisioning: giving clients access to exactly what they want, and filtering out what they can't use. Discovery may include giving access to content the user has paid for, content based on user preferences (types of applications he or she likes), or perhaps applications specialized to the geographical location of the client.

The discovery process results in the production of a URI the client device may request to initiate delivery of a particular bundle. As I noted above, this URI could be on a different server. So how does the provisioning server know the capabilities of all the devices that ask for bundles?

Device capabilities are specified in the devices configuration file, devices.xml, which is deployed with the provisioning application. The following excerpt from a devices.xml file shows how to define the capabilities of the Motorola i95cl phone:

...

<device>
   <!-- Motorola i95cl -->
   <identifier>Motorola/i95cl</identifier>
   <adapter-name>midp</adapter-name>
   <capability>

      <capability-name>HardwarePlatform.ScreenSize</capability-name>
      <capability-value>120x160</capability-value>
   </capability>
   <capability>
      <capability-name>HardwarePlatform.BitsPerPixel</capability-name>

      <capability-value>8</capability-value>
   </capability>
   <capability>
      <capability-name>SoftwarePlatform.JavaPlatform</capability-name>
      <capability-value>MIDP/1.0</capability-value>

   </capability>        
   <capability>
      <capability-name>SoftwarePlatform.JavaProtocol</capability-name>
      <capability-value>
         comm, socket, https, ssl, datagram, file
      </capability-value>

   </capability>
</device> 
...      

The <identifier> tag denotes an individual device - but multiple <identifier> tags can appear in a single tag, so a single description can specify the capabilities of a whole series of devices. Notice the various device capabilities that the file defines. The definition is also very important, as it determines which adapter can be used to provision the device. A provisioning adapter is a software component that implements a particular provisioning model, MIDP or JNLP for example.

The matching configuration file, matchers.xml, also plays a key role in determining which bundles are available to a client. This file defines the algorithms that the provisioning server uses to compare bundle requirements against device capabilities. It can easily be extended to support new requirement or capability attributes. For example, this block of XML from a matchers.xml file defines a matcher for checking screen size:

...
<matcher>

   <attribute-name>HardwarePlatform.ScreenSize</attribute-name>
   <matcher-class>
      javax.provisioning.matcher.DimensionMatcher
   </matcher-class>
   <init-param>
      <param-name>allMustMatch</param-name>

      <param-value>false</param-value>
   </init-param>
</matcher>
...

The specification defines a default algorithm for matching that should work in most situations. In most cases, the provisioning application developer won't need to touch this file.

Delivery

You might be wondering: How can the provisioning server provision any kind of device, using any network protocol or standard, such as MIDP OTA, OMA OTA, or JNLP? The spec defines a way of defining delivery methods called the provisioning adapter component model. Adapters are software components in the provisioning server that tailor the delivery of content to a particular provisioning model supported by the device. If you have a foo adapter for foo devices, and you discover a type of device that supports a different network protocol, all you need to do to start provisioning devices of the new type is to add an adapter for it.

The delivery stage involves delivering a client bundle to a particular user using a particular device using a particular provisioning model. This simply means giving users exactly what they want. A provisioning adapter, defined in adapters.xml, handles the actual delivery of a client bundle. Here's a sample definition of a MIDP adapter:

...
<adapter>
   <adapter-name>midp</adapter-name>
   <adapter-class> 
      com.sun.provisioning.adapters.midp.AdapterMIDP
   </adapter-class>

   <base-uri>/delivery/midp</base-uri>
   <descriptor-file>
      <extension>jad</extension>
      <mime-type>text/vnd.sun.j2me.app-descriptor</mime-type>

   </descriptor-file>

   <init-param>       
      <param-name>directory-path</param-name>
      <param-value>MyRepository/midp</param-value>
   </init-param>

</adapter>  
...

Notice that the adapter configuration usually includes a MIME type and filename extension that the web server uses in the response. This specification also helps the provisioning server decide which adapter to use for the bundle it has been asked to deliver.

In this example the adapter is implemented using the AdapterMIDP class that's included in the reference implementation. The RI also includes classes that implement generic and JNLP adapters. To add a new adapter, the provisioning developer simply writes a class that extends javax.provisioning.adapter.Adapter, then registers it with the provisioning server in the adapters.xml configuration file as shown above.

When an adapter class extends javax.provisioning.adapter.Adapter it must implement two methods:

  • createDescriptorFile(java.net.URL descriptorFile)
    This method returns a DescriptorFile instance corresponding to the specified descriptorFile URL.
  • java.lang.String createFulfillmentURI(FulfillmentTask fulfillmentTask)
    This method returns a "fulfillment URI" that a client device can use to initiate the download of a bundle (which may involve downloading multiple files). In the case of a MIDlet, the URI returned is for a JAR file.

Once configured in adapters.xml, the adapter can be used to provision different types of client bundles for various devices, as specified in devices.xml.

Summary

If you're simply making a few MIDlets available for download on your web site, you can probably get away with just making the JAD and JAR files available for download. This approach works for developers deploying their applications on their own web servers, but many MIDP developers submit content to several carriers, each running its own vending machine. PARs make this task much easier by providing a standard format that all vending machines will use: "Package once, stock anywhere".

If you're serious about deploying your applications to various devices, and have tailored versions of each application to the properties of specific devices, then the J2EE Client Provisioning Specification demands some investigation. Further, if you need to worry about the problems of distribution, installation, billing, tracking, and personalizing smart clients, you should be willing to develop a provisioning server.

As the diversity of clients and the need to manage all aspects of deployment and installation continue to grow, so will the need for a provisioning server that can support those requirements.

Resources

Acknowledgments

Special thanks to Danny Coward for his help reviewing this article.




Reader Feedback
Excellent   Good   Fair   Poor  

If you have other comments or ideas for future technical tips, please type them here:

Comments:
If you would like a reply to your comment, please submit your email address:
Note: We may not respond to all submitted comments.

Have a question about Java programming? Use Java Online Support.



Back To Top

Oracle is reviewing the Sun product roadmap and will provide guidance to customers in accordance with Oracle's standard product communication policies. Any resulting features and timing of release of such features as determined by Oracle's review of roadmaps, are at the sole discretion of Oracle. All product roadmap information, whether communicated by Sun Microsystems or by Oracle, does not represent a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. It is intended for information purposes only, and may not be incorporated into any contract.