C H A P T E R  2

A Subset of the Java Virtual Machine

This chapter describes the subset of the Java virtual machine and language that is supported in the Java Card platform, Version 2.2.2.


2.1 Why a Subset is Needed

It would be ideal if programs for smart cards could be written using all of the Java programming language, but a full implementation of the Java virtual machine is far too large to fit on even the most advanced resource-constrained devices available today.

A typical resource-constrained device has on the order of 1.2K of RAM, 16K of non-volatile memory (EEPROM or flash) and 32K-48K of ROM. The code for implementing string manipulation, single and double-precision floating point arithmetic, and thread management would be larger than the ROM space on such a device. Even if it could be made to fit, there would be no space left over for class libraries or application code. RAM resources are also very limited. The only workable option is to implement Java Card technology as a subset of the Java platform.


2.2 Java Card Platform Language Subset

Applets written for the Java Card platform are written in the Java programming language. They are compiled using Java compilers. Java Card technology uses a subset of the Java language, and familiarity with the Java platform is required to understand the Java Card platform.

The items discussed in this section are not described to the level of a language specification. For complete documentation on the Java programming language, see The Java Language Specification.

2.2.1 Unsupported Items

The items listed in this section are elements of the Java programming language and platform that are not supported by the Java Card platform.

2.2.1.1 Unsupported Features

Dynamic Class Loading

Dynamic class loading is not supported in the Java Card platform. An implementation of the Java Card platform is not able to load classes dynamically. Classes are either masked into the card during manufacturing or downloaded through an installation process after the card has been issued. Programs executing on the card may only refer to classes that already exist on the card, since there is no way to download classes during the normal execution of application code.

Security Manager

Security management in the Java Card platform differs significantly from that of the Java platform. In the Java platform, there is a Security Manager class (java.lang.SecurityManager) responsible for implementing security features. In the Java Card platform, language security policies are implemented by the virtual machine. There is no Security Manager class that makes policy decisions on whether to allow operations.

Finalization

Finalization is also not supported. finalize() will not be called automatically by the Java Card virtual machine.

Threads

The Java Card virtual machine does not support multiple threads of control. Programs for the Java Card platform ("Java Card programs") cannot use class Thread or any of the thread-related keywords in the Java programming language.

Cloning

The Java Card platform does not support cloning of objects. Java Card API class Object does not implement a clone method, and there is no Cloneable interface provided.

Access Control in Java Packages

The Java Card platform language subset supports the package access control defined in the Java language. However, the cases that are not supported are as follows.

Typesafe Enums

The Java Card platform language subset does not support the enumerated type facility and the keyword enum.

Enhanced for Loop

The Java Card platform language subset does not support the enhanced for loop language construct. Support for the enhanced for loop construct requires support for array indexing using the integer data type. The Java Card platform only supports array indexing using the short data type.

Varargs

The Java Card platform language subset does not support variable-length argument lists. The variable-length argument construct requires the compiler to generate code that creates a new array object each time a variable-length argument array method is invoked, thereby causing implicit memory allocations in Java Card runtime memory heap.

Runtime Visible Metadata (Annotations)

The Java Card platform does not support this language feature which lets you introduce meta-data information into the runtime environment to be accessed reflectively. The Java Card platform does not support reflection.

Assertions

The Java Card runtime does not provide runtime support for statements in the Java programming language called assertions that are used to test assumptions about program functionality.

2.2.1.2 Keywords

The following keywords indicate unsupported options related to native methods, threads, floating point, memory management, and debugging.


TABLE 2-1 Unsupported Keywords

native

synchronized

transient

volatile

strictfp

enum

assert

 


2.2.1.3 Unsupported Types

The Java Card platform does not support types char, double, float and long. It also does not support arrays of more than one dimension.

2.2.1.4 Classes

In general, none of the Java programming language core API classes are supported in the Java Card platform. Some classes from the java.lang package are supported (see Section 2.2.2.4, Classes), but none of the rest are. For example, classes that are not supported are String, Thread (and all thread-related classes), wrapper classes such as Boolean and Integer, and class Class.

System

Class java.lang.System is not supported. Java Card technology supplies a class javacard.framework.JCSystem, which provides an interface to system behavior.

2.2.2 Supported Items

If a language feature is not explicitly described as unsupported, it is part of the supported subset. Notable supported features are described in this section.

2.2.2.1 Features

Packages

