| C H A P T E R 2 |
|
Application Programming Models |
Three application models are supported in the runtime environment for the Java Card Platform, v3.0.1, Connected Edition. All three, including the web application model, and the two applet-based application models are described in this chapter.
Also described in this chapter are the naming, dispatching and thread management aspects of application programming, as well as object persistence and transaction management.
This chapter describes the following aspects of the application programming model:
The Java Card Platform, Connected Edition MUST support a subset of the Java Servlet Specification v2.4 web application model. This section gives an overview of the web application model, whereas the supported subset of the web application model is described in detail in the Java Servlet Specification for the Java Card Platform, v3.0.1, Connected Edition.
Web applications interact with off-card web clients via a request/response paradigm implemented by the web container. On the Java Card Platform, the web container MUST support HTTP and HTTPS as protocols for requests and responses.
The web container’s main responsibilities are:
The server connection endpoints over which requests and responses are received from clients and sent to clients, respectively, by the web container are called container-managed endpoints.
A web application is typically composed of:
Developers are required to implement the following components of web applications: servlets, request and response filters, and lifecycle event listeners.
Web applications are deployed into the web container and are uniquely identified by the specific path at which they are rooted in the web container namespace. This path is called the context path of the web application (see Section 2.3, Unified Naming and Dedicated Application Namespaces). All requests for a resource whose URL path component is prefixed with that context path will be routed to that application to be further dispatched to the targeted web resources of that application. Based on the mappings from URL path to web components configured for that application, web components (servlets and filters) are invoked with objects encapsulating the requests received and the responses to be sent. The web container is multithreaded. Web applications must, therefore, account for multithreading and for servicing multiple requests concurrently (see Section 2.7, Multithreading).
On the Java Card Platform, web applications are limited when compared to more regular web platforms, but they may also use many of the facilities provided by the platform, such as persistence (see Section 2.8, Persistence), transactions (see Section 2.9, Transaction Facility), inter-application communication (see Section 2.5, Inter-Application Communication Facilities Overview), and restartable tasks facilities (see Section 2.10, Restartable Tasks).
The Java Card Platform runtime environment specifics for web applications are described in detail in Chapter 3. On the Java Card Platform, web applications include additional descriptors specific to the Java Card Platform beyond the regular web application deployment descriptor. These descriptors, as well as the Java Card Platform-specific subset of the regular web application deployment descriptor, are described in detail in Chapter 8.
The Java Card Platform, Connected Edition MUST support both the classic applet application model and the extended applet application model. This section gives an overview of both applet application models in general, whereas the classic applet application model is described in detail in the Runtime Environment Specification, Java Card Platform, v3.0.1, Classic Edition.
Applet applications interact with off-card applet clients via the APDU command/response paradigm implemented by the applet container. On the Java Card Platform, the applet container MUST support the ISO 7816-4 defined APDU protocol for commands and responses. The applet container’s main responsibilities are to contain and manage applet applications and their components through their lifecycle.
Extended applet applications differ from classic applet applications in the following respects:
Classic applet applications have the following characteristics:
An applet application is typically composed of:
Applet applications are deployed into the applet container and are uniquely identified on the card, by the URI paths corresponding to their applet instance Application Identifiers (AID), which they are rooted in the applet container namespace. These paths define unique namespaces for the applet application on the card (see Section 2.3, Unified Naming and Dedicated Application Namespaces). Applet instances of an applet application are selected for receiving APDU commands over logical communication channels using the ISO 7816-4 defined APDU SELECT command containing the applet instance AID data.
The applet container dispatches APDU commands to classic applications sequentially even when received concurrently over different I/O interfaces.
The applet container is able to dispatch APDU commands received on different I/O interfaces concurrently to extended applet applications. Extended applet applications must, therefore, account for multithreading and for servicing multiple commands concurrently. (See Section 2.7, Multithreading.)
On the Java Card Platform, extended applet applications may also use many of the facilities provided by the platform, such as persistence (see Section 2.8, Persistence), transactions (see Section 2.9, Transaction Facility), inter-application communication (see Section 2.5, Inter-Application Communication Facilities Overview), and restartable tasks facilities (see Section 2.10, Restartable Tasks).
The Java Card Platform runtime environment specifics for applet applications are described in detail in Chapter 4. On the Java Card Platform, applet applications include additional descriptors specific to the Java Card Platform beyond the regular applet application deployment descriptor. These descriptors, as well as the Java Card Platform-specific subset of the regular applet application deployment descriptor, are described in detail in Chapter 8.
The Unified Naming scheme supported by the Java Card Platform, Connected Edition allows for applications of all types and their respective resources to be uniquely named and uniformly addressed on the platform. Each application is assigned a dedicated resource namespace rooted under its own unique name.
All applications MUST be named with a relative URI (or more properly, a relative URI-reference), one that starts with “//”. These URIs are called application URIs.
Every web application MUST be named with a relative URI that uses the null registry-based authority. The path component of a web application URI MUST correspond exactly to its context path. Web application URIs are of the following form:
where <context path> is a web application context path (which MUST always start with a ‘/’ and which MUST not include any path segment parameters), see the “Servlet Context” chapter of the Java Servlet Specification for the Java Card Platform, v3.0.1, Connected Edition.
Every applet application MUST be named with a relative URI that uses the “aid” registry-based authority. The path component of an applet application URI MUST correspond to its hexadecimal encoded AID (Application Identifier). Applet application URIs are of the following form:
where <RID> (resource identifier) and <PIX> (proprietary identifier extension) are the two classical components of applet application AID, see the “Java Card Applet Lifetime” chapter of Runtime Environment Specification for the Java Card Platform, v3.0.1, Classic Edition.
All the bytes of the RID and PIX including any leading 0 byte values MUST be represented in the character string notation. A RID byte string is 5 bytes in length. Its character string equivalent MUST be exactly 10 characters in length. A PIX byte string can be from 0 to 11 bytes in length. A PIX byte string of N bytes in length MUST have an equivalent character string representation of exactly 2*N characters in length.
In order to comply with the requirement for non-overlapping application URI namespaces (defined in Dedicated Application Namespaces), when a <PIX> component of an AID URI is 0 in length, it MUST be replaced by ‘-’. In such a case, the AID URI has the following form:
AID objects which encapsulate applet application AIDs can be transformed into the equivalent application URI String objects and vice versa using the getURI(AID) and getAID(String) methods of the javacardx.framework.JCSystem class.
Two application instances MUST NOT have the same application URI name.
An application instance MUST NOT be named with the reserved ///platform and ///standard URIs or be named relatively to these reserved URIs.
Application URI namespaces MUST NOT overlap. For example, there must not be two web application instances named ///transit and ///transit/pos.
An application URI defines the root of a dedicated namespace within which all its resources are named. All resources of an application MUST be named relatively to that application’s URI.
Any attempt to create or register resources under another application’s namespace MUST result in a security exception.
Creation and registration of resources under the reserved ///platform and ///standard namespaces MUST be subject to resource-type-specific access control.
Access to resources under another application’s namespace MUST be subject to resource-type-specific access control.
TABLE 2-1 shows the URI namespace formats for applications as well as resources on the Java Card Platform.
The Java Card Platform uses URIs for designating:
A Java Card Platform implementation MUST support the URI syntax as defined by RFC 3986: Uniform Resource Identifiers (URI): Generic Syntax with the additional following amendments:
URIs can be absolute or relative. A URI which starts with a scheme (preceding a ‘:’) such as sio, event or file, is an absolute URI. Otherwise it is a relative URI or, more properly, a relative URI reference.
In order to properly interpret or compare URIs, the Java Card Platform MUST implement the following requirements:
API and SPI methods MUST accept well-formed URIs (including those identifying applications or the platform) passed by applications but MUST only return or pass to applications such URIs in their canonical forms.
Relative URI references MUST be resolved as per RFC 3986 against a base URI:
<scheme>:<application URI>/
where <scheme> is the scheme, <application URI> is the canonical URI of the current application as determined from the current thread’s active namespace (see Section 2.7.2.2, Per-Thread Active Context and Active Namespace). Note that a ‘/’ is appended to construct the default base URI.
The following are examples of relative URI reference resolutions:
By default, all URIs handled by the Java Card RE, API and SPI MUST be normalized as per RFC 3986’s Syntax-Based Normalization which includes:
In addition, URIs MUST be further normalized as follows:
These normalization rules MUST also apply to the root path of an application resource URI which identifies the application.
For example, event:///transit/pos/foo/bar/../../ticketbook/overdraft must be rewritten as event:///transit/pos/ticketbook/overdraft. And HTTP://java.SUN.com:080/products/javacard must be rewritten http://java.sun.com:80/products/javacard. Also, event://aid/platform/clock/resynced must be rewritten event:///platform/clock/resynced.
Scheme-based and protocol-based normalizations MUST only be performed when actually locating and controlling access to network resources designated by the URI. In addition to syntax-based normalization, network URIs MUST be normalized as per RFC 3986’s Scheme-based Normalization and Protocol-based Normalization which include depending on the schemes:
If an optional protocol is not supported, a Java Card Platform implementation MAY not perform this normalization for that protocol.
Scheme-based and Protocol-based Normalization of URIs MUST only be performed by the methods of the javax.microedition.io.Connector class.
URI patterns are used to designate one or more resources. URI patterns are of the following types:
| Note - The root of the namespace designated by the path prefix URI pattern may or may not be itself included in the set of resources designated, depending on the context. For example, in the context of permissions, the path prefix pattern sio:///transit/pos/* does not include sio:///transit/pos. The path prefix pattern file:///transit/pos/logs/* does not include the directory designated by file:///transit/pos/logs, see Section 6.2.1.2, URI-named Permissions. In the context of servlet mapping the path prefix pattern /transit/pos/* includes the web resource /transit/pos, see the “Mapping Requests to Servlets” chapter of the Java Servlet Specification for the Java Card Platform, v3.0.1, Connected Edition. |
TABLE 2-2 shows the different URI pattern types supported on the Java Card Platform.
This section describes the basic requirements of the firewall-enforced context isolation mechanism originally defined on the Java Card Platform, Classic Edition as applicable to the Java Card Platform, Connected Edition. Section 6.9, Context Isolation Enhancements describes the additional features of the context isolation facility on the Java Card Platform, Connected Edition, v 3.0.1.
Any implementation of the Java Card RE MUST support isolation of contexts and applications. Isolation means that one application cannot access the components, fields and methods of objects of an application in another context unless the other application explicitly provides an interface for access. The Java Card RE mechanisms for context isolation and object sharing are detailed in the following sections.
The basic minimum protection requirements of contexts and firewalls are described in this document because the features are not transparent to the application developer. Developers must be aware of the behavior of objects, APIs, and exceptions related to the firewall.
Java Card RE implementers are free to implement additional security mechanisms beyond those of the application firewall, but these mechanisms MUST be transparent to applications and MUST NOT change the externally visible operation of the VM.
The application firewall within Java Card technology is runtime-enforced protection and is separate from the Java technology protections. The Java programming language protections still apply to Java Card applications. The Java programming language ensures that strong typing and protection attributes are enforced.
Application firewalls are always enforced in the Java Card VM. They allow the VM to automatically perform additional security checks at runtime.
The Java Card technology-based firewall (Java Card firewall) provides protection against the most frequently anticipated security concern: developer mistakes and design oversights that might allow sensitive data to be “leaked” to another application. An application may be able to obtain an object reference from a publicly accessible location. However, if the object is owned by an application protected by its own firewall, the requesting application must satisfy certain access rules before it can use the reference to access the object.
The firewall also provides protection against incorrect code. If incorrect code is loaded onto a card, the firewall still protects objects from being accessed by this code.
Firewalls essentially partition the Java Card platform’s object system into separate protected object spaces called group contexts. These are illustrated in FIGURE 2-1. The firewall is the boundary between one group context and another. The Java Card RE MUST allocate and manage a group context for each application group containing applications[1]. An application group corresponds to a set of application modules (see Section 8.4.1, Application Module Distribution Format) which have a trust relationship among themselves as determined by the application provider and the card manager.
All application instances within a single application group MUST share the same context. There is no firewall between individual application instances within the same application group. That is, an application instance can freely access objects belonging to another application instance that resides in the same application group.
FIGURE 2-1 Contexts Within the Java Card Platform’s Object System
In addition, the Java Card RE MUST maintain its own Java Card RE context. This context is much like the context of an application, but it MUST have special system privileges so that it can perform operations that are denied to contexts of applications. For example, access from the Java Card RE context to any application instance’s context must be allowed, but the converse, access from an application instance’s context to the Java Card RE context, must be prohibited by the firewall.
At any point in time, there may be multiple active contexts within the VM, one per thread. The currently active context of a thread is described in Section 2.7.2.2, Per-Thread Active Context and Active Namespace. This can be either the Java Card RE context or an application’s context. All bytecodes that access objects MUST be checked at runtime against the currently active context in order to determine if the access is allowed. A java.lang.SecurityException MUST be thrown when an access is disallowed.
If access is allowed, the VM determines if a context switch is required. A context switch occurs when certain well-defined conditions, as described in Section 2.4.2.8, Class and Object Access Behavior, are met during the execution of invoke-type bytecodes. For example, a context switch may be caused by an attempt to access a shareable object that belongs to an application instance that resides in a different group context. The result of a context switch is a new currently active context.
During a context switch, the previous context and object owner information MUST be pushed on the VM thread stack, a new context becomes the currently active context for that thread, and the invoked method MUST execute in this new context. Upon exit from that method the VM MUST perform a restoring context switch. The original context (of the caller of the method) is popped from the stack and is restored as the currently active context for that thread. Context switches can be nested. The maximum depth depends on the amount of VM stack space available.
Most method invocations in Java Card technology do not cause a context switch. For example, a context switch is unnecessary when an attempt is made to access an object that belongs to an application instance that resides in the same group context. Context switches only occur during invocation of and return from certain methods, as well as during exception exits from those methods (see Section 2.4.2.8, Class and Object Access Behavior).
Further details of contexts and context switching are provided in later sections of this chapter.
Any given object in the Java Card platform’s object space has a context and an owner associated with it. When a new object is created, it MUST be associated with the currently active context, but the object MUST be owned by the application instance within the currently active context when the object is instantiated. An object can be owned by an application instance, or by the Java Card RE.
Following are the combined rules of context and object ownership within the firewall:
FIGURE 2-2 below illustrates method transitions from method m1 in application instance A to method m2 in application instance B, within the same group context, context 1, which MUST NOT trigger a context switch. The transition from method m2 in application instance B to a method m0 in application instance C MUST trigger a context switch since application C is in a different group context, context 2.
FIGURE 2-2 Context Switching and Object Access
In general, an object MUST only be accessed by its owning context, that is, when the owning group context is the currently active context. The firewall MUST prevent an object from being accessed by another application in a different group context.
In implementation terms, each time an object is accessed, the object’s owner group context is compared to the currently active context. If these do not match, the access is not performed and a SecurityException MUST be thrown.
An object is accessed when one of the following bytecodes is executed using the object’s reference:
getfield, putfield, invokevirtual, invokeinterface, athrow, <T>aload, <T>astore, arraylength, checkcast, instanceof, monitorenter
<T> refers to the various types of array bytecodes, such as iaload and aastore.
This list MUST include any special or optimized forms of these bytecodes implemented in the Java Card VM for performance or other optimization purposes.
Transient objects of CLEAR_ON_RESET type also behave like all other objects in that they MUST be accessed only when the currently active context is the object’s owning context (the currently active context at the time when the object was created).
Transient objects of CLEAR_ON_DESELECT type MUST only be created or accessed by an applet application, when the currently active context is the context of the currently selected applet. If any of the makeTransient factory methods are called to create a CLEAR_ON_DESELECT type transient object, from a web application or when the currently active context is not the group context of the currently selected applet (even if the attempting group context is that of an active applet instance on another logical channel), the method MUST throw a java.lang.SystemException with reason code of ILLEGAL_TRANSIENT. If an attempt is made to access a transient object of CLEAR_ON_DESELECT type from a web application or when the currently active context is not the context of the currently selected applet (even if the attempting context is that of an active applet instance on another logical channel), the Java Card RE MUST throw a java.lang.SecurityException.
Applications that are part of the same application group share the same group context. Every application instance from the application group shares all its object instances with all other instances from the same application group. This includes transient objects of both CLEAR_ON_RESET type and CLEAR_ON_DESELECT type owned by these application instances.
The transient objects of CLEAR_ON_DESELECT type owned by any applet instance in the same application group MUST be accessible when any of the applet instances is the currently selected applet.
Instances of classes (objects) are owned by application instances within group contexts. Classes themselves are not.
Runtime context checks MUST NOT be performed when a class static field is accessed. A context switch MUST NOT occur when a static method or static initializer method (<clinit>) is invoked. Similarly, invokespecial MUST NOT cause a context switch.
Public static fields and public static methods MUST be accessible from any context: Static methods execute in the same context as their caller.
Objects referenced in static fields are just regular objects. They are owned by whomever created them and standard firewall access rules apply. If it is necessary to share them across multiple contexts, these objects need to be shareable interface objects (SIOs), see Section 2.4.2.4, Shareable Interfaces, or transferable across the firewall, see Section 6.9.3.1, Ownership of Objects Created by Transferred Objects.
The conventional Java technology protections are still enforced for static fields and methods. In addition, when applications are loaded, the card management facility verifies that each attempt to link to an external static field or method is permitted by the code isolation and package access control checks, see Section 6.7, Code Isolation and Section 6.8, Package Access Control.
The application firewall confines an applications actions to its designated context. To enable applications to interact with each other and with the Java Card RE, some well-defined yet secure mechanisms are provided so one context can access an object belonging to another context.
These mechanisms are provided in the Java Card API and are discussed in the following sections:
To allow for applications to request system services performed by privileged Java Card RE routines, the Java Card API designates Java Card RE entry point objects. These are objects owned by the Java Card RE context, but they are flagged as containing entry point methods. Access to these classes and objects is controlled by the javacardx.spi.framework.JCREPermission permissions configured for these objects, see Section 6.2.5.2, Context-switch-triggered Security Checks.
The firewall protects the fields and components of these objects from access by applications. The entry point designation allows the methods of these objects to be invoked from any context. When that occurs, a context switch to the Java Card RE context is performed. These methods are the gateways through which applications request privileged Java Card RE system services. The requested service MUST be performed by the entry point method only after verifying that the method parameters are within bounds and all objects passed in as parameters are accessible from the caller’s context.
Following are the two categories of Java Card RE entry point objects:
Like all Java Card RE entry point objects, methods of temporary Java Card RE entry point objects can be invoked from any context. However, references to these objects cannot be stored in class variables, instance variables or array components. The Java Card RE MUST detect and restrict attempts to store references to these objects as part of the firewall functionality to prevent unauthorized reuse. In addition, the Java Card RE MUST allow access to these objects only by threads that are passed these objects as parameters via applet application entry points.
The APDU object is an example of a temporary Java Card RE entry point object.
Like all Java Card RE entry point objects, methods of permanent Java Card RE entry point objects can be invoked from any context. Additionally, references to these objects can be stored and freely re-used.
Java Card RE owned AID instances are examples of permanent Java Card RE entry point objects.
The Java Card RE MUST perform the following tasks:
| Note - Only the methods of these objects are accessible through the firewall. The fields of these objects are still protected by the firewall and can only be accessed by the Java Card RE context. |
The Java Card Platform, Connected Edition, MUST implement Java Card RE-owned instances of the classes listed in TABLE 2-3 and TABLE 2-5 as permanent Java Card RE entry point objects.
Java Card RE-owned instances of the classes listed in TABLE 2-4 are temporary Java Card RE entry point objects.
Java Card RE-owned instances of the classes listed in TABLE 2-5 are permanent Java Card RE entry point objects (EPO).
Java Card RE-owned instances of the classes listed in TABLE 2-6 are permanent Java Card RE entry point objects (EPO).
The set of Permanent Java Card RE EPO classes MAY be extended by standards bodies provided the classes respect the contract of Java Card RE EPO requirements defined above.
| Note - Some of the classes listed in TABLE 2-3, TABLE 2-5 and TABLE 2-6 may be instantiated by an application. Such application-owned instances are not subject to Java Card RE entry point objects access rules. |
Before performing a context switch to the Java Card RE context upon a call to a Java Card RE entry point object, the Java Card RE MUST ensure that the parameters of the call are owned by either the calling application or its group context, are not owned by any context (such as for implicitly transferable objects), or are Java Card RE entry point objects. Otherwise, a security exception MUST be thrown.
Before performing a context switch back to the context of the calling application upon returning from a call to a Java Card RE entry point object, the Java Card RE MUST make the object to be returned (if any) accessible to the calling application by assigning the ownership of the object to the calling application’s context, unless otherwise stated in the Java Card API, that is unless:
Especially, the java.lang.Object.toString method of a Java Card RE entry point object MUST return a java.lang.String instance owned by the calling application, or not owned by any context if the String instance corresponds to an interned String. The java.lang.Object.getClass method of a Java Card RE entry point object MUST return a java.lang.Class instance that is not owned by any context since Class objects are impolitely transferable objects.
The java.lang.Throwable class and subclasses thereof are implicitly transferable classes, see Section 7.2.1, Transferable Classes. Therefore, all errors and exceptions thrown by the Java Card RE are implicitly transferable objects, meaning direct instances of implicitly transferable throwable classes.
Some applet environment array objects require that they be accessible from any context. The firewall would ordinarily prevent these objects from being used in a flexible manner. The Java Card VM allows an array object to be designated as global.
Global arrays have properties similar to those of temporary Java Card RE entry point objects. These objects are owned by the Java Card RE context, but can be accessed from any context. However, references to these objects cannot be stored in class variables, instance variables or array components. The Java Card RE MUST detect and restrict attempts to store references to these objects as part of the firewall functionality to prevent unauthorized reuse. In addition, the Java Card RE MUST allow access to these objects only by threads that are passed these objects as parameters via applet application entry points.
The Java Card Platform, Connected Edition, MUST implement Java Card RE-owned instance(s) of these array objects listed in TABLE 2-7 as global array objects.
|
bArray, the byte array parameter to the Applet.install method |
| Note - Global array objects listed in TABLE 2-7 are instances of byte arrays which may also be instantiated by an application. Such application-owned instances of byte arrays are not subject to global array objects access rules. |
The Java Card RE context has a special privilege. The Java Card RE context can access fields, methods and components of any object on the card including CLEAR_ON_DESELECT transient objects owned by the currently selected application.
The Java Card RE context is the currently active context when the VM begins running after a card reset. The Java Card RE context is the “root” context and is always either the currently active context or the bottom context saved on the stack of every Java Card RE-managed thread.
Shareable interfaces are a feature in the Java Card API to enable application interaction. A shareable interface defines a set of shared interface methods. These interface methods can be invoked from one context even if the object implementing them is owned by an application in another context.
In this specification, an object instance of a class implementing a shareable interface is called a shareable interface object (SIO).
To the owning context, the SIO is a normal object whose fields and methods can be accessed. To any other context, the SIO is an instance of the shareable interface, and only the methods defined in the shareable interface are accessible. All other fields and methods of the SIO MUST be protected by the firewall.
Shareable interfaces provide a secure mechanism for inter-application communication, as described in the following sections.
When an application calls JCSystem.getPreviousContextAID, the Java Card RE MUST return the instance AID of the applet application instance active at the time of the last context switch, if the previous application is an applet application.
When an application calls JCSystem.getPreviousURI, the Java Card RE MUST return the URI of the most recently active application namespace.
If an application calls JCSystem.getPreviousContextAID or JCSystem.getPreviousURI, from the run method of a newly started application-managed thread, the Java Card RE MUST return null.
The Java Card RE context neither has an AID, nor a namespace URI. If an application calls the getPreviousContextAID method when the context of the application was entered directly from the Java Card RE context, this method MUST return null.
If an application calls the getPreviousURI method when the context of the application was entered via an application lifecycle or entry point method from the Java Card RE context, this method MUST return null.
A shareable interface is simply one that extends (either directly or indirectly) the tagging interface javacard.framework.Shareable.
Interfaces extending the Shareable tagging interface have this special property: Calls to the interface methods take place across Java Card platform’s application firewall boundary by means of a context switch.
The Shareable interface serves to identify all shared objects. Any object that needs to be shared through the application firewall MUST directly or indirectly implement this interface. Only those methods specified in a shareable interface are available through the firewall.
Implementation classes can implement any number of shareable interfaces and can extend other shareable implementation classes.
A shareable interface simply defines a set of service methods. A service provider class implements the shareable interface and provides implementations for each of the service methods of the interface. A service client class accesses the services by obtaining an object reference, casting it to the shareable interface type, and invoking the service methods of the interface.
The shareable interfaces within the Java Card technology MUST have the following properties:
Inter-application communication is accomplished when a client application invokes a shareable interface method of an SIO belonging to a server application. The client application discovers and obtains the SIO from the server application using either the classic application mechanisms or the new service and event facilities of the Java Card Platform, Connected Edition.
The server application implements the ServiceFactory interface and registers its SIO service with the ServiceRegistry. The client application is able to lookup services via the ServiceRegistry. Or, the client application implements the EventNotificationListener interface and registers its listener with the EventRegistry to receive notification of SIO-based events fired by the server application. The server application creates an instance of the SIO-based Event class and fires the event through the EventRegistry. These mechanisms are described in Section 7.3, Shareable Interface Object-based Services.
The server classic applet application implements the Applet.getShareableInterfaceObject method. The JCSystem class provides the JCSystem.getAppletShareableInterfaceObject method to enable an client applet application to request SIO objects from the server classic applet application. These mechanisms are described in more detail in the “Applet Isolation and Object Sharing” chapter of the Runtime Environment Specification, Java Card Platform, Classic Edition, v 3.0.1.
A static class field is accessed when one of the following Java programming language bytecodes is executed:
getstatic, putstatic
An object is accessed when one of the following Java programming language bytecodes is executed using the object’s reference:
getfield, putfield, invokevirtual, invokeinterface, athrow, <T>aload, <T>astore, arraylength, checkcast, instanceof, monitorenter
<T> refers to the various types of array bytecodes, such as iaload, aastore, etc.
This list includes any special or optimized forms of these bytecodes implemented in the Java Card VM for performance or other optimization purposes.
Prior to performing the work of the bytecode as specified by the Java VM, the Java Card VM MUST perform an access check on the referenced object. If access is denied, a java.lang.SecurityException MUST be thrown.
The Java Card 3.0.1 Platform defines additional permission-based security checks during context switching to allow for a finer-grained access control during sharing across group contexts, see Section 6.9.1, Context Switches.
The access checks performed by the Java Card VM depend on the type and owner of the referenced object, the bytecode, and the currently active context. They are described in the following sections.
getstatic, putstatic
<T>aload, <T>astore, arraylength, checkcast, instanceof
getfield, putfield
invokevirtual
invokeinterface
invokeinterface
athrow
checkcast, instanceof
checkcast, instanceof
checkcast, instanceof
| Note - The method access behavior of global arrays is identical to that of Java Card RE entry point objects. |
invokevirtual
The Java Card Virtual Machine MUST restrict access to the monitors for objects owned by applications in other contexts.
monitorenter
On the Java Card Platform, Connected Edition, an application can communicate with another application using the following two inter-application communication facilities:
This facility also ensures a seamless integration of classic Java Card runtime environment SIO registration and lookup.
To use this facility, component developers are required to implement SIO-based services and their associated factories.
See Section 7.3, Shareable Interface Object-based Services for details on inter-application communication facility.
This facility cannot be used directly by classic applet applications.
To use this facility, component developers are required to implement SIO-based events and event listeners.
See Section 7.4, Events for details on the event notification facility.
The server connection endpoint over which HTTP requests and HTTP responses are received and sent, respectively, by the web container on behalf of applications it manages is called a container-managed endpoint. Similarly, the endpoint over which APDU commands and APDU responses are received and sent, respectively, by the applet application container on behalf of applications it manages is also called a container-managed endpoint. When an HTTP request or an APDU command is received over one of these container-managed endpoints, the targeted application is determined and the request or command is dispatched to that application for processing. This constitutes the primary mode of activation of an application on the Java Card Platform.
Developers may create applications that are not primarily activated through a container-managed endpoint. These applications may, for example, provide services to other on-card applications or provide network services to off-card applications, such as through an application-managed server endpoint. These applications typically are automatically started or restarted upon a platform reset and must execute in their own application-managed threads, see Section 2.7, Multithreading.
An application developer may create such an application by registering a restartable task (see Section 2.10, Restartable Tasks), which will be automatically invoked or started, respectively, upon a platform reset.
To setup an application for automatic start, a web application developer may use the contextInitialized method of a javax.servlet.ServletContextListener object to register the task when the web application is instantiated, see Section 3.2.3, Application Instance Creation. An extended applet application developer may similarly use the constructor or the install method of an applet for the same purpose, see Section 4.2.3, Application Instance Creation.
The Java Card virtual machine supports multithreading and concurrent execution of applications, see Java Card Virtual Machine Specification, Java Card Platform, v3.0.1, Connected Edition. The Java Card API includes a Java SE subset of the java.lang.Thread API, which allows for an application to create and handle threads of control.
The Java Card Runtime Environment (RE) MUST provide the following multithreaded application programming environments:
While the classic applet application programming environment does not support multithreading, it MUST still operate concurrently with the other two application environments.
The web application container, the extended applet application container and other facilities of the Java Card RE MAY use multiple threads, referred to in this specification as Java Card RE-managed threads, to invoke the entry point methods of applications to:
Web applications and extended applet applications must be thread-aware and must account for such concurrent processing. See Chapter 3 and Chapter 4 for more details.
Classic applet applications are not thread-aware; the classic applet application environment MUST, therefore, guarantee the thread-safety of classic applet applications.
Additionally, web applications and extended applet applications may themselves spawn new threads, referred to in this specification as application-managed threads.
The above-mentioned Java Card RE-managed and application-managed threads are the only threads to which application developers may be exposed. All these threads may be handled using the java.lang.Thread API. Some restrictions MUST apply when handling a thread based on:
Some Java Card Platform implementations MAY rely internally on various additional threads. The management of these threads is implementation-dependent.
The Java Card Runtime Environment MAY create a new thread of control or MAY reuse an already created thread of control to invoke an application’s entry point method, a lifecycle method, an event notification method or a task execution method.
In resource-constrained configurations and for performance reasons, a Java Card Platform implementation MAY limit the number of concurrent Java Card RE-managed threads. This may limit the number of HTTP requests and APDU commands the platform may handle concurrently. A Java Card Platform implementation MAY also rely on a pool of reusable threads. An application must, therefore, not rely on different Thread objects being used for each subsequent entry point method invocation.
Web applications and extended applet applications may create new threads. A Java Card Platform implementation MAY restrict the creation of application-managed threads to ensure that other components of the platform are not negatively impacted. An application must, therefore, account for such restrictions and must handle situations where the creation of a new thread results in a security exception being thrown.
To create a new thread of control, an application must instantiate a Thread object, optionally set its initial priority, and run it by invoking its start method.
As per the context isolation principle, when a Thread object is instantiated, it MUST be assigned an owner context, see Section 2.7.4, Thread Ownership.
The creation of threads by applications MUST be subject to access control. When a Thread’s constructor is invoked, a security check MUST ensure that the permission javacardx.framework.JCRuntimePermission with the target name thread.create is granted.
An application may alter the scheduling of a thread’s execution it owns by doing one of the following:
Thread priority changes by applications MUST be subject to access control. When the Thread.setPriority method is invoked, a security check MUST ensure that the permission javacardx.framework.JCRuntimePermission with the target name thread.modify is granted. See Section 2.7.4, Thread Ownership for details on other restrictions that apply.
The Thread.sleep(long millis) method MUST put the currently executing thread to sleep for at least the specified number of milliseconds. There is no guarantee the thread will wake up in exactly the specified time. Other thread scheduling can interfere, as can the granularity and accuracy of the system clock, among other factors. If the thread is interrupted while it is sleeping, then an InterruptedException MUST be thrown.
A Java Card platform implementation with a coarse system clock granularity and limited system clock accuracy MAY take a conservative approach to guarantee that a call to the sleep method does not return before the specified number of milliseconds, unless interrupted, such as by using an upper-bound conservative estimate.
After a platform reset, a thread that was sleeping at the time of the card tear or power off is terminated as any other thread. See Section 2.7.3, Thread Interruption and Termination for more details.
All objects MUST be associated with an owner context, which corresponds to a group context, as well as an application owner identifier (application URI or AID). Refer to Section 2.4, Context Isolation Basics for more details on context isolation and context switching.
For each thread of control, distinct active context and active namespace references MUST be maintained:
As a method of an object is executed the currently active context is set to the owner context of that object. The currently active context does not change when a static method or a method of a context-less object is executed, see Section 7.2, Object Ownership Transfer Mechanism.
Each object created by a thread MUST be bound to the thread’s currently active context.
| Note - A thread’s currently active context is distinct from the owner context of the Thread object itself. |
The active context and namespace references of a newly started thread (as per a call to the Thread.start method) MUST be set to the currently active context and namespace of its parent thread.
The legacy API’s javacard.framework.JCSystem.getAID method is applicable to applet applications (both classic and extended) to obtain the AID (application identifier) of the owner of the calling object. This method MUST return null if the owner application identifier cannot be expressed as an AID object, that is if the application is a web application.
A call to the javacardx.framework.JCSystem.getURI method MUST return the currently active namespace, meaning the application URI, associated with the current thread.
A call to the javacardx.framework.JCSystem.getPreviousURI method MUST return the previously active namespace, meaning the application URI, that was associated with the current thread before it entered the current group context. This method MUST ignore any interposed Java Card RE context.
A call to the javacardx.framework.JCSystem.getClientURI method MUST return the namespace, meaning application URI, of the client of a shareable interface object invoked through one of its shareable interface methods. The client of a shareable object is defined as follows:
A call to the javacardx.framework.JCSystem.getServerURI(Shareable) method MUST return the namespace, meaning application URI, that will get associated with the current thread if that thread enters another group context of the shareable interface object passed as the argument.
Each application’s group context is bound to a set of permissions--a protection domain--which determines the protected functions an application is permitted to access (Section 6.1, Security Policy). At any time during its execution, a thread keeps track of the currently active context. The set of permissions that must be enforced during a particular method’s invocation MUST be the set of permissions associated with the active context of the currently executing thread:
A thread may terminate in one of the two following ways:
A Java Card RE-managed thread MAY not terminate when returning from the application’s entry point method it is executing. A Java Card Platform implementation MAY rely on a pool of reusable Java Card RE-managed threads. Such threads will typically not terminate when returning from the application’s entry point method it is executing.
Application-managed threads can be interrupted by calling the thread’s interrupt method. Interruption of threads by applications MUST be subject to access control. When the Thread.interrupt method is invoked, a security check MUST ensure that the permission javacardx.framework.JCRuntimePermission with the target name thread.modify is granted. See Section 2.7.4, Thread Ownership for details other restrictions that apply.
After a card reset, both Java Card RE and application threads are terminated. Persistent Thread objects, meaning Thread objects reachable from a root of persistence as per the persistence by reachability model, MUST be in the “terminated” state and their associated thread of control MUST NOT be restarted.
As per the context isolation principle (see Section 2.4, Context Isolation Basics), when a Thread object is instantiated, it MUST be assigned an owner context, according to the following rules:
This imposes certain restrictions on what an application can do on a thread, depending on whether it is the owner of the thread or if the thread is owned by the Java Card RE or another application in a different group context.
In all cases, the current application MUST be allowed to invoke the static methods of the Thread class and MUST, therefore, be allowed to perform any of the following operations:
If the thread is owned by the Java Card RE or another application in a different group context, the current application MUST NOT be allowed to invoke any of the thread’s instance methods and, therefore, MUST NOT be allowed to perform any of the following operations:
As per the context isolation principle (see Section 2.3, Unified Naming and Dedicated Application Namespaces), any attempt to call a Thread instance method on any thread not owned by the current group context MUST result in a security exception being thrown. This especially applies to the HTTP request, APDU command and event notification threads, which are always owned by the Java Card RE and which an application may retrieve by calling the Thread.currentThread method.
These restrictions MUST apply in addition to the permission-enforced access control restrictions applicable to the currently executing thread. These restrictions must be taken into account by all applications regardless of what the initial entry point method invoked was, whether it was a lifecycle method, a shareable interface method, an event notification method or an application task run method.
These restrictions must be taken into account by extension libraries, which cannot easily discriminate between threads that are owned by the calling application and those that are not, by properly handling the security exceptions that may be thrown.
The firewall MUST NOT prevent any application from storing a reference to a thread, whether it is one of the threads it created, a Java Card RE-owned thread, or another application's thread. However, an application may only actively manage threads it owns.
The following Java Card API classes and methods are required to be thread-safe:
| Note - Temporary Java Card RE entry point objects (see Section 2.4.2.1, Java Card RE Entry Point Objects) are not required to be thread-safe because they MUST only be used within a single thread at a time. References to such objects cannot be passed to other threads because the firewall prevents storing references to such objects in any field variable or array component. See Section 4.3.4.1, Thread Safety. |
Code and data persistence across card tear (or reset) and power up is key to the special nature of smart card devices and the Java Card platform. The Java Card Virtual Machine and application code persist across card tear (or reset) and card power up. Objects may be made persistent as well, if they are reachable from the roots of persistence.
The term volatile memory is used to indicate that the memory is not expected to retain its contents between card tear and power up events or across a reset event on the smart card device. For the purposes of the Runtime Environment Specification, Java Card Platform, v3.0.1, Connected Edition, it is assumed that volatile memory can be read and written to directly without any special setup. The most common type of volatile memory is DRAM.
The term non-volatile memory is used to indicate that the memory is expected to retain its contents between card tear and power up events or across a reset event on the smart card device. For the purposes of the Runtime Environment Specification, Java Card Platform, v3.0.1, Connected Edition, it is assumed that non-volatile memory is usually accessed in read mode, and that special setup may be required to write to it. Examples of non-volatile memory include ROM, EEPROM and Flash memory. The Runtime Environment Specification, Java Card Platform, v3.0.1, Connected Edition does not define which memory technology a device must have, nor does it define the behavior of such memory in a power-loss scenario.
A volatile object is an object that is ideally suited to be stored in volatile memory. This type of object is intended for a short-lived object or an object which requires frequent updates. A volatile object MUST be garbage collected on card tear (or reset). A Java Card conformant implementation SHOULD store the object in volatile memory but need not guarantee it due to the limited availability of volatile memory store in smart card devices. The volatile object may, therefore, be physically stored in volatile memory or non-volatile memory or some combination of the two types of memory store.
A persistent object is an object that MUST be stored in non-volatile store. This type of object is intended to be a long-lived object. A persistent object MUST retain its contents between card tear and power up events or across a reset event.
All objects, volatile objects and persistent objects, are garbage collected when no longer referenced from other objects. Garbage collection on volatile objects is typically initiated automatically as needed. Garbage collection on all objects - especially persistent objects -MAY be initiated on demand via the java.lang.System.gc(), java.lang.Runtime.gc() or javacard.framework.JCSystem.requestObjectDeletion() methods.
Every object created by executing the new, newarray, anewarray or multianewarray bytecode MUST be a volatile object. The newly created object continues to be a volatile object as long as it is referenced only from other volatile objects or the stack or by reachability disrupting objects (described in Section 2.8.2.1, Reachability Disrupting Objects). If a volatile object is referenced by a persistent object, which is not a reachability disrupting object, or by a root of persistence such as a static reference field, the volatile object MUST be promoted and becomes a persistent object. If the newly promoted persistent object is not a reachability disrupting object, it MUST promote all the volatile objects it references to become persistent objects. Each of these newly promoted persistent objects, which is not a reachability disrupting object, MUST in turn, recursively, promote the volatile objects it references.
Thus, an object is maintained as a volatile object or persistent object according to its reachability[3] from another object that acts as its root of persistence. The root of persistence for an application depends on the application model it implements.
The reachability graph is disrupted by some special objects. If a volatile object is referenced by these special objects, promotion to a persistent object MUST NOT be triggered. These special objects are:
These special objects may themselves be volatile objects or persistent objects but have the same disrupting effect on the reachability graph. These reachability disrupting objects are, therefore, used by an application to prevent the promotion of volatile objects that are short lived or require frequent updates.
| Note - Being referenced by a reachability disrupting object does not prevent a volatile object from being promoted to become a persistent object via other promotion triggering references. |
All static fields are stored in non-volatile store and act as roots of persistence.
In addition, each of the application models supported by the Java Card 3 platform Connected Edition has its own model-specific roots of persistence:
Each application model is associated with its own application container. The application container is anchored by a Java Card RE owned persistent object. The application container MUST manage the persistence of the instantiated applications and their roots of persistence. The application container MUST manage the persistence of all container-managed objects by depending on the persistence by reachability principle. The persistence requirement of a container-managed object is based on the characteristics of the object itself, including its life span, frequency of updates, reuse requirements and security.
If a container-managed volatile object is promoted inadvertently or maliciously to become a persistent object by the application, the container MAY create a new volatile object to replace the promoted persistent object, provided the lifetime characteristics of the object are not violated.
A container-managed volatile object MAY be reused by the application container over several request handling cycles and sessions, provided the object is reused only by application(s) within the same group context.
All application-managed objects that need to be persistent must be referenced directly or indirectly by the roots of persistence of their application model.
The Transaction Facility enables an application to complete a single logical operation on application data atomically, consistently and durably within a transaction. The transaction facility provides atomicity, which ensures that updates to data either all occur, or none occur. Consistency allows the application to establish a consistent state before the start and after the end of the transaction. The transaction facility provides durability, which ensures that when the transaction is successfully completed, the updates are committed.
The Java Card Platform, Connected Edition supports a Transaction Facility that extends the “Transactions and Atomicity” subsystem described in Chapter 7 of Runtime Environment Specification, Java Card Platform, v3.0.1, Classic Edition. The Transaction facility associates each transaction with a commit buffer. The commit buffer records all the updates that have not yet been committed. The commit buffer is used to rollback updates when the transaction does not complete successfully.
The Transaction Facility on the Java Card Platform, Connected Edition provides the following feature extensions:
Atomicity ensures that either all the updates to application state are completed or none are. It avoids the possibility of partially updated states.
The Java Card platform guarantees that any update to a single static class field or a single field of a persistent object, or a single component of an array will be atomic. That is, if the smart card loses power during the update of a data element that MUST be preserved across card tear and power up, that data element MUST be restored to its previous value.
Some methods also guarantee atomicity for block updates of multiple data elements. For example, the atomicity of the javacard.framework.Util.arrayCopy method guarantees that either all bytes are correctly copied or else the destination array is restored to its previous byte values.
Applications might not require atomicity for array updates. The javacard.framework.Util.arrayCopyNonAtomic method and other similar methods are provided for this purpose. These methods do not use the transaction commit buffer even when called with a transaction in progress.
An application might need to atomically update several different fields or array components in several different objects. The Java Card platform provides a transaction facility to ensure that either all updates take place correctly and consistently, or else all fields or components are restored to their previous values. Fields and array components of both volatile and persistent objects are protected by the transaction facility.
A transaction is defined with an explicit starting point and ending point during which updates are collectively performed atomically. During the period of the transaction, between start and end (or start and abort), all updates to fields of objects and components of arrays (except for the components of transient arrays, global arrays and the fields of TransientReference objects) are tracked in a commit buffer. The updates are conditional and only committed when the end of the transaction is reached. However, accessing an updated field or component even before being committed, returns the updated state[4]. If the transaction is aborted before the end of the transaction is reached, all the updated data are reverted back to their state at the start of the transaction, using the data in the commit buffers.
Note that when a transaction is in progress, updates to all fields, including fields and components of volatile objects, fields and components of persistent objects and static fields, are tracked in a commit buffer. Aborting a transaction reverts both type of objects to their states at the start of the transaction.
Runtime Environment Specification, Java Card Platform, v3.0.1, Connected Edition uses annotations metadata to mark an entire method for a transaction demarcation. A method annotated with a TransactionType annotation declares an explicit transaction behavior upon entry into the method which is applicable until normal return from the method. If the method throws an uncaught exception, the transaction is aborted.
The TransactionType annotation is defined in the package javacardx.framework. The value of the TransactionType annotation is given by the enum TransactionTypeValue. The possible enum values are:
The TransactionType annotation may be specified on a class as well as on a method, but not on a constructor (See Section 2.9.2.7, Constructors and Static Initializers). A class level annotation sets the default for all methods on the class. A method level annotation overrides the default. If a class does not specify the TransactionType annotation, it is assumed to be SUPPORTS.
The TransactionType annotation, when specified on an interface or an interface method, has just an informative purpose and simply describes the transactional behavior that is expected of classes which implement the interface. The platform MUST only enforce the TransactionType annotation (or default) specified by the classes which implement the interface.
The TransactionType annotation allows the application programmer to specify the six different transaction behaviors on a method, MANDATORY, REQUIRED, REQUIRES_NEW, SUPPORTS, NOT_SUPPORTED and NEVER using their corresponding enum values.
The following code shows annotation usage for transaction tagging. The TicketBookSIO class does not explicitly use the TransactionType annotation and is by default assigned the SUPPORTS TransactionType annotation. The setBalance() method overrides the default transaction tag with a REQUIRED transaction tag. The getBalance() method retains the default SUPPORTS transaction tag.
New threads MUST NOT be associated with any transaction initially. A new transaction may be created based on the annotation of the run() method of the Runnable instance from which a thread is starting execution.
Java Card RE managed threads MUST NOT invoke application entry point methods, such as container-managed lifecycle methods or service entry point methods with a transaction in progress. A new transaction may be created based on the annotation of the entry point methods.
| Note - The Applet.install() method is an exception to this rule. The Applet.install() method MUST be invoked with a transaction in progress. |
Each TransactionType annotation value and its associated behavior is described in detail in the following sections.
When a method is annotated with the REQUIRES_NEW TransactionType annotation, a new commit buffer, separate and distinct from any commit buffers previously in use, is created to track updates made by the application until either the transaction ends or is aborted. Upon normal exit from the method, the updates are committed and the caller's transaction mode is resumed. An exception exit results in the transaction being aborted.
When a method is annotated with the REQUIRED TransactionType annotation, the commit buffer in use, if any, by the caller is used to continue logging updates during this method also. Upon normal exit from this method, the commit buffer logging resumes in the callers’ method. An exception exit simply results in a control transfer back into the caller's transaction.
If the caller is not within a transaction, or if this method is being started in a new thread, a new commit buffer is created. Upon normal exit from the method, the updates are committed and the caller's transaction mode is resumed. An exception exit results in the transaction being aborted.
When a method is annotated with the SUPPORTS TransactionType annotation, the commit buffer in use, if any, by the caller is used to log updates in this method also. If the caller is not within a transaction, or if this method is being started in a new thread, no commit buffer is created and updates are not tracked. Upon normal exit from the method, the commit buffer logging resumes in the caller’s method. An exception exit simply results in a control transfer back into the caller's transaction.
| Note - SUPPORTS TransactionType annotation MUST be the default transaction behavior. |
| Note - All classes of a classic applet application MUST be tagged with SUPPORTS TransactionType annotation[5] to ensure backward compatibility with the Java Card v2.2.2 platform. |
Upon entry into a method which is annotated with the NOT_SUPPORTED TransactionType annotation, any ongoing transaction is suspended until exit from the method. Upon normal exit from the method, the caller's transaction mode is resumed. An exception exit simply results in a control transfer back into the caller's transaction.
If a method annotated with the MANDATORY TransactionType annotation is called when no transaction is in progress, The Java Card RE MUST throw a TransactionException with exception reason “Transaction Required”. Otherwise, the behavior is exactly the same as a method tagged with the “REQUIRED” TransactionType annotation.
If a method annotated with the NEVER TransactionType annotation is called when a transaction is in progress, The Java Card RE MUST throw a TransactionException with exception reason “Transaction Disallowed”. Otherwise, the behavior is exactly the same as a method tagged with the NOT_SUPPORTED TransactionType annotation.
TABLE 2-8 below describes the possible transitions managed by the transaction facility upon entry into a method and exit from a method based on the transaction state of the calling method. The cells shown with a shaded background (and double asterisks **) have transactions in progress where conditional updates are tracked in the commit buffer.
Constructors and Static Initializers do not support the TransactionType annotation. Constructors and Static Initializers MUST always execute with the NOT_SUPPORTED TransactionType behavior.
The Java Card RE MUST support the transaction behavior described in Chapter 7 of Runtime Environment Specification, Java Card Platform, v3.0.1, Classic Edition for classic applet applications.
Classic applet application code MUST run single-threaded, use exactly one commit buffer and encounter a maximum transaction depth of 1. They use the beginTransaction(), commitTransaction() and abortTransaction() APIs to control the demarcation of the transaction.
An extended applet application or a web application thread may enter classic applet application code via a shareable interface object method. All classic applet application methods MUST be tagged with the SUPPORTS TransactionType annotation. Hence, upon entry, if a transaction in progress, the transaction facility MUST continue using the caller’s commit buffer. If the beginTransaction() method is now called, a TransactionException exception with reason code TransactionException.ILLEGAL_USE MUST be thrown; if commitTransaction() or abortTransaction() method is called, a TransactionException exception with reason code TransactionException.NOT_IN_PROGRESS MUST be thrown. If a classic applet application is entered with no transaction in progress, the beginTransaction(), commitTransaction() and abortTransaction() methods MUST behave as normal.
A classic applet application thread may enter an extended applet application or a web application code via a shareable interface object method. A transaction may be in progress, at the point of entry into the SIO method. In such a case, the transaction facility MUST enforce the transitions described previously based on TransactionType annotations of the methods upon entry and exit.
The beginTransaction(), commitTransaction(), abortTransaction(), getTransactionDepth, getUnusedCommitCapacity() and getMaxCommitCapacity() APIs throw exceptions when accessed from extended applet applications and web applications.
When the same data element - object field, array component, or static field - is updated from two different transactions on concurrently executing threads - the resulting state of that element will either be the original state or a state written by one or the other of the threads, depending on the order in which the threads execute and whether the transactions are committed or aborted. The developer is strongly encouraged to avoid such a programming pattern.
When updated from multiple transactions on the same thread (assuming no updates from other threads), the same data element - object field, array component, or static field - may also result in an unexpected state. When the same data element is updated in multiple transactions, each nested within another, the platform MUST ensure the following outcomes:
Array components of transient array objects and global array objects are not conditionally updated during a transaction. Updates to components of transient array objects and global array objects MUST be committed immediately.
The private reference field of a TransientReference object is not conditionally updated during a transaction. An update to the private reference field of a TransientReference object MUST be committed immediately.
When a card tear or power loss occurs and the card is subsequently powered-up, all ongoing transactions MUST be aborted. All the commit buffers MUST be examined in the reverse order in which they were created, and all updates recorded in each of the commit buffers MUST be examined in the chronologically reverse order of updates to restore the corresponding object field, class field or array component.
When an exception is thrown by a transacted method with REQUIRES_NEW TransactionType annotation, the transaction MUST be aborted.
When an exception is thrown by a method with REQUIRED TransactionType annotation and for which a new transaction was started upon entry, that transaction MUST be aborted.
When the abortTransaction() API is called by a classic applet application, the transaction MUST be aborted.
Transaction abortion requires that the commit buffer be traversed to rollback all updates performed since the start of the method. This MUST be attempted only after the finally clause has executed.
Updates tracked in the commit buffer MUST be reversed starting with the chronologically last update and ending with the first on each recorded field or array component.
If a new object is created within a transaction, and the transaction is subsequently aborted, the newly created object may now be obsolete. But, since references to the object may be stored outside the aborted transaction, the object must be garbage collected only when no references to it remain.
The Restartable Task facility provided by the Java Card Platform, Connected Edition allows for web applications and extended applet applications to register recurrent tasks that get executed in separate application threads and are automatically restarted after each platform reset.
Only web applications and extended applet applications can register tasks for recurrent execution. Classic applet applications cannot use this facility.
The javacardx.facilities.TaskRegistry class allows for applications to dynamically register and unregister recurrent tasks.
The TaskRegistry instance MUST be a singleton. It MUST be a permanent Java Card runtime environment entry point object (see Section 2.4.2.1, Java Card RE Entry Point Objects). It is retrieved by calling the TaskRegistry.getTaskRegistry method.
Task objects MUST implement the java.lang.Runnable interface.
To create a recurrent task, an application must register a task object with the registry. The application must call the TaskRegistry.register method and provide a task object. The application may additionally specify if the task is to be executed immediately or upon the next platform reset.
Attempts by an application which previously registered a task to register the same task again MUST have no effect other than the currently executing task’s thread, if any, to be interrupted if the task is only to be started after the next platform reset.
Attempting to register a task that is already registered by another application MUST result in a security exception being thrown.
Registration of tasks MUST be subject to access control. When the TaskRegistry.register method is invoked, a security check MUST ensure that the permission javacardx.facilities.TaskRegistryPermission with the target name task.register is granted.
| Note - An application may register a task even though it is not granted the permission to create and start a new thread, see Section 2.7.1, Thread Creation. |
Applications may register tasks anytime during their lifetime.
Each registered task MUST be executed in its own separate thread.
Each registered task MUST be automatically restarted in a new thread when the platform is reset.
Tasks MUST be restarted after the application containers have been restarted but before any request or command gets dispatched to applications.
Tasks MUST be started only once during a card session. If a task finishes normally or abnormally it MUST NOT be restarted until the next platform reset.
All restartable task registry threads MUST be owned by the Java Card RE. See Section 2.7.4, Thread Ownership for more details on the restrictions that apply to Java Card RE-owned threads.
An application may unregister a task it previously registered at any time. To unregister a task, an application must provide the same task object that was registered.
The application must call the TaskRegistry.unregister method and provide a task object. The application may additionally specify if the task’s thread is to be interrupted first.
Attempting to unregister a task registered by another application MUST result in a security exception being thrown.
Unregistration of tasks MUST be subject to access control. When the TaskRegistry.unregister method is invoked, a security check MUST ensure that the permission javacardx.facilities.TaskRegistryPermission with the target name task.unregister is granted.
Applications may unregister tasks anytime during their lifetime. Attempting to unregister a task that is not - or no longer - registered has no effect.
A task MUST remain registered until it is removed from the registry by the application that registered it or when that application is deleted. See Section 8.9, Deletion of Application Instance for more details on application instance deletion.
The registry MUST ensure that task objects are persistent across card sessions. Therefore, applications do not have to hold on to references to these objects to ensure their persistence.
The TaskRegistry implementation MUST be thread safe to account for concurrent registrations and unregistrations.
Tasks concurrently run in their own separate threads. Therefore, developers must explicitly deal with synchronization when tasks are accessing shared resources.
Each thread is associated to a current active context and namespace. When entering the run method of a task, the thread’s current active context and namespace MUST be changed to the owner context of the task. See Section 2.7.2.2, Per-Thread Active Context and Active Namespace.
The TaskRegistry singleton instance is a permanent Java Card RE entry point object and therefore MUST NOT participate in any application transaction. The TaskRegistry class MUST be annotated with the NOT_SUPPORTED TransactionType annotation, see Section 2.9.2, Transaction Demarcation. All registration operations MUST nevertheless be atomic and MUST ensure that the task registry is at all times consistent.
Copyright © 2009 Sun Microsystems, Inc. All rights reserved.