JC101-1j: Hello World (for Java developers)

UPDATED (03/10/08): Fixed some more bugs …

UPDATED (05/05/07): Fixed some bugs; added a few explanations.

“Hello world” seems easy in most languages, but there are several reasons that make it cumbersome to write in Java Card. First, Java Card only supports a subset of the Java language, and this subset includes neither the char type, nor the String type. Well, we will use bytes. Then, a Java Card does not have a screen to display “Hello world” on; in fact, the Java Card specification defines a server-side framework, and a Java Card applet will only respond to requests made from a terminal. So, we will have to handle that request.

The easiest way to do that is to use the RMI framework included in Java Card (since version 2.2). Like in any distributed object scheme, we first need to write an interface that defines the function to be implemented:

 1 package com.vetilles.helloworld ;
 2
 3 import java.rmi.Remote ;
 4 import java.rmi.RemoteException ;
 5
 6 public interface IHelloWorld extends Remote
 7 {
 8   public byte[] hello() throws RemoteException ;
 9 }

The source code is quite classical:

  • Line 1 is a package declaration. It has a particular importance in Java Card, because Java Card applets are packaged at the package level: all classes in a package are loaded together.
  • Lines 3 and 4 are typical import declarations, which are using standard Java packages. Whenever possible, rather than reinveting the wheel, Java Card subsets the standard Java APIs.
  • On line 6, the interface declaration is classical for RMI, extending the Remote interface.
  • On line 8, the method declaration is also classical for RMI. The possible RemoteException (a checked exception) is used to encapsulate the possible communication errors between the card and its client.

The next step is to implement the method, by defining a class that implements the interface:

 1 package com.vetilles.helloworld ;
 2
 3 import java.rmi.RemoteException ;
 4
 5 public class HelloWorld implements IHelloWorld
 6 {
 7   private static final byte[] message =
 8              {0x48, 0x65, 0x6c, 0x6c, 0x6f } ;
 9
10    public byte[] hello() throws RemoteException
11   {
12     return message ;
13   }
14 }
  • Lines 1 to 3 are the usual declarations.
  • Line 5 starts the declaration of a class called HelloWorld, which implements the IHelloWorld interface. This means that this class needs to implement all the methods declared in the interface.
  • Line 7 declares the message to return. It is declared as an array of bytes, with the short message “Hello”.
  • Lines 10 to 13 declare a method that simply returns the message. Note that the methods declares a RemoteException although it cannot throw it directly. Since the method is remote it declares the exception (which extends IOExceptionbecause of the possible communication problems when the method in invoked remotely.

The last element of the application is the applet class. Don’t be fooled by the name: a Java Card applet, unlike a classical Java applet, is a server-side component, which processes the requests that arrive to the card as command APDUs. The minimum required components in an applet class are as follows:

  • A constructor. In Java Card, objects are usually statically allocated, once and for all, in the applet constructor.
  • An install method. This static method is invoked by the system when the applet is installed. It usually allocated an applet instance, and then registers it to the system.
  • A process method. This method is invoked each time that an APDU is to be processed by the applet instance.

In our case, the applet is rather simple:

 1 package com.vetilles.helloworld ;
 2 
 3 import javacard.framework.* ;
 4 import javacard.framework.service.* ;
 5 
 6 public class HelloApplet extends Applet
 7 {
 8   HelloWorld hello ;
 9   Dispatcher disp ;
10   Service svc ;
11 
12   private HelloApplet()
13   {
14     hello = new HelloWorld() ;
15     svc = new RMIService(hello) ;
16     disp = new Dispatcher((short)1) ;
17     disp.addService(svc,Dispatcher.PROCESS_COMMAND) ;
18   }
19 
20   public static void install
21           (byte[] buf, short ofs, short len)
22   {
23     (new HelloApplet()).register() ;
24   }
25 
26   public void process(APDU apdu)
27   {
28     disp.process(apdu) ;
29   }
30 }

The most complex method is here the constructor, in which the objects are built:

  • On line 14, the remote object itself is built (i.e., the object that actually provides the service).
  • On line 15, a RMI service is built. This object will unwrap the arguments from incoming commands, invoke the appropriate method, and then wrap the return value into a response.
  • On line 16, a dispatcher is allocated, with a single slot for a single service.
  • Finally, on line 17, the RMI service is added to the dispatcher. The PROCESS_COMMAND parameter indicates that this particular services processes commands (i.e., it produces a response from an incoming command).

3 Comments

  • Hello! we encountered a problem at line 14 and line 23. What seems to be the problem? What is the hello = new HelloWorld for? there’s no variable HelloWorld. Also, the install() method is not in the code. The install method present has parameters. and line 23 calls an install method without parameters. What shall we do?

  • Yes, there is a bug, and there should be an invocation for register() in that code instead of install.

    The “new HelloWorld” is here to allocate a new instance of he HeeloWorld class, and it is just missing parentheses.

    I have corrected these in the text, but I can’t test the code right now, because I am traveling. Let’s hope that there are no more bugs …

  • Good tutorial and easy to follow.

Leave a Reply

Your email is never shared.Required fields are marked *