Software written for the Java Card platform follows the standard rules for the Java platform packages. Java Card API classes are written as Java source files, which include package designations. Package mechanisms are used to identify and control access to classes, static fields and static methods. Except as noted in "Access Control in Java Packages" (Section 2.2.1.1, Unsupported Features), packages in the Java Card platform are used exactly the way they are in the Java platform.

Dynamic Object Creation

The Java Card platform programs supports dynamically created objects, both class instances and arrays. This is done, as usual, by using the new operator. Objects are allocated out of the heap.

A Java Card virtual machine will not necessarily garbage collect objects. Any object allocated by a virtual machine may continue to exist and consume resources even after it becomes unreachable. See Section 2.2.3.2, Object Deletion Mechanism for more information regarding support for an optional object deletion mechanism.

Virtual Methods

Since Java Card technology-based objects ("Java Card objects") are Java programming language objects, invoking virtual methods on objects in a program written for the Java Card platform is exactly the same as in a program written for the Java platform. Inheritance is supported, including the use of the super keyword.

Interfaces

Java Card API classes may define or implement interfaces as in the Java programming language. Invoking methods on interface types works as expected. Type checking and the instanceof operator also work correctly with interfaces.

Exceptions

Java Card programs may define, throw and catch exceptions, as in Java programs. Class Throwable and its relevant subclasses are supported. Some Exception and Error subclasses are omitted, since those exceptions cannot occur in the Java Card platform. See Section 2.3.3, Exceptions for specification of errors and exceptions.

Generics

This Java language facility allows a type or method to operate on objects of various types while providing compile-time type safety. It adds compile-time type safety and eliminates the need for casting.

Static Import

This Java language facility lets you avoid importing an entire class simply to access its static members or qualifying static members with class names each time it is used.

Runtime Invisible Metadata (Annotations)

This language feature lets you avoid writing boilerplate code under many circumstances by enabling tools to generate it from annotations in the source code. The Java Card platform language subset supports the use of annotations which are not visible at runtime. These annotations do not themselves use the runtime visible meta-data annotation @Retention(RetentionPolicy.RUNTIME).

2.2.2.2 Keywords

The following keywords are supported. Their use is the same as in the Java programming language.


TABLE 2-2 Supported Keywords

abstract

default

if

private

this

boolean

do

implements

protected

throw

break

else

import

public

throws

byte

extends

instanceof

return

try

case

final

int

short

void

catch

finally

interface

static

while

class

for

new

super

 

continue

goto

package

switch

 


2.2.2.3 Types

Java programming language types boolean, byte, short, and int are supported. Objects (class instances and single-dimensional arrays) are also supported. Arrays can contain the supported primitive data types, objects, and other arrays.

Some Java Card implementations might not support use of the int data type. (Refer to Section 2.2.3.1, Integer Data Type).

2.2.2.4 Classes

Most of the classes in the java.lang package are not supported on the Java Card platform. The following classes from java.lang are supported on the card in a limited form.

Object

Java Card API classes descend from java.lang.Object, just as in the Java programming language. Most of the methods of Object are not available in the Java Card API, but the class itself exists to provide a root for the class hierarchy.

Throwable

Class Throwable and its subclasses are supported. Most of the methods of Throwable are not available in the Java Card API, but the class itself exists to provide a common ancestor for all exceptions.

2.2.3 Optionally Supported Items

This section describes the optional features of the Java Card platform. An optional feature is not required to be supported in a Java Card platform-compatible implementation. However, if an implementation does include support for an optional feature, it must be supported fully, and exactly as specified in this document.

2.2.3.1 Integer Data Type

The int keyword and 32-bit integer data type need not be supported in a Java Card implementation. A Java Card virtual machine that does not support the int data type will reject programs which use the int data type or 32-bit intermediate values.

The result of an arithmetic expression produced by a Java Card virtual machine must be equal to the result produced by a Java virtual machine, regardless of the input values. A Java Card virtual machine that does not support the int data type must reject expressions that could produce a different result.

2.2.3.2 Object Deletion Mechanism

Java Card technology, version 2.2.2 offers an optional, object deletion mechanism. Applications designed to run on these implementations can use the facility by invoking the appropriate API. See Application Programming Interface, Java Card Platform, Version 2.2.2. But, the facility is best suited for updating large objects such as certificates and keys atomically. Therefore, application programmers should conserve on the allocation of objects.

2.2.4 Limitations of the Java Card Virtual Machine

