By Bruce Hopkins, January 2010
No, that's not a typo. No, I'm not talking about technology that will be available 10 years from now. Java Card 3.0 technology is available today that allows application developers to create and deploy servlet applications on smart card devices. This article shows developers how to get started with developing servlets with the Java Card Connected Development Kit 3.0.2.
In previous versions of the Java Card specification, Java developers were significantly limited in the breadth and depth of the applications that could be created for Java Card 2 devices, such as:
.class
filesDespite these limitations, Java Card technology became the most widely deployed Java platform in the world with over 3.5 billion deployments. Java Card 3.0 technology has several significant enhancements over the Java Card 2 platform, as explained in the following sections.
As you can see from the sequence diagrams in Figures 1 and 2 located below, creating a complete application that involved using Java Card 2 technology could be tedious.
Figure 1. A Sequence Diagram Depicting the Interactions Between a Desktop Application and a Java Card 2 Application
Figure 2. A Sequence Diagram Depicting the Interactions Between a Mobile Application and a Java Card 2 Application
As you can see from the preceding figures, both the desktop and mobile applications need to eventually use the APDU (application protocol data unit) protocol to communicate with applications (also known as applets) located on the Java Card 2 smart card. In some cases, however, the API restrictions -- combined with having to use byte arrays for all interaction with the smart card -- were major deterrents to attracting enterprise Java developers to the Java Card platform.
However, the Java Card 3 platform provides significant improvements to its predecessor, and those changes should appeal not only to enterprise and desktop developers, but to mobile developers as well. The Java Card 3 platform includes support for the following features:
byte
, short
, int
, long
, char
and java.lang.String
.class
files.war
deployment filesFigure 3, shown below is a sequence diagram showing the steps and actions involved in creating a complete application using the Java Card 3 platform.
Figure 3. A Sequence Diagram Depicting the Interactions Between a Mobile or Desktop Application and a Java Card 3 Application
With Java Card 3 technology, smart card application development has instantly become a lot easier, and has now taken a significant leap-ahead in capability so that the following scenarios are possible:
Did you know that Java Card applications have access to two heap spaces? One of them is volatile, which means that it acts like RAM, so all information stored in that heap location is lost after the system is reset (that is, when the card is removed and inserted). The other heap area is non-volatile, so data stored in that location is truly persistent, even after a system reset.
To get clear understanding of how to store data on the card in the volatile heap allocation, let's take a look at the Persistence example from the Java Card Connected Development Kit 3.0.2. Table 1, shown below, provides a detailed breakdown of the files contained within the %folder_root%\JCDK3.0.2_ConnectedEdition\samples\web\Persistence
folder.
Table 1. Description of Files and Folders Within the Persistence Example
Folder/File Name | Description |
---|---|
/build.xml |
This is the primary ant build xml file. The project name, base directory, and import file are specified in this file. |
/build/ |
This is the parent folder that contains the build arifacts that will be automatically created by ant. These artifacts include the intermediary /WEB-INF/classes folder, which will be packaged into the final .war file |
/config/ |
This is the parent folder that contains the configuration files. |
/config/build-impl.xml |
This is an autogenerated ant build file that is imported from the primary build.xml file. It is not recommended for developers to modify this file. |
/config/genfiles.properties |
This is an autogenerated file used by NetBeans. It is not recommended for developers to modify this file. |
/config/project.properties |
This is the main property file that sets several configurable properties such as the main servlet, the main URL, as well as the web context path. |
/config/project.xml |
This the NetBeans project XML file. |
/dist |
This is the parent folder containing the redistributable items / artifacts after the build process is complete. |
/dist/Presistence.signature |
This is a binary file that contains a digital signature. |
/dist/Presistence.war |
This is the deployable .war file that will be loaded on the Java Card. |
/html/ |
This is the parent folder containing the index.html as well as the accompanying images. |
/html/index.html |
This is a simple placeholder html page that redirects to the "index" path of the JavaCard WAR application. |
/html/images/ |
This is the folder that contains the images referenced by the JavaCard servlet. |
/META-INF/ |
This is the parent folder containing manifest files. |
/META-INF/javacard.xml |
This is the JavaCard application descriptor file. |
/META-INF/MANIFEST.MF |
This is a simpe manifest file that's common for JAR and WAR files. |
/src |
This is the parent folder for all Java source code. |
src/.../PresistanceServlet.java |
This is a servlet that shows the contents of the database, adds new items to the database, and deletes existing items. |
src/.../IndexServlet.java |
This is a servlet that has been mapped to the "index" path of the Java Card WAR application. This servlet presents an HTML form, which invokes the HelloWorldServlet card application. |
src/.../Database.java |
JavaCard 3 applications have two heap spaces (volatile and non-volatile). This is a simple class that store data in volatile heap. |
/WEB-INF |
This is the parent folder that contains the assests used by the servlets. |
/WEB-INF/footer.i |
This is a part of an HTML file. |
/WEB-INF/header.i |
This is a part of an HTML file. |
/WEB-INF/index.i |
This is a part of an HTML file. |
/WEB-INF/web.xml |
This is a typical web.xml that defines and maps the servlets with URLs. |
Listing 1 is the code for Database.java
, a class that allows multiple users in different browser sessions to store and retrieve data objects from the volatile heap space of a Java Card application.
Listing 1. Database.java
package com.sun.jchowto.persistence;
import java.util.Vector;
/**
*
*/
public class Database {
private static Vector<String> items = new Vector<String>();
/**
* @param item
*/
public static void addItem(String item) {
if (!items.contains(item)) {
items.addElement(item);
}
}
/**
* @return
*/
public static Vector<String> getItems() {
return items;
}
/**
* @param item
* @return
*/
public static boolean delete(String item) {
return items.removeElement(item);
}
}
As you can see, the code for the database is pretty simple as it is primarily a wrapper class that allows users to store, retrieve, and delete objects from a String-typed Vector. It demonstrates the capabilities of the Java Card 3 platform well, since it shows that you can use generics, first introduced in the Java SE 5.0.
Listing 2 is the code for the Java Card 3 servlet that accesses the database.
Listing 2. PersistenceServlet.java
package com.sun.jchowto.persistence;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* A Simple Persistence Servlet.
*/
public class PresistanceServlet extends HttpServlet {
/* (non-Javadoc)
* @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
String op = request.getParameter("op");
String item = request.getParameter("item");
if (op != null) {
if (op.equals("Add")) {
if (item != null) {
Database.addItem(item);
}
} else if (op.equals("Delete")) {
if (item != null) {
Database.delete(item);
}
}
}
response.setContentType("text/html");
PrintWriter out = response.getWriter();
RequestDispatcher dispatcher = null;
dispatcher = request.getRequestDispatcher("/WEB-INF/header.i");
dispatcher.include(request, response);
out.println("<tr>");
out.println("<td bgcolor=\"#FFFFFF\" align=\"center\" valign=\"middle\">");
out.println("<table bgcolor=\"#000000\" border=\"0\" width=\"100%\" cellspacing=\"1\" cellpadding=\"15\">");
out.println("<tr>");
out.println("<td align=\"center\" bgcolor=\"#FFFFFF\">");
out.println("</b><big><big>Simple Database</big></big></b>");
out.println("<form method=\"get\" action=\"database\">");
out.println("<table border = 0>");
out.println("<tr>");
out.println("<td>Item : </td><td colspan=2><input type=\"text\" name=\"item\"></input></td>");
out.println("</tr>");
out.println("<tr>");
out.println("<td> </td>");
out.println("<td><input type=\"submit\" name=\"op\" value=\"Add\"></td>");
out.println("<td><input type=\"submit\" name=\"op\" value=\"Delete\"></td>");
out.println("</tr>");
out.println("<tr>");
out.println("<td colspan=3><hr></td>");
out.println("</tr>");
out.println("<tr>");
out.println("<td colspan=3><b>Items in Database</b></td>");
out.println("</tr>");
out.println("<tr>");
out.println("<td colspan=3><textarea readonly rows=\"5\" cols=\"20\">");
if(Database.getItems().size() <= 0) {
out.print(" \n \nDatabase is Empty;\n \n ");
} else {
for (String str : Database.getItems()) {
out.println(str);
}
}
out.println("</textarea></td>");
out.println("</tr>");
out.println("</table>");
out.println("</form>");
out.println("</td>");
out.println("</tr>");
out.println("</table>");
out.println("</td>");
out.println("</tr>");
dispatcher = request.getRequestDispatcher("/WEB-INF/footer.i");
dispatcher.include(request, response);
}
}
As you can see from the preceding code listing, PersistenceServlet.java
works like any other subclass of HTTPServlet. All you need to do is override the HTTP methods that you want, and replace them with your own code. In this case, we're only supporting HTTP GET requests. If the HTTP parameter "op" is set to "Add", then we'll add a new item to the database. If, however, "op" is set to "Delete", then the specified item will be removed from the database.
In either case, the servlet completes its work by showing the final list of contents in the database. The Java Card 3 platform doesn't support JSP files, so you should notice in Listing 2 that much of the application is dedicated to creating the HTML response. Figure 4 is the PersistenceServlet in action.
Figure 4. Adding My Favorite Stock Symbols to the PersistenceServlet.java
The Java Card 3 platform is lightyears ahead of its predecessor. It includes several new features that allow developers to create extremely sophisticated applications using Java servlet technology. Are you ready for a new generation of servlet applications that execute on a smart card?