high level display screens in j2me brands
J2ME (Java 2 Platform, Micro Edition) devices have invaded Asia and Europe and are starting to penetrate the US. Vendors have shipped millions of GSM (Global System for Mobile Communications) mobile phones and PDAs enabled with J2ME. No longer will a communication device, and eventually consumer devices in general, be constrained to basic functionalities. The possibilities are now endless. A Java solution allows a developer to reach numerous devices with just a single piece of code.
However, as these Java devices proliferate, we will see wide variations in how quickly different applications perform particular tasks due to the deviation in processor platforms, VM implementations, and device memory capabilities. Vendors who are not traditional VM providers may develop many of the VM implementations. Thus, characterizing device performance proves useful for writing applications. Developers can better understand each device"s limitations and strengths, and tailor applications to suit their intent.
Traditional benchmarking standards used in desktop and server environments, such as CaffeineMark, Linpack, SPECmarks, and Dhrystones, are comprehensive, but address many performance aspects that might not be directly relevant to J2ME devices. J2ME devices are inherently lightweight computing devices not meant to provide the same level of functionality as traditional desktop or server computing devices. Thus, we must examine how to measure performance on a J2ME device.
With less emphasis on heavy computation and complexity, J2ME devices instead emphasize simplification of user tasks. Given the typically small screen size and constrained data input mechanisms, the user interface and the computations associated with a good user experience are paramount in any J2ME application.
In this article, we approach performance measurement by examining J2ME devices" performance from a user functionality perspective. Rather than compare what processor and operating system a particular device runs, the tests focus on determining whether a good user experience results when accessing a particular function.
Since most J2ME-enabled devices currently in the market only support CLDC (Connected Limited Device Configuration) 1.0 and MIDP (Mobile Information Device Profile) 1.0, our performance benchmark is based on J2ME CLDC/MIDP 1.0. In the future, we will update our benchmark if real devices support higher J2ME versions.
As of May 15, 2002, more than 70 types of J2ME-enabled mobile devices were available in the market. The number is increasing dramatically. See Resources for a list of devices that support J2ME.
We test our benchmark applications with Sun Microsystems" J2ME Toolkit 1.04 beta (using Microsoft Windows 2000 and a Intel Pentium 4 1.5-GHz processor) for a better comparison. Although J2ME Wireless Toolkit 1.04 has functions for customizing a device, tracing exceptions, monitoring memory usage, and so on, we disable all those functions during benchmarking.
iPAQ 3760 supports PersonalJava (Jeode) and J2ME (IBM J9 VM). J2ME applications can be transformed to PersonalJava applications and tested in the PersonalJava environment using ME4SE technology. We test our benchmark in iPAQ 3760 using both the Jeode and IBM J9 environments.
Because different devices have different hardware settings, operating systems, and Java platform implementations, we provide a general benchmark standard and related applications to test the performance of various J2ME devices, and compare the performance fairly. We define the benchmark according to two different levels: kernel level and application level.Kernel level: We give a general idea of how fast a J2ME virtual machine executes those common basic instructions like logic-compare, loop, and method invocation. Compared to API calls, these are low-level instructions. We consider speed as the only performance standard here. The kernel-level test is application independent.
Application level: We give a general idea of how fast different J2ME devices execute common application interfaces like drawing a picture on the screen, opening an HTTP connection, storing data in a local file system, and parsing the XML document. Because some of these executions consume memory, we show the memory usage information during benchmarking. However, memory usage is not considered a benchmark standard since different J2ME devices differ little in memory usage.
We only benchmark general J2ME platform performance. We do not benchmark an individual application"s performance nor do we locate an application"s bottleneck to optimize it. But application developers may glean from our benchmark tests which parts of J2ME applications consume more processor time and heap size as compared to others. These benchmarks should show developers which J2ME-enabled devices perform better in certain areas.
Many companies define benchmarking strategies for Java platforms (some are free, some are not). Most benchmarks test desktop and server-side environments. Some provide powerful tools, with, for example, support for thread monitoring. For our standard, we follow the common procedures for performing benchmarks and use typical test areas.
In the kernel-level test, we pick up some of the common test areas for J2SE (Java 2 Platform, Standard Edition) benchmarks and add our own. In each test area, we execute a test-specific code in a loop. We receive the speed (loops per second) as the result. We built an application named JKernelMark (version 1.0, 10 KB), to perform the kernel-level benchmark.
In the application-level test, we define some test areas first. In each test area, we execute a test-specific code in a method. The speed (milliseconds per execution) is the result we receive. We built different benchmark applications according to different J2ME APIs: For J2ME standard APIs, we built an application named JAppsMark (version 1.0, 14 KB). For third-party APIs—XMLParser, for example—we built the JXMLMark application (version 1.0, 21 KB) to test XML-parsing performance using kXML.
For each benchmark, a MIDlet suite application performs the benchmark in the real device. The following sections explain what we test in each benchmark application.
JKernelMark tests the following:Sieve: Arithmetic algorithm that generates the mathematical results with predefined mathematical expressions and conditions.
Loop: JKernelMark tests how VMs optimize loop operations. Again, this test is a mathematical algorithm, which outputs a mathematical expression"s series of results. The benchmark puts the result into an array and reverses the array"s sequence.
Logic: JKernelMark tests how fast the VM executes logic instructions. JKernelMark creates many Boolean flags and then reverses those flag values in loops.
String: Here, we test the speed of the virtual machine executing typical string operations. JKernelMark creates a StringBuffer, continues to append a string into that StringBuffer in loops, and then tries to find the specified substring"s location.
Memory allocation and garbage collection: Here, JKernelMark tests the memory allocation speed and how garbage collection affects performance. It continues to create new objects and new arrays of bytes in memory (in each loop, it may create around 20 KB of objects in the heap). If the memory is not enough, the system will collect garbage and definitely affect the speed of allocating new objects.
JAppsMark tests the following:Network communication: This test records the time required by a Java phone to make an HTTP connection to a Web-based system and read 200 bytes of information from the response. The test execution time also includes the network delay. If the test is unsuccessful, we receive test-failed status. Even though a mobile phone is J2ME enabled, you still need a SIM (Subscriber Identity Module) card with either data service GSM or GPRS (General Packet Radio Service) activated. There are other ways to configure the J2ME devices to conduct this test, which we don"t highlight. For example, you can directly connect the handheld to a PC.
Low-level GUI: JAppsMark tests a Java phone"s performance in rendering the graphics to the screen. This test involves loading an image file and painting it on a canvas at 250 coordinates randomly. The time required to execute this application is recorded for different phone devices.
RMS (record management system): The RMS test is conducted using a MIDP application that creates a record store, adds records, retrieves sorted enumerated RecordStore objects, iterates through the records, and finally deletes a record store. The total time for this execution is recorded for phone devices from different manufacturers.
Parsing XML in J2ME is interesting because J2ME has no standard XML-related APIs. Since a normal XML parser is too heavy for mobile devices, performance—which includes runtime performance, user perception, and deployment code size—proves important when parsing XML in J2ME.
As Jonathan Knudsen explains in "Parsing XML in J2ME" (Sun Microsystems, 2002), there are three ways to parse XML:"A model parser reads an entire document and creates a representation of that document in memory. Model parsers use significantly more memory than other types of parsers.
A pull parser reads a little bit of a document at once. The application drives the parser through the document by repeatedly requesting the next piece.
Although MIDP 1.0 does not include an XML parser, due to the importance of XML, Sun plans to add a small, efficient XML parser to enable platform-independent data exchange in MIDP 2.0. Please check JSR (Java Specification Request) 118: Mobile Information Device Profile 2.0 for more details.
Among lightweight XML parsers, kXML is one of the most popular and standard APIs for XML parsing and can be used in the MIDP environment. Thus, we use kXML as the base API to benchmark the speed of parsing XML. We use kXML 1.21 since kXML 2.0 is still under alpha tests (when we designed our application).
Due to limited memory, J2ME mobile devices can only parse small XML files. We created a simple and small XML file, shown below, for our benchmark. DTD (document type definition) is not needed since kXML does not validate DTD (which costs processor time and memory).
We parse the whole XML file from beginning to end in the usual way—go through the whole XML document and read every tag, every attribute, and every value. Please check Jonathan Knudsen"s article "Parsing XML in J2ME" for more details.
Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about products and services that can be purchased through this site.
This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.
To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:
For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.
For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.
Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites, develop new products and services, conduct educational research and for other purposes specified in the survey.
Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.
If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email information@informit.com.
On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.
We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users" wishes when a user submits their information through our Contact Us form.
Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.
Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.
This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.
Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.
Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.
If a user"s personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user"s personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user"s account.
Users can always make an informed choice as to whether they should proceed with certain services offered by InformIT. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.informit.com/u.aspx.
While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.
California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson"s commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.
To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.
This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.
We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.
This chapter explains the Java 2 platform architecture and its security features as they apply to building Java applications. In particular, it describes the various Java platforms and the core security features that contribute to the end-to-end security of Java-based applications running on various systems—from servers to stand-alone computers, computers to devices, and devices to smart cards.
Sun"s Java philosophy of "Write Once, Run Anywhere" has been an evolving success story since its inception, and it has revolutionized the computing industry by delivering to us the most capable platform for building and running a wide range of applications and services. In general, the Java platform provides a general-purpose object-oriented programming language and a standard runtime environment for developing and delivering secure, cross-platform application solutions that can be accessed and dynamically loaded over the network or run locally.
With the release of the Java 2 Platform, Sun categorized the Java technologies under three key major editions in order to simplify software development and deployment. The Java 2 Standard Edition (J2SE) provides the runtime environment and API technologies for developing and executing basic Java applications, and it also serves as the secure foundation for running Java enterprise applications. The Java 2 Enterprise Edition (J2EE), or the J2EE Platform, is a set of standards and API technologies for developing and deploying multi-tier business applications. To support Java on microdevices and embedded systems, Java 2 Micro Edition (J2ME) provides the runtime environment and API technologies for addressing the needs of consumer electronics and devices. With its widespread adoption, today Java technology is enabled and executed from smart cards to microdevices, handhelds to desktops, workstations to enterprise servers, mainframes to supercomputers, and so on.
To facilitate end-to-end security of the Java platform-based application solutions, the Java runtime environment (JRE) and the Java language provide a solid security foundation from the ground up by imposing strong format and structural constraints on the code and its execution environment. This distinguishes the Java platform from other application programming languages—it has a well-defined security architectural model for programming Java-based solutions and their secure execution.
In this chapter, we will explore the various Java platforms and the intricate details of their security architecture that contribute to the end-to-end security of Java-based application solutions. In particular, we will study Java security and the inherent features of the following technologies:
Security has been an integral part of Java technology from day one. Security is also an evolving design goal of the Java community—building and running secure and robust Java-based network applications. The primary reason for Java"s success today as a secure execution environment is the intrinsic security of its architectural foundation—the Java Virtual Machine (JVM) and the Java language. This foundation achieves the basic Java security goal and its definitive ways for extending security capabilities to ensure features such as confidentiality, integrity, trust, and so forth. A second reason for its success is its ability to deliver an interoperable and platform-neutral security infrastructure that can be integrated with the security of the underlying operating system and services.
The JVM is an abstract computing engine that resides on a host computer. It is the execution environment for the Java programming language and has the primary responsibility for executing the compiled code by interpreting it in a machine-independent and cross-platform fashion. The JVM is often referred to as the Java runtime environment. While executing a Java program running on top of the JVM, the JVM insulates the application from the underlying differences of the operating systems, networks, and system hardware, thus ensuring cross-platform compatibility among all of the implementations of the Java platform.
The Java language allows creation of general-purpose programs called Java classes that represent a Java program or an application. The Java classes compile into a format called Java"s executable bytecodes, which are quite similar to the machine language that can run on top of a JVM. The JVM also allows users to download and execute untrusted programs and applications from remote resources or over a network. To support delivery of Java components over the network, the JVM controls the primary security layer by protecting users and the environment from malicious programs. To enable security, the JVM enforces stringent measures ensuring systems security on the host client machine and its target server environments.
Distributing the executable Java bytecode over a network or running automatically inside a Web browser or a client"s machine leads to different security risks and attacks, such as disclosure of the target environment to the untrusted applications and damage or modification of the client"s private information and data. For example, Java applets downloaded from a network are not allowed to have access to, read from, or write to a local file system. They are also not allowed to create network connections to any host system except the one where they are deployed. On the other hand, stand-alone Java applications that reside and run locally as trusted applications are not subjected to these security features. The key issue is that allowing untrusted applications such as Java applets to be downloaded from a network via a Web browser and letting them access certain resources on the host computer paves the way for security breaches and becomes a potential avenue for the spread of viruses. To prevent known security breaches and threats, the JVM provides a built-in Java security architecture model, configurable security policies, access control mechanisms, and security extensions. Because of the built-in JVM safety features, Java programs can run safely and are more securely protected from known vulnerabilities.
Java is a general-purpose object-oriented programming language similar to C++. It delivers platform-neutral compiled code that can be executed using a JVM and is intended for use in distributed application environments, heterogeneous systems, and diverse network environments. The Java language is also designed to provide for the security and integrity of the application and its underlying systems at all levels—from the Java language constructs to the JVM runtime and from the class library to the complete application.
The language defines all primitives with a specific size and all operations are defined to be in a specific order of execution. Thus, the code executed in different JVMs will not differ from the specified order of execution.
The language provides access-control functionality on variables and methods in the object by defining name space management for type and procedure names. This secures the program by restricting access to its critical objects from untrusted code. For example, access is restricted by qualifying the type members as public, protected, private, package, etc.
The Java language does not allow defining or dereferencing pointers, which means that programmers cannot forge a pointer to the memory or create code defining offset points to memory. All references to methods and instance variables in the class file are done via symbolic names. The elimination of pointers helps to prevent malicious programs like computer viruses and misuse of pointers such as accessing private methods directly by using a pointer starting from the object"s pointer, or running off the end of an array.
The Java language is a strongly typed language. During compile time, the Java compiler does extensive type checking for type mismatches. This mechanism guarantees that the runtime data type variables are compatible and consistent with the compile time information.
The language allows declaring classes or methods as final. Any classes or methods that are declared as final cannot be overridden. This helps to protect the code from malicious attacks such as creating a subclass and substituting it for the original class and override methods.
The Java Garbage Collection mechanism contributes to secure Java programs by providing a transparent storage allocation and recovering unused memory instead of deallocating the memory using manual intervention. This ensures program integrity during execution and prevents programmatic access to accidental and incorrect freeing of memory resulting in a JVM crash.
With these features, Java fulfills the promise of providing a secure programming language that gives the programmer the freedom to write and execute code locally or distribute it over a network.
In the previous two sections, we briefly looked at the basic security features provided by the JVM and the Java language. As part of its security architecture, Java has a built-in policy-driven, domain-based security model. This allows implementing security policies, protecting/controlling access to resources, rule-based class loading, signing code and assigning levels of capability, and maintaining content privacy.
In the first release of the Sun Java Platform, the Java Development Kit 1.0.x (JDK) introduced the notion of a sandbox-based security model. This primarily supports downloading and running Java applets securely and avoids any potential risks to the user"s resources. With the JDK 1.0 sandbox security model, all Java applications (excluding Java applets) executed locally can have full access to the resources available to the JVM. Application code downloaded from remote resources, such as Java applets, will have access only to the restricted resources provided within its sandbox. This sandbox security protects the Java applet user from potential risks because the downloaded applet cannot access or alter the user"s resources beyond the sandbox.
The release of JDK 1.1.x introduced the notion of signed applets, which allowed downloading and executing applets as trusted code after verifying the applet signer"s information. To facilitate signed applets, JDK 1.1.x added support for cryptographic algorithms that provide digital signature capabilities. With this support, a Java applet class could be signed with digital signatures in the Java archive format (JAR file). The JDK runtime will use the trusted public keys to verify the signers of the downloaded applet and then treat it as a trusted local application, granting access to its resources. Figure 3-1 shows the representation of a sandbox in the JDK 1.1 security model.
The release of J2SE [J2SE] introduced a number of significant enhancements to JDK 1.1 and added such features as security extensions providing cryptographic services, digital certificate management, PKI management, and related tools. Some of the major changes in the Java 2 security architecture are as follows:
In the Java 2 security architecture, all code—regardless of whether it is run locally or downloaded remotely—can be subjected to a security policy configured by a JVM user or administrator. All code is configured to use a particular domain (equivalent to a sandbox) and a security policy that dictates whether the code can be run on a particular domain or not. Figure 3-2 illustrates the J2SE security architecture and its basic elements.
): In J2SE, all local Java applications run unrestricted as trusted applications by default, but they can also be configured with access-control policies similar to what is defined in applets and remote applications. This is done by configuring a ProtectionDomain, which allows grouping of classes and instances and then associating them with a set of permissions between the resources. Protection domains are generally categorized as two domains: "system domain" and "application domain." All protected external resources, such as the file systems, networks, and so forth, are accessible only via system domains. The resources that are part of the single execution thread are considered an application domain. So in reality, an application that requires access to an external resource may have an application domain as well as a system domain. While executing code, the Java runtime maintains a mapping from code to protection domain and then to its permissions.
Protection domains are determined by the current security policy defined for a Java runtime environment. The domains are characterized using a set of permissions associated with a code source and location. The java.security.ProtectionDomain class encapsulates the characteristics of a protected domain, which encloses a set of classes and its granted set of permissions when being executed on behalf of a user.
): In essence, permissions determine whether access to a resource of the JVM is granted or denied. To be more precise, they give specified resources or classes running in that instance of the JVM the ability to permit or deny certain runtime operations. An applet or an application using a security manager can obtain access to a system resource only if it has permission. The Java Security API defines a hierarchy for Permission classes that can be used to configure a security policy. At the root, java.security.Permission is the abstract class, which represents access to a target resource; it can also include a set of operations to construct access on a particular resource. The Permission class contains several subclasses that represent access to different types of resources. The subclasses belong to their own packages that represent the APIs for the particular resource. Some of the commonly used Permission classes are as follows:
Example 3-1 shows how to protect access to an object using permissions. The code shows the caller application with the required permission to access an object.
Permissions can also be defined using security policy configuration files (java.policy). For example, to grant access to read a file in "c:\temp\" (on Windows), the FilePermission can be defined in a security policy file (see Example 3-2).
Policy: The Java 2 security policy defines the protection domains for all running Java code with access privileges and a set of permissions such as read and write access or making a connection to a host. The policy for a Java application is represented by a Policy object, which provides a way to declare permissions for granting access to its required resources. In general, all JVMs have security mechanisms built in that allow you to define permissions through a Java security policy file. A JVM makes use of a policy-driven access-control mechanism by dynamically mapping a static set of permissions defined in one or more policy configuration files. These entries are often referred to as grant entries. A user or an administrator externally configures the policy file for a J2SE runtime environment using an ASCII text file or a serialized binary file representing a Policy class. In a J2SE environment, the default system-wide security policy file java.policy is located at
Example 3-3 is a policy configuration file that specifies the permission for a signed JAR file loaded from "http://coresecuritypatterns.com/*" and signed by "javaguy," and then grants read/write access to all files in /export/home/test.
The J2SE environment also provides a GUI-based tool called "policytool" for editing a security policy file, which is located at "
The effective policy of the JVM runtime environment will be the union of all permissions in all policy files. To specify an additional policy file, you can set the java.security.policy system property at the command line:
): Each Java application can have its own security manager that acts as its primary security guard against malicious attacks. The security manager enforces the required security policy of an application by performing runtime checks and authorizing access, thereby protecting resources from malicious operations. Under the hood, it uses the Java security policy file to decide which set of permissions are granted to the classes. However, when untrusted classes and third-party applications use the JVM, the Java security manager applies the security policy associated with the JVM to identify malicious operations. In many cases, where the threat model does not include malicious code being run in the JVM, the Java security manager is unnecessary. In cases where the SecurityManager detects a security policy violation, the JVM will throw an AccessControlException or a SecurityException.
In a Java application, the security manager is set by the setSecurityManager method in class System. And the current security manager is obtained via the getSecurityManager method (see Example 3-4).
The class java.lang.SecurityManager consists of a number of checkXXXX methods like checkRead (String file) to determine access privileges to a file. The check methods call the SecurityManager.checkPermission method to find whether the calling application has permissions to perform the requested operation, based on the security policy file. If not, it throws a SecurityException.
If you wish to have your applications use a SecurityManager and security policy, start up the JVM with the -Djava.security.manager option and you can also specify a security policy file using the policies in the -Djava.security.policy option as JVM arguments. If you enable the Java Security Manager in your application but do not specify a security policy file, then the Java Security Manager uses the default security policies defined in the java.policy file in the $JAVA_HOME/jre/lib/security directory. Example 3-5 programmatically enables the security manager.
): The access controller mechanism performs a dynamic inspection and decides whether the access to a particular resource can be allowed or denied. From a programmer"s standpoint, the Java access controller encapsulates the location, code source, and permissions to perform the particular operation. In a typical process, when a program executes an operation, it calls through the security manager, which delegates the request to the access controller, and then finally it gets access or denial to the resources. In the java.security.AccessController class, the checkPermission method is used to determine whether the access to the required resource is granted or denied. If a requested access is granted, the checkPermission method returns true; otherwise, the method throws an AccessControlException.
Codebase: A URL location of class or JAR files are specified using codebase. The URL may refer to a location of a directory in the local file system or on the Internet. Example 3-7 retrieves all the permissions granted to a particular class that"s been loaded from a code base. The permissions are effective only if the security manager is installed. The loaded class uses those permissions by executing Class.getProtectionDomain() and Policy.getPermissions().
To ignore the default policies in the java.security file, and only use the specified policy, use "==" instead of "=". With the policy just presented, you may run the following:
Bytecode verifier: The Java bytecode verifier is an integral part of the JVM that plays the important role of verifying the code prior to execution. It ensures that the code was produced consistent with specifications by a trustworthy compiler, confirms the format of the class file, and proves that the series of Java byte codes are legal. With bytecode verification, the code is proved to be internally consistent following many of the rules and constraints defined by the Java language compiler. The bytecode verifier may also detect inconsistencies related to certain cases of array bound-checking and object-casting through runtime enforcement.
ClassLoader: The ClassLoader plays a distinct role in Java security, because it is primarily responsible for loading the Java classes into the JVM and then converting the raw data of a class into an internal data structure representing the class. From a security standpoint, class loaders can be used to establish security policies before executing untrusted code, to verify digital signatures, and so on. To enforce security, the class loader coordinates with the security manager and access controller of the JVM to determine the security policies of a Java application. The class loader further enforces security by defining the namespace separation between classes that are loaded from different locations, including networks. This ensures that classes loaded from multiple hosts will not communicate within the same JVM space, thus making it impossible for untrusted code to get information from trusted code. The class loader finds out the Java application"s access privileges using the security manager, which applies the required security policy based on the requesting context of the caller application.
With the Java 2 platform, all Java applications have the capability of loading bootstrap classes, system classes, and application classes initially using an internal class loader (also referred to as primordial class loader). The primordial class loader uses a special class loader SecureClassLoader to protect the JVM from loading malicious classes. This java.security.SecureClassLoader class has a protected constructor that associates a loaded class to a protection domain. The SecureClassLoader also makes use of permissions set for the codebase. For instance, URLClassLoader is a subclass of the SecureClassLoader. URLClassLoader allows loading a class or location specified with a URL.
Keystore and Keytool: The Java 2 platform provides a password-protected database facility for storing trusted certificate entries and key entries. The keytool allows the users to create, manage, and administer their own public/private key pairs and associated certificates that are intended for use in authentication services and in representing digital signatures.
We will take a look in greater detail at the usage of the Java keystore and keytool and how these tools help Java security in the section entitled "Java Security Management Tools," later in this chapter.
Designing applications for small computing devices is a challenge, to say the least,primarily because of the limited resources found in these devices. The small computing device contains minimal memory and storage room for persistent data. Many traditional systems design methods and best practices are simply not appropriate for building applications to run on small computing devices
Asmall computing device has a radically different hardware configuration than traditional computing devices such as desktop computers and servers. Traditional computing devices are under Continuous power from the power grid, while some small computing devices such as cellular telephones rely on battery power that diminishes during the course of operation. Apower grid powers other small computing devices such as set-top boxes and appliances. Another important difference between traditional computing devices and small computing devices is the network connection
1.programs and data are stored in a small computer device’s memory, commonly referred to as primary storage. These are lost when the device drops power, although many devices have a secondary battery to retain programs and data as long as possible. 2.Once lost, programs and data must be reloaded into the device. Secondary storage is not usually available on a small computing device. 3.Therefore, a J2ME application should rely on data stored offline in a desktop computer or server rather than data stored in the device’s primary storage. 4.Data stored offline can be reloaded into the device using a network connection.
5.Don’t expect a mobile small computing device to transmit and receive data at the same rate as a device on a hard-wired network. 6.Data transmission between a mobile small computing device and a traditional computing device is slow in comparison to a hard-wired network connection because radio and infrared technology offers a narrower transmission bandwidth than that found in hard-wired network connections. 7.A bandwidth is the number of communications channels available to transmit bits of data simultaneously.
Many users of your J2ME application expect the same response from your application as they experience from desktop computer applications. Therefore, you must design your J2ME application to minimize and optimize data transmission with offline data sources. One way to optimize your J2ME application is called ROMizing the application for run-time operations. ROMizing creates a machine code image of an application before the application is deployed on the small computing device
Best Practices Over time and through trial and error, J2ME developers have come up with the best way to solve complex J2ME programming problems. And these techniques are called BEST PRACTICES AND PATTERNS. Best practices are proven design and programming techniques used to build J2ME systems. Patterns are routines that solve common programming problems that occur in such systems. Professional developers use best practices and patterns to avoid making common mistakes when designing and building a J2ME application
Typically, you design an application by dividing it into objects that have associated DATA AND METHODS. Let’s use an order form as an example. An order form is an object that has an order number, customer number, product number,and related data. Likewise, an order form has functionality associated with it, such as inserting a new order, modifying an existing order, and deleting an order. And the order form has one or more menu options that enable a user to navigate the order form.
The size of your J2ME application is critical to deploying the application efficiently. The best practice is to remove unnecessary components of your application in order to reduce the size of the overall application.
Limit the Use of Memory In addition to removing unnecessary features from your application, design your application to manage memory efficiently. There are two types of memory management that should be used in the J2ME application. These are overall memory management and peak time memory management. Overall memory management is designed to reduce the total memory requirements of an application. Peak memory management focuses on minimizing the amount of memory the application uses at times of increased memory usage on the device.
A primary way to reduce total memory requirements of your application is to avoid using object types. Instead, use scalar types, which use less memory than object types. Likewise, always use the minimum data type suited for storing data. Peak time memory management requires you to manage garbage collection. J2ME does have a garbage collector, but as with J2SE, you don’t know when the garbage collector will collect your garbage. Therefore, it is critical that you clean up after the application is finished using memory.
This reduces both memory allocation and the need for processing power. Memory allocation is reduced because multiple references can use the same object at different times in the application’s life cycle. Obviously, both objects that use the same memory cannot run simultaneously. The need for processing power is reduced because a portion of the processing required to allocate new memory doesn’t need to be invoked since memory has already been allocated when the object is instantiated.
Small computing devices are designed to run applications that do not require intensive processing because processing power common to desktop computers is not available onthese devices. This means that you must design your J2ME application to perform minimal processing on the small computing device. The alternative is to build a client-service J2ME application or web services J2ME application. There are two levels of operation in a client-service application. These are the client level and the server level. The small computing device runs the client level that provides user interface and presentation functionality to the application. The server-side level processes client requests and returns the result to the small computing device for presentation to the user. Nearly all processing occurs on the server side of the application.
2.The first layer is the client tier, sometimes referred to as the presentation tier. This is where a person interacts with an application. 3.The second layer contains the business logic that is used to fulfill requests from a client by calling appropriate software on the processing tier. 4.Processing software returns results to the business logic layer, and in turn, those results are returned to the client for presentation to the user.
Besides lightening the processing load on the small computing device, you must also be concerned about the availability of a network connection. Cellular telephone networks use technology that attempts to maintain connection as the mobile device moves from one cell to another cell. In reality there are dead zones where the mobile device is outside the range of the cellular telephone transceiver. The drop in communication can occur without warning, as many cellular telephone users have experienced.
Although you cannot avoid a break in communication, you can take steps to reduce the impact on the user of your application. Begin by keeping transmissions short—transfer the minimum information necessary to accomplish a task. Consider using store-forwarding technology and a server-side agent whenever your J2ME application requests a lot of information. A server-side agent is software running on the server that receives a request from a mobile device and then retrieves requested information from a data source, which is very similar to the business logic layer of web services technology.
Most desktop applications have a standard set of graphical user interface objects such as text boxes, combo boxes, radio buttons, check boxes, and push buttons. However, small computing devices use a variety of user display and input devices. Some devices, such as a cellular telephone, have an inch-square display and a telephone keypad for data input. There is a standard display and input for desktop computers, but you cannot say the same about small computing devices. The variety of shapes and hardware configurations found in devices classified as small computing devices makes it nearly impossible to standardize on a set of user interface objects for these devices.
It is critical that you design a user interface that takes advantage of convenient features found on a small computing device and avoid user interactions that are awkward to perform. If you decide to create a user interface containing a menu, consider the available input mechanisms of the small computer device before beginning your design. Some devices have touch screens that enable you to use icons, rather than words, to represent menu options. Other devices, such as cellular telephones, have limited keypads. Let’s say three options are presented in a list on the screen. Typically, you identify each option with a shortcut key that is a sequence of letters (A, B, C), or numbers (1, 2, 3), or a letter within the name of the option.
Use Local Variables Limited resource is the theme that echoes through design considerations for applications that run on small computing devices. As a developer, you cannot assume there are sufficient resources on every small computing device to run your application. You’ll find this line of thought radically different from the mind- set used to write applications for desktop devices and server devices, where you can safely assume that sufficient resources exist to run an application. Data storage is a key area within an application for reducing excessive processing. In many applications, developers assign values to data members of a class rather than using a local variable. You can increase processing of your application if you eliminate the extra steps of accessing a data member of a class by assigning values to local variables.
Concatenating strings is another processing drain that can be avoided by designing an application to eliminate concatenations or at least reduce the number of concatenations to the minimum necessary to achieve the objective of the application.
A string is an array of characters terminated by a NULL and stored sequentially in memory. Let’s assume the application wants to compare two strings, both of which are four characters and reside in memory. The application instructs the small computing device to copy the first character of each string into the CPU for comparison. This process continues until either the null character is reached or a letter pair is different. The entire process might require ten reading instructions and five comparison instructions, depending on when a mismatch is discovered
It is very common for developers to invoke one or multiple threads within an operation. Invoking a thread is a way of sharing a routine among other operations. For example, a sort routine can be shared simultaneously by multiple operations that must sort data. Each operation invokes the sort routine independent of other operations, although the same code is being executed for all operations.
Deadlocks and other conflicts might arise when multiple operations use the same routine. These problems are avoided by synchronizing the invocations of a thread, as you probably remember when you learned Java programming. Always use a thread whenever an operation takes longer than a tenth of a second to run because a thread requires less overhead than non-thread invocation methods, and therefore you’ll see a performance increase in your application.
A common way of reducing the overhead of starting a new thread is to create a group of thread objects that are assigned threads as needed by operations within an application. Less processing is required to assign a thread to an existing thread object than to create a new thread object. Grouping thread objects is made possible by the ThreadGroup class, but J2ME does not support this class. You can work around it, however, by creating your own grouping using the Collection class. You can store groups of thread objects in a collection and then use standard collection methods to start and stop threads in the collection and assign threads to particular thread objects within the collection.
Version management is always a concern of application developers, especially when applications are invoked from within a small computing device. You can reduce and possibly eliminate problems associated with multiple versions of the same application by requiring invocation of the application from a web server. Here’s how a small computing device can invoke a web server–based J2ME application: midp -transient Rather than running a local JAD file, the -transient option specifies that the JAD file is located on a web server identified by the URL on the command line. In this way, the developer only needs to update one copy of the application, and distribution is handled by making the latest version of the application available on the web server.
There will likely be occasions when you need to have your application perform in a certain way, depending on the type of small computing device that runs the application. First, design your application with switches that activate and/or deactivate routines depending on the value of a setting. A setting is a value assigned to a variable that is either created within the application or passed to the application as a command line parameter. J2ME applications are capable of reading the value of a setting from a JAD file and manifest file.
The J2ME program in Listing 4-2 illustrates how to read this user-defined value during run time without having to recompile or repackage the application. A user-defined value is read by invoking the getAppProperty() method and passing the name of the user-defined value to the getAppProperty() method. The getAppProperty() returns the user-defined value from either the manifest file or the JAD file depending on which of these files contains the user-defined value. Model-Version user-defined value defined in the JAD file and displays the value on the screen. Of course, you can create a compound statement that invokes the getAppProperty() method and then assigns the returned value to a variable or uses the return value directly in an expression.
MIDlet-Version: 2.0 MIDlet-Vendor: MyCompany MIDlet-Jar-URL: MIDlet-1: BestMIDlet, /images/BestMIDlet.png, Best.BestMIDlet Model-Version: M253 public class BasicMIDletShell extends MIDlet { public void startApp() System.out.println(getAppProperty("Model-Version")); } public void pauseApp() public void destroyApp( boolean unconditional)
A drop-down box is a convenient way for users to choose an item from a list of possible items, such as an abbreviation for a state. Traditionally, content of a drop-down box is loaded from the data source once when the application is invoked and remains in memory until the application terminates. While caching the contents in memory is a best practice in Java programming, caching is a questionable practice when developing a J2ME application. Loading a list of data for a drop-down box when the J2ME application is invoked is efficient if this is a short list that doesn’t require substantial memory resources. Load the list dynamically from a server whenever the list is long. Release the list once the user has made a selection, and then reload the list the next time the drop-down box is invoked. In this way, memory used to store the list can be reused between calls to the drop-down box.
Nearly every J2ME application has an interface that enables user interactions with the application. The user interface can be as simple as pressing a button on the small computing device, which causes the application to react, or as complex as displaying a form containing check boxes, radio buttons, lists, and other objects common to many applications. Selections made by a user are considered events that are forwarded to your application by the device’s application manager for processing. The application’s developer must write code that recognizes an event and then reacts to the event by performing a task based on the nature of the application.
J2ME User Interfaces A user interface is a set of routines that displays information on the screen, prompts the user to perform a task, and then processes the task. For example, a J2ME application might display a list of menu options, such as Inbox, Compose, and Exit, and then prompt the user to make a selection by moving the cursor keys and pressing a key on the small computing device. The device’s application manager passes the selection to the application, where it is compared with known options. If a match occurs, the application performs the steps necessary to process the option. A developer can use one of three kinds of user interfaces for an application. These are a command, form, or canvas.
A command-based user interface consists of instances of the Command class. An instance of the Command class is a button that the user presses on the device to enact a specific task. For example, Exit is an instance of the Command class associated with an Exit button on the keypad to terminate the application. The Help button is also an instance of the Command class that is linked to the Help key on the device, which is used whenever the user requires assistance. A form-based user interface consists of an instance of the Form class that contains instances derived from the Item class such as text boxes, radio buttons, check boxes, lists, and other conventions used to display information on the screen and to collect input from the user. A form is similar to an HTML form. A canvas-based user interface consists of instances of the Canvas class within which the developer creates images such as those used in a game.
Display Class The device’s screen is referred to as the display, and you interact with the display by obtaining a reference to an instance of the MIDlet’s Display class. Each MIDlet has one and only one instance of the Display class. Every J2ME MIDlet that displays anything on the screen must obtain a reference to its Display instance. This instance is used to show instances of Displayable class on the screen. The Displayable class has two subclasses. These are the Screen class and the Canvas class. The Screen class contains a subclass called the Item class, which has its own subclasses used to display information or collect information from a user (such as forms, check boxes, radio buttons). The Screen class and its derived classes are referred to as high-level user interface components. The Canvas class is used to display graphical images such as those used for games. Displays created using the Canvas class are considered a low-level user interface and are used whenever you need to display a customized screen.
Instances of classes derived from the Displayable class are placed on the screen by calling the setCurrent() method of the Display class. The object that is to be displayed is passed to the setCurrent() method as a parameter. It is important to note that instances of derived classes of the Item class are not directly displayable and must be contained within an instance of a Form class. An instance of an Item class appears on the screen when the setCurrent() method is used to show the form. The getCurrent() method of the Display class is used by a MIDlet to retrieve information about the instances of derivatives of the Displayable class.
Listing 5-1 contains the JAD file for this MIDlet, and Listing 5-2 illustrates how the Display class is used to determine the color attribute of the small computing device’s screen. In this example, the MIDlet invokes the isColor() method of the Display class to determine whether the screen is capable of displaying color. If so, the MIDlet displays an instance of the TextBox class reporting that the device has a color screen; otherwise the instance reports that the device is incapable of displaying color. Of course, in a realworld MIDlet, the response returned by the isColor() method is used within the MIDlet either to activate or deactivate routines that manipulate color on the screen.
MIDlet-Version: 1.0 MIDlet-Vendor: MyCompany MIDlet-Jar-URL: CheckColor.jar MIDlet-1: CheckColor, CheckColor.png, CheckColor MicroEdition-Configuration: CLDC-1.0 MicroEdition-Profile: MIDP-1.0 MIDlet-JAR-SIZE: 100 import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class CheckColor extends MIDlet implements CommandListener private Display display; private Form form; private TextBox textbox; private Command exit; public CheckColor() { display = Display.getDisplay(this); exit = new Command("Exit", Command.SCREEN, 1); String message=null; if (display.isColor())
{ message="Color display."; } else { message="No color display"; } textbox = new TextBox("Check Colors", message, 17, 0); textbox.addCommand(exit); textbox.setCommandListener(this); } public void startApp() { display.setCurrent(textbox); public void pauseApp() public void destroyApp(boolean unconditional) { } public void commandAction(Command command, Displayable displayable) if (command == exit) destroyApp(true); notifyDestroyed(); } } }
Command Class You create an instance of the Command class by using the Command class constructor within your J2ME application. The Command class constructor requires three parameters. These are the command label, the command type, and the command priority. The Command class constructor returns an instance of the Command class. The following example illustrates a cancel command. The first parameter of the command declaration is Cancel. cancel = new Command("Cancel", Command.CANCEL, 1);
Command Listener Every J2ME application that creates an instance of the Command class must also create an instance that implements the CommandListener interface. The CommandListener is notified whenever the user interacts with a command by way of the commandAction() method. Classes that implement the CommandListener must implement the commandAction() method, which accepts two parameters. The first parameter is a reference to an instance of the Command class, and the other parameter is a reference to the instance of the Displayable class, as public void commandAction(Command command, Displayable displayable) { if (command == cancel) { destroyApp(false); notifyDestroyed(); } } The device’s application manager calls the commandAction(