The limitations of resource-constrained hardware prevent Java Card virtual machines from supporting the full range of functionality of certain Java platform features. The features in question are supported, but a particular virtual machine may limit the range of operation to less than that of the Java platform.

To ensure a level of portability for application code, this section establishes a minimum required level for partial support of these language features.

The limitations here are listed as maximums from the application programmer's perspective. Java packages that do not violate these maximum values can be converted into Java Card technology-based CAP files ("Java Card CAP files"), and will be portable across all Java Card implementations. From the Java Card virtual machine implementer's perspective, each maximum listed indicates a minimum level of support that will allow portability of applets.

2.2.4.1 Packages

Package References

A package can reference at most 128 other packages.

Package Name

The fully qualified name of a package may contain a maximum of 255 characters. The package name size is further limited if it contains one or more characters which, when represented in UTF-8 format, requires multiple bytes.

2.2.4.2 Classes

Classes in a Package

A package can contain at most 255 classes and interfaces.

Interfaces

A class can implement at most 15 interfaces, including interfaces implemented by superclasses.

An interface can inherit from at most 14 superinterfaces.

Static Fields

A class in an applet package can have at most 256 public or protected static non-final fields. A class in a library package can have at most 255 public or protected static non-final fields. There is no limit on the number of static final fields (constants) declared in a class.

Static Methods

A class in an applet package can have at most 256 public or protected static methods. A class in a library package can have at most 255 public or protected static methods.

2.2.4.3 Objects

Methods

A class can implement a maximum of 128 public or protected instance methods, and a maximum of 128 instance methods with package visibility. These limits include inherited methods.

Class Instances

Class instances can contain a maximum of 255 fields, where an int data type is counted as occupying two fields. These limits include inherited fields.

Arrays

Arrays can hold a maximum of 32767 components.

2.2.4.4 Methods

The maximum number of variables that can be used in a method is 255. This limit includes local variables, method parameters, and, in the case of an instance method invocation, a reference to the object on which the instance method is being invoked (meaning, this). An int data type is counted as occupying two local variables.

A method can have at most 32767 Java Card virtual machine bytecodes. The number of Java Card technology-based bytecodes ("Java Card bytecodes") may differ from the number of Java bytecodes in the Java virtual machine implementation of that method.

The maximum depth of an operand stack associated with a method is 255 16-bit cells.

2.2.4.5 Switch Statements

The format of the Java Card virtual machine switch instructions limits switch statements to a maximum of 65536 cases. This limit is far greater than the limit imposed by the maximum size of methods (Section 2.2.4.4, Methods).

2.2.4.6 Class Initialization

The Java Card virtual machine contains limited support for class initialization because there is no general mechanism for executing <clinit> methods. Support for <clinit> methods is limited to the initialization of static field values with the following constraints:

Primitive constant data types include boolean, byte, short, and int.

Given Java technology source files that adhere to these language-level constraints on static field initialization, it is expected that reasonable Java compilers will:

2.2.5 Multiselectable Applets Restrictions

Applets that implement the javacard.framework.Multiselectable interface are called multiselectable applets. For more details on multiselection, please see the Runtime Environment Specification, Java Card Platform, Version 2.2.2.

All applets within a package shall be multiselectable, or none shall be.

2.2.6 Java Card Platform Remote Method Invocation (RMI) Restrictions

This section defines the subset of the RMI system that is supported by Java Card platform RMI ("Java Card RMI").

2.2.6.1 Remote Classes and Remote Interfaces

A class is remote if it or any of its superclasses implements a remote interface.

A remote interface is an interface which satisfies the following requirements:

In addition, Java Card RMI imposes additional constraints on the definition of remote methods. These constraints are as a result of the Java Card platform language subset and other feature limitations. For more information, see Section 2.2.6.2, Access Control of Remote Interfaces and Section 2.2.6.3, Parameters and Return Values.

2.2.6.2 Access Control of Remote Interfaces

The Java RMI system supports the package access control defined in the Java language. However, Java Card RMI does not support package-visible remote interfaces.

2.2.6.3 Parameters and Return Values

The parameters of a remote method must only include parameters of the following types:

The return type of a remote method must only be one of the following types:


2.3 Java Card VM Subset

Java Card technology uses a subset of the Java virtual machine, and familiarity with the Java platform is required to understand the Java Card virtual machine.

The items discussed in this section are not described to the level of a virtual machine specification. For complete documentation on the Java virtual machine, refer to the The Java Virtual Machine Specification.

2.3.1 class File Subset

