Oracle Application Server Wireless Developer's Guide 10g (9.0.4) Part Number B10948-01 |
|
Each section of this document presents a different topic. These sections include:
J2ME (Java 2, Micro Edition) is a technology for Java applications on small devices. As a mobile application development platform, J2ME is standard-based and offers a rich UI, one that is comparable to browser-based solutions. In addition, J2ME-based applications are more resilient to network disruption because they do not depend on a wireless network to perform many sophisticated operations.
With the increasing market penetration of J2ME-capable handsets, enterprises are eager to develop J2ME applications to access their back-end applications for their mobile employees. Operators are also seeking to expand their revenue source by deploying new customer applications on these handsets.
OracleAS Wireless provides a complete J2ME offering, which includes a J2ME Developer Kit as a component of OracleAS Wireless Developer Kit for developing Web service-enabled J2ME applications, J2ME application management, and J2ME application provisioning which enables the flexible and reliable provisioning of J2ME applications to handsets.
The key features provided by the OracleAS Wireless J2ME solution include:
OracleAS Wireless J2ME solution not only enables Service Developers to quickly develop J2ME application that integrate with enterprise back-end systems through Web service technology, but also enables Content Managers to easily manage these applications. The provisioning and Digital Rights Management support offers a new means of creating revenue for the operators and service providers marketing J2ME applications to their consumers.
The following sections provide an overview of the following features of the J2ME Client Library and J2ME Proxy Server:
MIDlets are packaged and deployed as MIDlet Suite. Each MIDlet suite contains the MIDlet's JAR file and its descriptor (JAD) file. The J2ME Client Library client JAR file requires only 26 KB of memory in a MIDlet suite. A currently available alternative is kSOAP 1.2, which is 41 KB and requires kXML, which adds another 21 KB for a total size of 62 KB.
The proxy server enables the 36 KB memory requirement because the server performs the operations on the Web services, thereby reducing the amount of work performed by MIDP device.
The entire process of a J2ME MIDlet calling a Web service consists of:
To register SOAP Web services with the J2ME Proxy Server, you provide the file location of the Web service's WSDL document. During WSDL Registration, the J2ME Proxy Server generates a SOAP client Java class. During execution, the J2ME Proxy Server calls this client class to invoke operations on the Web service.
The J2ME Proxy Server also supports a second type of registration called Class Registration, which enables you to register any Java class with the J2ME Proxy Server. This enables you to access enterprise applications from J2ME MIDlets by creating a Java client to these applications. Once you register this Java client with the J2ME Proxy Server, all of the public methods of the Java class become available for invocation from the J2ME MIDlet.
The methods in the generated J2ME client stub classes contain additional parameters that allow you to cache the result from a Web service call in local persistent storage on the MIDP device. This enables the MIDlet to access the results returned from the Web service repeatedly without requiring additional network round-trips, even after the device has been turned off or has been moved to an area without network access.
Call queuing enables you to queue Web service operation invocations if a network error prevents calling a Web service normally. The J2ME Client Library runtime automatically retries the queued calls until they succeed, and then caches the responses in persistent storage until MIDlet retrieves them.
Request packetization enables you to specify a maximum request size for cases in which a wireless network cannot handle HTTP requests that exceed a certain size. The J2ME Client Library and J2ME Proxy Server automatically break up call requests and responses into pieces no larger than the maximum specified size.
The J2ME Client Library and J2ME Proxy Server compress requests and responses for improved bandwidth and memory usage. Requests and responses are encoded to reduce their size during network transmission and when cached in the MIDlet. This is done automatically.
Session support is activated by default, meaning that an instance of the Java class registered with the J2ME Proxy Server (a class that was either generated during WSDL Registration or provided during Class Registration) is stored in an HttpSession object and then reused when the J2ME Proxy Server receives multiple requests from the same MIDlet. Session support can be turned off by setting a property in the J2ME Client Library.
Once you complete the development of a MIDlet, the J2ME MIDlets and the Web services registered with the J2ME Proxy Server can be easily deployed to a complete OracleAS Wireless installation. The WDK and OracleAS Wireless contain migration scripts to facilitate this deployment.
This section describes how to develop Web service-enabled J2ME MIDlets using the J2ME Web Services Client Library (J2ME Client Library) and the J2ME Web Services Proxy Server (J2ME Proxy Server) in the Wireless Development Kit (WDK).
The OracleAS Wireless Proxy Server consists of two sets of components: the actual server and the scripts to manage the server.
Windows: <ORALCE_HOME>\opmn\bin\opmnctl start wdk
UNIX: <ORACLE_HOME>/opmn/bin/opmnctl.sh start wdk
Dhttp.useProxy=true -Dhttp.proxyHost=<http proxy server> Dhttp.proxyPort=<port number> -Dhttp.nonProxyHosts=<hosts inside firewall>
The following are the WDK directories relevant to the J2ME Client Library and J2ME Proxy Server.
This section walks you through the following step for creating a J2ME MIDlet that calls a Web service:
The Wireless Tools provide you with a graphical interface to the J2ME Proxy Server. In the Wireless Development Kit, however, the interface to the J2ME Proxy Server is through command-line scripts. The J2ME Proxy Server registration and management scripts are:
For Windows: <ORACLE_HOME>\wireless\bin\j2mesdkmgr.bat
For UNIX: <ORACLE_HOME>/wireless/bin/ j2mesdkmgr.sh
You can register a Web service either through Web Service Registration or through Class Registration.
For Web Service Registration, you registering Web services with the J2ME Proxy Server to make those Web services accessible to J2ME MIDlets. You register a SOAP Web service with the J2ME Proxy Server by providing the WSDL document describing the Web service. Once registered, the Web service is available to J2ME MIDlets by calling methods of a J2ME stub class generated from the registered service.
In addition to registering SOAP Web services, you can also register any Java class with the J2ME Proxy Server using Class Registration. All of the public methods of the Java class become available for remote invocation from your MIDlet. This enables you to give your MIDlets access to any enterprise application simply by building a Java client to the enterprise application. This Java class must have either a public constructor with no arguments or a public static method called getInstance()
with no arguments that returns an instance of the class.
When registering Web services, you can group them into namespaces. Associating services with a namespace enables you to group related Web services and to avoid naming conflicts. If you do not specify a namespace, then the Web service is registered under the default namespace.
j2mesdkmgr -registerwsdl registers a Web service using the Web service's WSDL document.
Usage:
j2mesdkmgr -registerwsdl <URL of the WSDL> [<namespace>]
For example, to register the Hello World service (hello.wsdl) available from the Oracle Technology Network (OTN), execute:
For Windows:
For UNIX:
To register the service inside a namespace, use the namespace as the third parameter to the script. For example, to register the Hello World application in a namespace called samples, execute:
For Windows:
For UNIX:
j2mesdkmgr -registerclass registers a Web service using a Java class.
Usage:
j2mesdkmgr -registerclass <URL of the Class Library> <Name of the class> [<namespace>]
The first parameter must be a URL. It may point to either a directory containing the class or to a JAR file.
The second parameter must be a fully qualified class name. For example, to register a service called TestWebService (which is included in the WDK), execute:
For Windows:
For UNIX:
Note: For this example, the WDK home directory is /iaswv904/wireless (UNIX) and C:\iaswv904\wireless (Windows). |
To register the service inside a namespace, use the namespace as the fourth parameter to the script. For example, to register the TestWebService class in the samples namespace, execute:
For Windows:
j2mesdkmgr.bat -registerclass file:C:\ora9ias\j2ee\OC4J_Wireless\applications\wdk\wdk-Web\Webservice\lib\testservices.jar oracle.wireless.me.server.TestWebService samples
For UNIX:
j2mesdkmgr.sh -registerclass file:/ias/j2ee/OC4J_Wilreless/applications/wdk/wdk-Web/Webservice/lib/testservices.jar oracle.wireless.me.server.TestWebService samples
The simplest way to call a Web service that you have registered with the J2ME Proxy Server from your MIDlet is to generate a J2ME stub for the service and to call the methods of the generated stub from your MIDlet.
j2mesdkmgr -generatestub generates a J2ME client stub class for a registered Web service.
Usage:
j2mesdkmgr -generatestub [<namespace>.]<service name> [<Output directory> [<stub name>]]
For example, to generate a J2ME stub class for the Hello World service available from the Oracle Technology Network (IOTNHelloWorld):
j2mesdkmgr -generatestub IOTNHelloWorld
If the service is inside a namespace, you must prefix the service name with the namespace and a period (.). For example, if the Hello World service (IOTNHelloWorld) is registered inside the samples namespace, generate the stub with:
j2mesdkmgr -generatestub samples.IOTNHelloWorld
You can specify a directory in which to place the generated stub as a third parameter to the script.
If you do not specify a stub name, then the generated J2ME client stub class will be called:
IOTNHelloWorldJ2MEStub.Java
To specify a different name for the generated stub, specify an output directory as the third parameter (tmp
in the following examples) and the desired stub class name (HelloWord
in the following examples) as the fourth parameter. For example:
For Windows:
For UNIX:
The generated J2ME client stub class contains one method for each operation of the Web service.
Each of the public methods in the generated J2ME stub class represents an operation of a registered service. The first two parameters of each method have special meaning to J2ME Client Library: the first parameter is the number of minutes to cache the response; the second parameter is a boolean, which should be set to true to bypass any cached responses (that is, force the J2ME Client Library to make a network call to the Web service), and set to false to use a cached response if available and valid. For more information about these parameters, see Section 12.1.4.1, "Response Caching".
All of the other parameters of the methods in the generated stub correspond to the parameters of the service operation that the method represents. Calling these methods from your MIDlet invokes these operations on the Web service.
To test your MIDlet with Sun's J2ME Wireless Toolkit (http://Java.sun.com/products/j2mewtoolkit/download.html):
import
statement for the generated J2ME stub class, create an instance of the stub class, and make calls to the methods in the stub class. The first parameter of each stub method is the number of minutes to cache the result. Set 0 for no caching, or -1 to cache forever. The second parameter of each stub method is true to ignore cached results (that is, always make a network call), or false to use valid cached results if available. The remaining parameters of the stub methods correspond to the parameters of the Web service operations represented by the methods.
The J2ME Client Library contains several sample MIDlets. One of these calls the IOTNHelloWorld service using a generated stub. The sample MIDlet is:
<ORACLE_HOME>\wireless\j2me\j2mesdk\sample\HelloWorld.Java
Note: The directory also contains other MIDlets that have examples of calling Web services through the J2ME Proxy Server using either generated stubs or the J2ME Client Library API. |
The listservices option lists all of the registered services. The removeservice option removes registered services.
The option j2mesdkmgr -listservices lists all the registered services. This script takes no parameters.
This script lists all registered services, but does not list the methods available in the services or the parameters that the methods take. You can view this information with a Web browser, using the URL to the J2ME Proxy Server in the WDK:
http://<host name>:9010/wdk/proxy
For example:
http://www.example.com:9010/wdk/proxy
The option j2mesdkmgr -removeservice removes registered services.
Usage:
j2mesdkmgr -removeservice [<namespace>.]<service name>
For example, to remove the registered service Hello World (IOTNHelloWord):
j2mesdkmgr -removeservice IOTNHelloWorld.
If the service is inside a namespace, you must prefix the service name with the namespace and a period (.). For example, to remove the Hello World service (IOTNHelloWorld), which is registered inside the samples namespace:
j2mesdkmgr -removeservice samples.IOTNHelloWorld
The J2ME Client Library provides a sample J2ME MIDlet, called TestStubMidlet, which enables you to quickly test the generated stub files for the Web services that you register with the J2ME Proxy Server.
To use the sample TestStubMidlet:
http://Java.sun.com/products/j2mewtoolkit/download.html
)
<ORACLE_HOME>/wireless/j2me/j2mesdk/sample/
Place this library inside the lib directory of the project. Place the stub class in the src directory of the project, and place the modified TestStubMidlet
class in an oracle/wireless/me/sample1/ subdirectory inside the src directory of the project (TestStubMidlet
is in the package oracle.wireless.me.sample1
)
Example:
This example uses TestStubMidlet
to call the XMethods Delayed Stock Quote Web service to display a stock quote for Oracle Corporation:
j2mesdkmgr -registerwsdl http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl
j2mesdkmgr -generatestub NetXmethodsServicesStockquoteStockQuoteService
... import NetXmethodsServicesStockquoteStockQuoteServiceJ2MEStub; ... /** * Call Stub. Edit this method to test the stub. * Remember to import the stub class */ private void callStub() { try { // Add your code to test the stub. // For example: // Use the stub to call the XMethods delayed stock quote service to get // Oracle's stock price and cache the result for 1 minute. // Instantiate the Stub class: NetXmethodsServicesStockquoteStockQuoteServiceJ2MEStub stub = new NetXmethodsServicesStockquoteStockQuoteServiceJ2MEStub(); // Call GetQuote Operation to get Oracle's stock price and // cache the result for 1 minute sCallResultString = new String("Stock price for ORCL :" + stub.getQuote(1, false, "ORCL")); } ...
You can register and test the following Web services with TestStubMidlet:
Hello World:
http://otn.oracle.com/tech/Webservices/htdocs/live/hello.wsdl
Delayed Stock Quotes:
http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl
Weather Temperature:
http://www.xmethods.net/sd/2001/TemperatureService.wsdl
FedEx Tracker:
The J2ME Proxy Server in OracleAS Wireless includes a JAR file with two simple sample Web services in the Java classes. Some of the sample MIDlets distributed with the J2ME Client Library use these sample services. To register them, execute the scripts:
For Windows:
For UNIX:
The script registers two Java classes as Web services - TestWebService and TestWebService2.
The TestWebService
class contains several simple methods for testing different parameter types. It has a public constructor with no arguments.
The TestWebService2
class contains one simple test method and a getInstance()
method with no arguments that returns an instance of TestWebService2. Its constructor is private.
The source code for these test services can be found at:
<ORACLE_HOME>/j2ee/OC4J_Wireless/applications/wdk/wdk-Web/Webservice/src
The JAR file that contains the compiled services is:
<ORACLE_HOME>/j2ee/OC4J_Wireless/applications/wdk/wdk-Web/Webservice/lib/testservices.jar
This section describes the usage instructions for the key features provided by the J2ME Client Library and J2ME Proxy Server.
The first two parameters of every public method in a generated stub are int timetokeep
and boolean refresh
. These parameters are used to control response caching. The J2ME Client Library is able to cache the response of a Web service operation in persistent memory on the wireless device. For future invocations of the same operation, the response is retrieved from the local cache instead of from the Web service.
int timetokeep
This is the time in minutes to keep the response in the cache. Further invocations of the same operation within the specified number of minutes will retrieve the response from the local cache instead of making a network round-trip to the Web service. After the specified number of minutes has elapsed, the response in the cache becomes invalid, and the next invocation of this operation will again make a network round-trip to the Web service. Set this parameter to 0 to disable caching, or to -1 to cache forever (the response never becomes invalid).
boolean refresh
This parameter indicates whether to bypass the cache when invoking this operation. Setting this parameter to true forces a network round-trip, even if a valid response is available in the local cache. If this parameter is false, the response if retrieved from the local cache if an available cached response is valid.
The J2ME Proxy Server and Client Library support accessing Web services that use the HTTP basic authentication scheme. To set the username and password for authentication, update the Web services' generated stub, setting the instance variables userName
and password
to the appropriate values. This username and password will be passed to the Web service's HTTP server by the proxy server for authentication.
Session support is activated by default. To disable session support, update the Web services' generated stub, setting the enableSession instance variable to false. The J2ME Proxy Server uses a Java class to invoke operations on the Web service whether you use WSDL Registration or Class Registration to register a Web service with the J2ME Proxy Server, Session support means that successive invocations of operations of a Web service coming from the same J2ME device use the same instance object of this Java class. The instance of the class is saved in the J2ME Proxy Server's servlet HttpSession object, so it is available as long as the HTTP session is valid.
The J2ME Client Library sends requests to the J2ME Proxy Server using HTTP, the only protocol that is guaranteed to support all MIDP implementations. Some wireless carriers are unable to correctly send an HTTP request if it exceeds a certain size. To work around this problem, the J2ME Client Library enables you to specify a maximum size in bytes for the request and response. In the J2ME stub generated for a Web service, edit the maxRequestSize
instance variable to set the maximum HTTP request and response size in bytes.
In most cases, you can use the server-generated client stub to invoke services registered with the J2ME Proxy Server. If you want to use an advanced feature such as call queuing, however, you must use the Client Library API directly, either from your own MIDlet, or by modifying the generated stub.
The API documentation for the J2ME Client Library is located at:
<ORACLE_HOME>\wireless\j2me\Javadoc\index.html
Use the ServiceFactory
class to create Service objects, which represent services registered with the J2ME Proxy Server. For convenient access, store the URL of the J2ME Proxy Server as a property of your MIDlet suite. For example, to create a Service
object for the TestWebService
class in the default namespace (assuming that the J2ME Proxy Server URL is stored in a MIDlet suite property called j2me_proxy_url
):
// Get the URL of the J2ME proxy server. String servURL = getAppProperty("j2me_proxy_url"); if (servURL == null) { servURL = "http://localhost:9010/wdk/proxy"; System.out.println("Unable to get j2me_proxy app property, using default: " + servURL); } ServiceFactory serviceFactory = ServiceFactory.getInstance(); Service service = serviceFactory.createService(servURL,Service.DEFAULT_ NAMESPACE,"TestWebService");
In the preceding code example, the first parameter to createService
is the URL of the J2ME Proxy Server, servURL the second is the namespace that contains the service (Service.DEFAULT_NAMESPACE
), and the third is the name of the registered service ("TestWebService"
).
Once you have an object of class Service
, you can create Call
objects. Each Call
object represents an operation of the remote Web service. For example, to create a Call
object for an operation called hello:
// Set cache timeout to 1 hour. Call call = service.createCall("hello", 60);
The first parameter to createCall
is the name of the operation of the Web service ("hello"
). The second parameter is the number of minutes to cache the response in the wireless device (60
). Enter 0 to disable response caching, and -1 to cache forever. For more information, see Section 12.1.4.1, "Response Caching".
Once you have a Call
object, you can invoke the Web service operation that it represents. Build a Java Vector to hold the parameters, and then call the Call
object's invoke
method. Assuming the hello operation takes a single String
parameter, invoke hello
is as follows:
// Put the parameters in a Vector. Vector params = new Vector(); params.addElement( new String("World") ); Response response = call.invoke(params, false);
The first parameter to the Call
object's invoke method is the Vector of parameters for the Web service operation. The second parameter may be set to true if you want to bypass the local cache. In other words, true ignores any valid cached response and forces a network call to the remote Web service. For more information, see Section 12.1.4.1, "Response Caching".
The invoke method returns a Response
object. Always check the Response
object's return code. If it is 0, then the call succeeded and you can use the Response
object's methods to access the information returned from the remote operation. If the return code is not 0, use the Response
object's getErrorMsg
method to get the error message. Assuming that the operation, hello
, returns a String
, perform the following:
// Check if the response is valid (0 = OK). int retCode = response.getReturnCode(); String retVal; if (retCode == 0) { retVal = response.getString(); } else { // return code not 0 retVal = "Call unsuccessful: " + response.getErrorMsg(); }
Use the Service.setProperty method
to set the following properties of the Service object, which represents a Web service registered with the J2ME Proxy Server:
Service.USERNAME
and Service.PASSWORD
- Set these properties to access Web services that require basic HTTP authentication.
Service.SESSION_MAINTAIN
- Set this property to enable or disable session support. For more information, see Section 12.1.1.6, "Session Support".
Service.MAX_REQUEST_SIZE - Set the maximum HTTP request and response size. For more information, see Section 12.1.4.4, "Request and Response Packetization".
Calls to Web services from wireless devices sometimes fail due to network connectivity problems. The J2ME Client Library enables MIDlets to queue Web service calls for later invocation. Once queued, the J2ME Client Library automatically retries the call periodically until it succeeds. You would queue a call following a network error using the ServiceManager.queueCall method, as follows:
try { Response response = call.invoke(params, false); ... catch (ServiceException se) { if (se.getErrorCode() == ServiceException.CONNECTION_FAILED) { int queuedId = ServiceManager.getInstance().queueCall(call); } ... } ...
Use the getQueuedCalls
method of the ServiceManager
class to retrieve queued calls. Set the boolean parameter of getQueuedCalls
to true to retrieve the IDs of queued calls that have already been invoked, and false to retrieve the IDs of queued calls that have not yet been invoked. Then, use the ServiceManager.getQueuedCall
method to get a Call
object from an ID, and use Call.getResponse
to retrieve the response to the call.
To find the queued Web service calls that have been invoked:
int[] queuedIds = ServiceManager.getInstance().getQueuedCalls( true ); for (int i = 0; i < queuedIds.length; i++){ //Retrieve Call object Call invokedCall = ServiceManager.getInstance().getQueuedCall(queuedIds[i]); Response response = invokedCall.getResponse(); ... }
To find the queued calls that have not been invoked:
... int[] queuedIds = ServiceManager.getInstance().getQueuedCalls( false ); ...
You should always call the close() method
of the ServiceManager
class when your MIDlet exits. This closes the RMS RecordStore used for Response Caching and Call Queuing. In a J2SE environment, this is performed in the ServiceManager's finalize()
method. However, J2ME does not support the finalize()
method. As a result, your code is responsible for closing the RMS RecordStore
used by the J2ME Client Library.
You must collect all the cleanup code for your MIDlet into one method, which you call from the MIDlet's destroyApp
method and from any other code that would cause the MIDlet to terminate (such as an Exit
command). In the following example, which is taken from one of the sample MIDlets included in the J2ME Client Library, the cleanup code is collected in the exitMIDlet
method:
private void exitMIDlet() { try { ServiceManager.getInstance().close(); } catch (Exception e) { } notifyDestroyed(); } protected void destroyApp(boolean unconditional) throws MIDletStateChangeException { exitMIDlet(); } public void commandAction(Command c, Displayable d) { if (c == exitCommand) { exitMIDlet(); } . . . }
Currently, the J2ME Web Services Client Library and Proxy Server support the following data types for Web service operation parameters and return values:
String
Integer
Boolean
Date
int
boolean
Vector
Hashtable
String
, Integer
, Boolean
, and Date
For every registered Web service, only those operations that use these data types can be registered with the J2ME Proxy Server and invoked using the J2ME Client Library.
The mapping of WSDL simple data types (which are XML Schema data types) to Java data types is as follows:
WSDL data type | Java data type |
---|---|
boolean |
Java.lang.Boolean |
integer |
Java.lang.Integer |
string |
Java.lang.String |
dateTime |
Java.util.Date |
When you have finished developing and testing your Web service-enabled J2ME MIDlets using the Wireless Development Kit, you can deploy them on a real OracleAS Wireless installation. You can do this by either one of the following two methods.
You may migrate your work by re-registering your Web services with the OracleAS Wireless J2ME Proxy Server. The Service Manager, one of the OracleAS Wireless tools, enables you to register Web services and generate J2ME stubs for them.
To deploy a service through re-registration:
If you made any manual modifications to the generated stubs, then you must manually modify the J2ME stubs that you already have as an alternative to Step 2. To do this, you must change the value of the _proxyUrl instance
variable. Update this URL with the correct hostname of the OracleAS Wireless server, the correct port number for OracleAS Wireless (typically 7777), and the correct path (typically: /mcs/wsproxy/proxy). For example:
private String _proxyUrl= "http://example.com:7777/mcs/wsproxy/proxy";
You can avoid reregistering every Web service that your MIDlets access by using the migration scripts. The process consists of downloading, or exporting, all information on the registered Web services to an XML file, and then uploading, or importing, this information from the XML file to a OracleAS Wireless installation.
migrateStandalone
This script is used to extract Web services registered with the WDK J2ME Proxy Server into an XML file. This script is located with the other WDK J2ME Proxy Server scripts for registration and management of Web services, at <ORACLE_HOME>/wireless/wdk/bin.
Usage:
j2mesdkmgr -export <xml file name>
Examples:
For Windows:
j2mesdkmgr -export C:\temp\registered_services.xml
For UNIX:
j2mesdkmgr.sh -export /usr/tmp/registered_services.xml
uploadJ2MEProxy
This script takes a single parameter: the name or full path to an XML file produced by the j2mesdkmgr -export script. All of the Web services described in this XML file are inserted into the database of this OracleAS Wireless and become registered with the J2ME Proxy Server of this OracleAS Wireless installation. This script is located in the directory <ORACLE_HOME>/wireless/bin/.
Usage:
uploadJ2MEProxy <xml file name>
Examples:
For Windows:
uploadJ2MEProxy.bat c:\temp\registered_services.xml
For UNIX:
uploadJ2MEProxy.sh /usr/tmp/registered_services.xml
You can skip this step by manually modifying the J2ME stubs that you already have.(Do this if you made any manual modifications to the generated stubs.) You must change the value of the _proxyUrl
instance variable to the correct hostname of the OracleAS Wireless server, the correct port number (typically 7777), and the correct path: /mcs/wsproxy/proxy. For example:
private String _proxyUrl= "http://example.com:7777/mcs/wsproxy/proxy";
At some point, you may want to migrate all of the information on Web services registered with the J2ME Proxy Server from one OracleAS Wireless installation to another. The process consists of downloading, or exporting, all information on the registered Web services of the source OracleAS Wireless to an XML file, and then uploading, or importing, this information from the XML file to the destination OracleAS Wireless. The scripts to do this are found in the following directory:
<ORACLE_HOME>/wireless/bin/
To migrate the information on Web services registered with the J2ME Proxy Server from on OracleAS Wireless installation to another:
downloadJ2MEProxy
This script takes a single parameter: the name or full path to an XML file. All Web services registered with the J2ME Proxy Server on the OracleAS Wireless where this script is run are extracted from the OracleAS Wireless database and placed into this XML file.
Usage:
downloadJ2MEProxy <xml file name>
Examples:
For Windows:
downloadJ2MEProxy.bat c:\temp\registered_services.xml
For UNIX:
downloadJ2MEProxy.sh /usr/tmp/registered_services.xml
uploadJ2MEProxy
This script takes a single parameter: the name or full path to an XML file produced by the downloadJ2MEProxy script. All of the Web services described in this XML file are inserted into the database of the OracleAS Wireless where this script is run and become registered with the J2ME Proxy Server of this OracleAS Wireless installation.
Usage:
uploadJ2MEProxy <xml file name>
Examples:
For Windows:
uploadJ2MEProxy.bat c:\temp\registered_services.xml
For UNIX:
uploadJ2MEProxy.sh /usr/tmp/registered_services.xml
You can skip this step by manually modifying the J2ME stubs that you already have.(Do this if you made any manual modifications to the generated stubs.) Change the value of the _proxyUrl
instance variable. Update this URL with the correct hostname of the OracleAS Wireless server, the correct port number (typically 7777), and the correct path (/mcs/wsproxy/proxy). For example:
private String _proxyUrl= "http://example.com:7777/mcs/wsproxy/proxy";
Digital Rights Management (DRM) enables the Content Manager to define the content usage policy after the content has been downloaded to the device. The usage policy defines the allowed permission associated with the content to the end user with additional temporal and monetary constraints if necessary. The common types of permission include:
Execute
: The right to invoke the application (for example, a J2ME game).
Display
: The right to display the content (for example, an image).
Play
: The right to play the content (for example, audio/video clip).
Print
: The right to create a hardcopy of the content (for example, image/jpeg).
Count
: The number of times the permission rights are granted (for example, the number of times you can run).
Interval
: The recurring period of time during which the permission rights are granted (for example, the number of hours you can use).
Start
and End
time: The pre-defined time range which the permission rights are granted.
There are many standards on expressing the digital rights. The one proposed by Open Mobile Alliance (OMA) for mobile content is a simplified version of the Open Digital Rights Language (ODRL) which means that digital rights should be expressed in an XML document following the syntax defined as ODRL Mobile Profile.
OracleAS Wireless includes two types of DRM policies that can be used to package J2ME applications: Count DRM Policy and Interval DRM Policy.
Count DRM Policy
: restricts the downloaded J2ME application to be run on the device up to x times, where x is the count specified by the Foundation Developer specifies while creating the policy.
Interval DRM Policy
: restricts the downloaded J2ME application to be run on the device for a specified period after it has been downloaded. The duration is specified in years, months, days, hours or minutes (or all of these). A standard conversion is used to handle years (365 days) and months (30 days).
The policy creation and the association of the policy with content is similar in both cases. The actual packaging of the policy with the content occurs at download time. The policy is enforced on the downloaded content after the user launches the downloaded application on the device. The Foundation Manager, one OracleAS Wireless Tools enables you to create built-in DRM policies Another Tool, the Content Manager, enables you to associate those policies with the J2ME application. See the Oracle Application Server Wireless Administrator's Guide for more information on the Content Manager.
OracleAS Wireless provides a platform to facilitate customized Digital Rights Policy and Content Enhancement for J2ME devices (OracleAS Wireless supports MIDP 1.0 complaint devices). Although Customized Digital Rights Policy and Content Enhancement are two completely different features, they are implemented using one framework in OracleAS Wireless.
The custom implementation of Digital Rights Policy or Content Enhancement is a two-step development process.
oracle.wireless.me.drm.DRMAgent
class for MIDP platform. This implementation is also referred to as a Digital Rights Object.
oracle.wireless.me.server.tools.drm.DRMPackager
interface, which implements the packaging logic of content with the Rights object developed in Step 1.
The following sections describe an example of PoweredByPolicy, where a splash screen is packaged with the associated applications.
package devguide; import Java.io.IOException; import Javax.microedition.midlet.*; import Javax.microedition.lcdui.*; import oracle.wireless.me.drm.DRMAgent; /** * <code>PoweredByPolicy</code> displays a "Powered By" splash * screen for a packaged content. The product copyright string may * be set using a property parameter using OracleAS Wireless Server. */ public class PoweredByPolicy extends DRMAgent implements CommandListener { /** * value of copyright */ private String copyright; public PoweredByPolicy(MIDlet ctx) { super(ctx); copyright = getProperty("copyright"); } /** * Displays a splash screen when the application starts up. */ public void onStartApp() { showSplash(); } /** * Creates a splash screen and sets it be the current display */ private void showSplash() { Form form = new Form("Powered By:"); try { form.append(Image.createImage("/devguide/9i.png")); } catch(IOException ioe){ form.append("Oracle AS Wireless"); } form.append(copyright); form.addCommand( new Command("OK", Command.SCREEN, 1)); form.setCommandListener(this); Display.getDisplay(context).setCurrent(form); } /** * Resume the normal application logic when user * attends to the splash screen */ public void commandAction(Command c, Displayable d) { resumeStartApp(); } } // end of class PoweredByPolicy
The PoweredByPolicy
class defines an implementation of oracle.wireless.me.drm.DRMAgent
(referred to as DRMAgent
hereafter). It defines a constructor with a single argument of type Javax.microedition.midlet.MIDlet
to satisfy the general contract of DRMAgent
, The implementation of onStartApp()
method displays a splash screen by calling the showSplash()
method that houses the business logic of the policy. Finally, the event handler of splash screen calls resumeStartApp()
for the packaged application to resume normally.
You can use the Sun J2ME Wireless Toolkit to compile and pre-verify the PoweredByPolicy class
. The required lib containing DRMAgent
class can be obtained from <IASW_HOME>/wireless/lib/j2medrm_demo.jar. The compiled and pre-verified class file or JAR file (which must also be pre-verified) containing the class file can be packaged by defining a packager as explained in Section 12.2.2.1.1.
oracle.wireless.me.server.tools.drm.DRMPackager
interface (referred to hereafter as DRMPackager
) defines API for packaging a MIDlet suite content with Digital Rights Policy or Content Enhancement developed in Section 12.2.2.1. The DRMPackager.getInitPropertiesDef()
method defines a contract to return a set of Properties used by tools such as user interfaces and publishing frameworks for discovering the parameter definitions of the Digital Rights Object. In turn, the OracleAS Wireless Runtime calls the init(Properties prop)
method with the value of the parameters. DRMPackager
defines the following API contract, which is invoked by OracleAS Wireless Runtime for packaging MIDlet Suite content with the Digital Rights object.
public byte[] packageDRMContent(byte[] content, Properties policyProperties, Document odrlXml,UserDevice device)
To simplify the implementation of DRMPackager
, oracle.wireless.me.server.tools.drm.J2MEDRMPackager
(referred to hereafter as J2MEDRMPackager
) defines the default implementation to specify the Digital Rights object and contain the JAR file using the setDRMAgentInfo(String agentClassName, String implJarFileName)
method. The implJarFileName
can be the absolute path of the file containing the Rights Objects. If not, the J2MEDRMPackager
performs a search for the specified JAR file in the CLASSPATH.
No customization is required for Rights object specified using ODRL.
The following class describes the packaging logic of the Rights object. The implementation assumes that JAR file containing the Rights object is archived in the C:\temp\poweredby.jar file. You do not have to restart the OracleAS Wireless server for changes made to the file containing the Digital Rights Object (C:\temp\poweredby.jar).
package devguide; import oracle.wireless.me.server.tools.drm.J2MEDRMPackager; import oracle.wireless.me.server.tools.drm.DRMPackager; import Java.util.Properties; /** * Powered By Rights Packager */ public final class PoweredByPolicyPackager extends J2MEDRMPackager { private static Properties defaultInitProperties = null; static { defaultInitProperties = new Properties(); // initializes the copyright property with a default value defaultInitProperties.setProperty("copyright", "Copyright 2003 Oracle Corporation. All Rights Reserved."); } private Properties initProperties = null; private static PoweredByPolicyPackager instance = new PoweredByPolicyPackager(); /** * Static factory that returns the instance of DRMPackager */ public static DRMPackager getInstance() { return instance; } private PoweredByPolicyPackager() { initProperties = defaultInitProperties; setDRMAgentInfo("devguide.PoweredByPolicy", "C:\\temp\\poweredby.jar"); } public Properties getInitPropertiesDef() { return defaultInitProperties; } }// end of the classpublic static DRMPackager getInstance() { return instance; }
Note:This class implements the general contract of
DRMPackager
by implementing the following method.
Note: To use the Foundation Developer, you must be granted the Foundation Manager role or the Super User role. |
To create a new Digital Rights Policy:
DRMPackager
implementation. See Figure 12-3, "Creating a New Digital Rights Policy".
Once the Digital Rights Object is created, you can associate it with an application link of a MIDlet application. You use the Service Manager to create a J2ME MIDlet application and then the Content Manager to create an application link to that MIDlet, which is a means to customize a application and publish it to a user group. For more information on creating a MIDlet application, see Section 5.3.6, "Creating a J2ME Application". For more information on creating an application link, see Oracle Application Server Wireless Administrator's Guide.
Using OracleAS Wireless J2ME Provisioning Server, Service Developers can upload, organize, and download J2ME applications. The uploaded J2ME application can then be published as an application using the Content Manager to users groups for downloading. The published service is available in the wireless user's application tree along with the other applications distributed to that user.
The OracleAS Wireless J2ME Provisioning Framework's Repository consists of the Content Repository and the framework which provide a means to create an association between the uploaded Digital Rights Management Policies (DRM) and the content. The association of the content with a DRM policy is done at the service creation time. All Content download transactions are recorded in an audit table.
The content repository stores the deliverable contents information for any uploaded content. The information is accessible through public APIs. Table 12-2 describes this information.
The Deliverable Content contains the meta-information of the actual content, which is available as a DeliverableContentItem
object
The provisioning transactions are logged in an audit table, the PROVISIONING_TRANSACTION_LOG (described in Table 12-4). These transactions are exposed as runtime metrics in the System Manager.
The framework enables the download operation to be tracked and controlled by allowing the implementer to plug in hooks at different stages. A custom implementation of the hooks can be plugged using the System Manager. The hooks need to be singleton classes and must contain the getInstance()
method to return their object reference.
Pre download Hook
: This is invoked at the time of application invocation before the actual download happens. The hook interface is supplied to the user download status object containing the user information and content information. The hook can return a true or false status to allow the user to proceed with the download or abort the operation respectively.
The ProvisioningPreDownloadHook
interface is defined in the public package oracle.panama.rt.hook
as follows:
public interface ProvisioningPreDownloadHook {
/** Delegate additional processing of this download
* @param UserDownloadStatus The download status object encapsulates
the current download transaction i.e. user, application, content,
version, mime type etc.
* @return boolean to indicate successful hook processing
* @see oracle.panama.model.UserDownloadStatus
*/
public boolean processRequest (
UserDownloadStatus uds
);
}
Post download Hook
: This hook is invoked at two stages during the post download cycle: after a successful download and after a device notification of a successful download.
The hook supplies the user download status object, which contains the user information and the content information. The hook implementation can decide to bill or audit the download operation at either of the stages.
The ProvisioningPostDownloadHook
interface is defined in the public package oracle.panama.rt.hook
as follows:
public interface ProvisioningPostDownloadHook { public static final int POST_DOWNLOAD = 1; public static final int POST_NOTIFY = 2; public boolean processRequest ( UserDownloadStatus uds, HttpServletRequest request, int hookType /* determines if it is a post notify or a post download hook */ ); }
You use the Service Manager to create a J2ME application. To access this tool, you must be granted either the Service Manager or Super User roles.
To create a J2ME MIDlet application:
The URL parameter points to the Download Service manager JSP that is included. You can also enter a custom JSP that provides the similar functionality.
The Content Manager enables you to publish the J2ME application to user groups. The application created using the Service Manager is published as an application link, which you create using the Content Manager. The Service Designer-created application, or master application, forms the core of the application link. Using the application link, you can customize the application. For example, you can customize the application to a user group or to a location. For more information, see Oracle Application Server Wireless Administrator's Guide.
To publish the J2ME application:
For the J2ME to be accessed (that is used) you must assign the application to a user group. Only users belonging to group to which you assign the J2ME application can use the application. In addition, group members must have at least one device address.
To access the application, users must log in to the Wireless and Voice portal using a URL similar to the following:
http://yourwirelessserver:7777/ptg/rm
When you choose the Morphing application (as depicted in Figure 12-9), the JSP displays a list all the J2ME contents uploaded for that application. Download the selected content to the device by clicking Download.
In the Customization Portal, you can view the download history log in to by clicking Applications and then View Download History.
|
![]() Copyright © 2003 Oracle Corporation. All Rights Reserved. |
|