Skip to content

Java Code Tutorial, Beginner

Martin Paljak edited this page Jul 2, 2025 · 5 revisions

Important

JCardEngine is not a drop-in replacement for legacy jcardsim, learn about the major differences (improvements) here: migration from legacy jcardsim

Maven coordinates

<repositories>
    <repository>
        <id>javacard-pro</id>
        <url>https://mvn.javacard.pro/maven/</url>
    </repository>
    <!-- for SNAPSHOT version -->
     <repository>
         <id>javacard-pro-snapshots</id>
         <url>https://mvn.javacard.pro/maven/SNAPSHOTS/</url>  
     </repository>
</repositories>

<dependency>
    <groupId>com.github.martinpaljak</groupId>
    <artifactId>jcardengine</artifactId>
    <version>25.06.30-SNAPSHOT</version>
</dependency>

Installing applets

JavaCardEngine provides the features a Card Manager in a traditional JavaCard/GlobalPlatform device would provide: installing and deleting applets. It does this without transformed .cap files, but referencing your applet classes directly from classpath:

JavaCardEngine sim = JavaCardEngine.create();

AID aid = AIDUtil.create("010203040506");
byte[] install_parameters = Hex.decode("01020304")

// Create applet instance
sim.installApplet(aid, YourApplet.class, install_parameters);

// Delete applet instance
sim.deleteApplet(aid);

JVM lifetime

JCardEngine provides ephemeral JavaCard environment where the "card lifetime" is "process lifetime" - if the JVM dies, the card state is destroyed and a new simulator process (or even a new simulator instance, in case of JCardEngine) starts with a fresh and clean card.

Exposing applets

By default applet classes are isolated from the rest of the system. If you'd like to access either static fields or instance fields from your test code, install the applet in exposed mode

static class YourApplet extends Applet {
     public static boolean registered = false;

     public static void install(byte[] bArray, short bOffset, byte bLength) throws ISOException {
         new YourApplet().register();
         registered = true;
     }

     public void process(APDU apdu) {
         // other code
     }
}

sim.installExposedApplet(aid, YourApplet.class, new byte[0]);

System.out.println("Applet got registered: " + YourApplet.registered);

Sending APDU-s

try (EngineSession conn = sim.connect("T=CL")) {
    ResponseAPDU response_apdu = conn.transmit(new CommandAPDU(...));
    byte[] response_bytes = conn.transmit(new byte[] {...});
}

Important

EngineSession must be .close()-d, as it guards the exclusive access to the simulator! Use try-with-resources!

Using javax.smartcardio

Instead of

CardTerminal terminal = TerminalFactory.getDefault().terminals().getTerminal("Your Real PC/SC Reader Name");
Card card = terminal.connect("*");

use

JavaCardEngine sim = JavaCardEngine.create();

// install any necessary applets and initialize them

CardTerminal terminal = CardTerminalSimulator.terminal(sim);
Card card = terminal.connect("*");

Next steps

Continue with Java Code Tutorial, Intermediate.

Clone this wiki locally