The operation of the Java Card virtual machine can be defined in terms of standard Java platform class files. Since the Java Card virtual machine supports only a subset of the behavior of the Java virtual machine, it also supports only a subset of the standard class file format.

2.3.1.1 Not Supported in Class Files

Class access flags
In class_info and interface_info structures, the access flag ACC_ENUM is not supported.
Field Descriptors

Field descriptors may not contain BaseType characters C, D, F or J. ArrayType descriptors for arrays of more than one dimension may not be used.

Constant Pool

Constant pool table entries with the following tag values are not supported.


TABLE 2-3 Unsupported Java Constant Pool Tags

Constant Type

Value

CONSTANT_String

8

CONSTANT_Float

4

CONSTANT_Long

5

CONSTANT_Double

6


Fields

In field_info structures, the access flags ACC_VOLATILE, ACC_TRANSIENT and ACC_ENUM are not supported.

Methods

In method_info structures, the access flags ACC_SYNCHRONIZED, ACC_STRICT, ACC_NATIVE, and ACC_VARARGS are not supported.

2.3.1.2 Supported in Class Files

ClassFile

All items in the ClassFile structure are supported.

Field Descriptors

Field descriptors may contain BaseType characters B, I, S and Z, as well as any ObjectType. ArrayType descriptors for arrays of a single dimension may also be used.

Method Descriptors

All forms of method descriptors are supported.

Constant pool

Constant pool table entry with the following tag values are supported.


TABLE 2-4 Supported Java Constant Pool Tags

Constant Type

Value

CONSTANT_Class

7

CONSTANT_Fieldref

9

CONSTANT_Methodref

10

CONSTANT_InterfaceMethodref

11

CONSTANT_Integer

3

CONSTANT_NameAndType

12

CONSTANT_Utf8

1


Fields

In field_info structures, the supported access flags are ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC and ACC_FINAL.

The remaining components of field_info structures are fully supported.

Methods

In method_info structures, the supported access flags are ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL and ACC_ABSTRACT.

The remaining components of method_info structures are fully supported.

Attributes

The attribute_info structure is supported. The Code, ConstantValue, Exceptions, LocalVariableTable, Synthetic, InnerClasses, RuntimeInvisibleAnnotations, RuntimeInvisibleParameterAnnotations and Deprecated attributes are supported.

2.3.2 Bytecode Subset

The following sections detail the bytecodes that are either supported or unsupported in the Java Card platform. For more details, refer to Chapter 7, "Java Card Virtual Machine Instruction Set".

2.3.2.1 Unsupported Bytecodes


TABLE 2-5 Unsupported Bytecodes

lconst_<l>

fconst_<f>

dconst_<d>

ldc2_w2

lload

fload

dload

lload_<n>

fload_<n>

dload_<n>

laload

faload

daload

caload

lstore

fstore

dstore

lstore_<n>

fstore_<n>

dstore_<n>

lastore

fastore

dastore

castore

ladd

fadd

dadd

lsub

fsub

dsub

lmul

fmul

dmul

ldiv

fdiv

ddiv

lrem

frem

drem

lneg

fneg

dneg

lshl

lshr

lushr

land

lor

lxor

i2l

i2f

i2d

l2i

l2f

l2d

f2i

f2d

d2i

d2l

d2f

i2c

lcmp

fcmpl

fcmpg

dcmpl

dcmpg

lreturn

freturn

dreturn

monitorenter

monitorexit

multianewarray

goto_w

jsr_w

 

 

 


2.3.2.2 Supported Bytecodes


TABLE 2-6 Supported Bytecodes

nop

aconst_null

iconst_<i>

bipush

sipush

ldc

ldc_w

iload

aload

iload_<n>

aload_<n>

iaload

aaload

baload

saload

istore

astore

istore_<n>

astore_<n>

iastore

aastore

bastore

sastore

pop

pop2

dup

dup_x1

dup_x2

dup2

dup2_x1

dup2_x2

swap

iadd

isub

imul

idiv

irem

ineg

ior

ishl

ishr

iushr

iand

ixor

iinc

i2b

i2s

if<cond>

ificmp_<cond>

ifacmp_<cond>

goto

jsr

ret

tableswitch

lookupswitch

ireturn

areturn

return

getstatic

putstatic

getfield

putfield

invokevirtual

invokespecial

invokestatic

invokeinterface

new

newarray

anewarray

arraylength

athrow

checkcast

instanceof

wide

ifnull

ifnonnull


2.3.2.3 Static Restrictions on Bytecodes

A class file must conform to the following restrictions on the static form of bytecodes.

ldc, ldc_w

The ldc and ldc_w bytecodes can only be used to load integer constants. The constant pool entry at index must be a CONSTANT_Integer entry. If a program contains an ldc or ldc_w instruction that is used to load an integer value less than
-32768 or greater than 32767, that program will require the optional int instructions (Section 2.2.3.1, Integer Data Type).

lookupswitch

The value of the npairs operand must be less than 65536. This limit is far greater than the limit imposed by the maximum size of methods (Section 2.2.4.4, Methods). If a program contains a lookupswitch instruction that uses keys of type int, that program will require the optional int instructions (Section 2.2.3.1, Integer Data Type). Otherwise, key values must be in the range
-32768 to 32767.

tableswitch

The bytecode can contain at most 65536 cases. This limit is far greater than the limit imposed by the maximum size of methods (Section 2.2.4.4, Methods). If a program does not use the optional int instructions (Section 2.2.3.1, Integer Data Type), the values of the high and low operands must both be at least -32768 and at most 32767.

wide

The wide bytecode can only be used with an iinc instruction.

2.3.3 Exceptions

The Java Card platform provides full support for the Java platform's exception mechanism. Users can define, throw and catch exceptions just as in the Java platform. The Java Card platform also makes use of the exceptions and errors defined in The Java Language Specification. An updated list of the Java platform's exceptions is provided in the JDKtrademark software documentation.

Not all of the Java platform's exceptions are supported in the Java Card platform. Exceptions related to unsupported features are naturally not supported. Class loader exceptions (the bulk of the checked exceptions) are not supported.

Note that some exceptions may be supported to the extent that their error conditions are detected correctly, but classes for those exceptions will not necessarily be present in the API.

The supported subset is described in the tables below.

2.3.3.1 Uncaught and Uncatchable Exceptions

In the Java platform, uncaught exceptions and errors will cause the virtual machine's current thread to exit. As the Java Card virtual machine is single-threaded, uncaught exceptions or errors will cause the virtual machine to halt. Further response to uncaught exceptions or errors after halting the virtual machine is an implementation-specific policy, and is not mandated in this document.

Some error conditions are known to be unrecoverable at the time they are thrown. Throwing a runtime exception or error that cannot be caught will also cause the virtual machine to halt. As with uncaught exceptions, implementations may take further responses after halting the virtual machine. Uncatchable exceptions and errors which are supported by the Java Card platform may not be reflected in the Java Card API, though the Java Card platform will correctly detect the error condition.

2.3.3.2 Checked Exceptions

 


TABLE 2-7 Support of Java Checked Exceptions

Exception

Supported

Not Supported

ClassNotFoundException

 

X

CloneNotSupportedException

 

X

IllegalAccessException

 

X

InstantiationException

 

X

InterruptedException

 

X

NoSuchFieldException

 

X

NoSuchMethodException

 

X


2.3.3.3 Runtime Exceptions


TABLE 2-8 Support of Java Runtime Exceptions

Runtime Exception

Supported

Not Supported

ArithmeticException

X

 

ArrayStoreException

X

 

ClassCastException

X

 

IllegalArgumentException

 

X

IllegalThreadStateException

 

X

NumberFormatException

 

X

IllegalMonitorStateException

 

X

IllegalStateException

 

X

IndexOutOfBoundsException

X

 

ArrayIndexOutOfBoundsException

X

 

StringIndexOutOfBoundsException

 

X

NegativeArraySizeException

X

 

NullPointerException

X

 

SecurityException

X

 


2.3.3.4 Errors


TABLE 2-9 Support of Java Errors

Error

Supported

Not Supported

AssertionError

 

X

LinkageError

X

 

ClassCircularityError

X

 

ClassFormatError

X

 

ExceptionInInitializerError

X

 

IncompatibleClassChangeError

X

 

AbstractMethodError

X

 

IllegalAccessError

X

 

InstantiationError

X

 

NoSuchFieldError

X

 

NoSuchMethodError

X

 

NoClassDefFoundError

X

 

UnsatisfiedLinkError

X

 

VerifyError

X

 

ThreadDeath

 

X

VirtualMachineError

X

 

InternalError

X

 

OutOfMemoryError

X

 

StackOverflowError

X

 

UnknownError

X

 

UnsupportedClassVersionError

X