Integrate new Java Card applet project in Visual Studio Code
To begin developing your Java Card applet, start by creating a new Maven project using Oracle Java Platform Extension. Open VS Code and select View > Command Palette or by using `Ctrl+Shift+P` for Windows/Linux. In the palette, select Java: New Project and choose Java with Maven to proceed. Follow the on-screen instructions to set up your project.
Create a “configurations” folder in your project root directory and add a
file named “applet-name.conf
”:
-i
-classdir ../bin
-applet <applet-AID> <class-name>
-out CAP JCA EXP
-d ../deliverables/<applet-name>
-v
-debug
-target 3.2.0
<package-name>
<package-AID> 1.0
This file contains the options that will be passed to the Converter. Specify the following:
- The applet’s AID (
<applet-AID>
). The AID has 5 to 16 decimal, hex or octal numbers separated by colons (e.g. 0xa0:0x00:0x00:0x00:0x62:0x03:0x01:0x0c:0x07); - The fully-qualified class name that defines the applet
(
<class-name>
). For example, the HelloWorld sample has the class namecom.oracle.jcclassic.samples.helloworld.HelloWorld
; - The name of the applet (
<applet-name>
). In the case of the HelloWorld sample, the name of the applet isHelloWorld
; - The fully-qualified package name of the package that will be converted
(
<package-name>
). For example, the HelloWorld sample has the package name of the appletcom.oracle.jcclassic.samples.helloworld
; - The package AID of the package that will be converted
(
<package-AID>
). For example, the HelloWorld sample has the package AID 0xA0:0x00:0x00:0x00:0x62:0x03:0x01:0x0C:0x01;
By default, the target Java Card platform version is 3.2.0, but can be replaced with other versions as needed. Similarly, the default package version is 1.0, but can be replaced with the desired version.
For more information regarding the options, see section Running the Converter inside the Development Kit Tools User Guide.
Next, within your project root directory, create a .vscode
folder. Inside this folder, add two files:
launch.json
file
{
"version": "0.2.0",
"configurations": [
{
"name": "Convert and Verify Applet",
"type": "node-terminal",
"request": "launch",
"command": "exit",
"windows": {
"command": "exit",
},
"preLaunchTask": "Convert and Verify Applet",
"suppressMultipleSessionWarning": true,
},
{
"command": "${JC_HOME_SIMULATOR}/runtime/bin/jcsl",
"windows": {
"command": "Set-Location ${Env:JC_HOME_SIMULATOR}\\runtime\\bin; .\\jcsw.exe",
},
"name": "Start Java Card Simulator",
"request": "launch",
"type": "node-terminal",
},
{
"name": "Start Java Card Simulator Debug Mode",
"type": "jdk",
"request": "attach",
"hostName": "localhost",
"port": "8000",
"preLaunchTask": "PreTask Debug",
"postDebugTask": "Terminate All Tasks",
}
],
}
tasks.json
file
{
"version": "2.0.0",
"tasks": [
{
"label": "Build Applet",
"type": "shell",
"icon": {
"id": "wrench",
"color": "terminal.ansiYellow"
},
"command": "${JAVA_HOME}/bin/javac -d ${workspaceFolder}/bin -g --release 10 -cp .:${JC_HOME_TOOLS}/lib/api_classic-3.2.0.jar:${JC_HOME_TOOLS}/lib/tools.jar:${JC_HOME_TOOLS}/lib/api_classic_annotations-3.2.0.jar $(find \"${workspaceFolder}/src\" -name \"*.java\")",
"windows": {
"command": "$classpath ='.;${env:JC_HOME_TOOLS}\\lib\\api_classic-3.2.0.jar;${env:JC_HOME_TOOLS}}\\lib\\tools.jar;${env:JC_HOME_TOOLS}\\lib\\api_classic_annotations-3.2.0.jar';$sourceFiles = (Get-ChildItem -Path \"${workspaceFolder}\\src\" -Recurse -Filter '*.java').FullName; javac -d \"${workspaceFolder}\\bin\" -g --release 10 -cp $classpath $sourceFiles"
},
"problemMatcher": [],
"presentation": {
"reveal": "never",
"close": true,
"focus": false,
"panel": "dedicated"
}
},
{
"label": "Convert and Verify Applet",
"type": "shell",
"icon": {
"id": "chip",
"color": "terminal.ansiYellow"
},
"command": "cd ${workspaceFolder}/src && package_list=\"${package_list:-*}\" && shopt -s nullglob; IFS=' '; read -r -a file_list <<<\"$package_list\" && for i in \"${file_list[@]}\"; do ${JC_HOME_TOOLS}/bin/converter.sh -config $(find \"../configurations\" -name \"${i}.conf\"); done”,
"windows": {
"command": "Set-Location \"${workspaceFolder}\\src\"; $package_list = if([string]::IsNullOrEmpty($Env:package_list)) { '*' } else { $Env:package_list }; $items =$package_list -split ' '; foreach ($i in $items) { $label = $i + '.conf'; $conf_file =(Get-ChildItem \"..\\configurations\" -Recurse -Filter $label).FullName; &\"${env:JC_HOME_TOOLS}\\bin\\converter.bat\" -config $conf_file};",
},
"problemMatcher": [],
"dependsOn": ["Build Applet"],
"presentation": {
"reveal": "always",
"close": false,
"focus": true,
"panel": "dedicated"
}
},
{
"label": "Launch Java Card Debug Proxy Task",
"icon": {
"color": "terminal.ansiMagenta",
"id": "plug"
},
"type": "shell",
"command": "${JAVA_HOME}/bin/java -jar ${JC_HOME_SIMULATOR}/client/DebugProxy/jc-debug-proxy.jar -capPath $(find \"./deliverables\" -name \"*.cap\" | tr '\n' ':') -debug-info \"${JC_HOME_SIMULATOR}/client/DebugProxy/debug-info\" -vmPort 8008 -port 8000",
"windows": {
"command": "$CapFile = (Get-ChildItem -Path \"./deliverables\" -Recurse -Filter '*.cap'| ForEach-Object { $_.FullName }) -join ';' ; Set-Location ${Env:JAVA_HOME}\\bin; java -jar ${Env:JC_HOME_SIMULATOR}\\client\\DebugProxy\\jc-debug-proxy.jar -capPath $CapFile -debug-info \"${Env:JC_HOME_SIMULATOR}\\client\\DebugProxy\\debug-info\" -vmPort 8008 -port 8000"
},
"problemMatcher": [
{
"owner": "java-proxy",
"severity": "info",
"pattern": [
{
"regexp": "^(INFO|ERROR|WARNING):\\s+(.*)$",
"file": 2,
"location": 1,
"severity": 1,
"message": 2
}
],
"background": {
"activeOnStart": true,
"beginsPattern": ".*handshake to VM\\d+$",
"endsPattern": ".*waiting for IDE on open server socket on port: \\d+$",
},
},
],
"dependsOn": [
"Wait for Port 8008"
],
"isBackground": true,
"presentation": {
"close": true,
"focus": false,
"panel": "dedicated",
},
},
{
"label": "Wait for Port 8008",
"icon": {
"id": "sync",
"color": "terminal.ansiBlue"
},
"type": "shell",
"command": "sleep 2 && while ! nc -z 127.0.0.1 8008; do sleep 1; done",
"problemMatcher": [],
"windows": {
"command": "while (-not (Test-NetConnection -ComputerName 127.0.0.1 -Port 8008 -InformationLevel Quiet)) { Start-Sleep -Seconds 1 }"
},
"presentation": {
"reveal": "never",
"close": true,
"focus": false,
"panel": "dedicated"
}
},
{
"label": "Start Java Card Simultor Debug Mode",
"icon": {
"color": "terminal.ansiGreen",
"id": "remote-explorer"
},
"type": "shell",
"command": "${JC_HOME_SIMULATOR}/runtime/bin/jcsl -debug_port=8008",
"windows": {
"command": "Set-Location ${Env:JC_HOME_SIMULATOR}\\runtime\\bin; .\\jcsw.exe -debug_port=8008"
},
"problemMatcher": [
{
"owner": "javacard-simulator",
"severity": "info",
"pattern": [
{
"regexp": "^(INFO|ERROR|WARNING|CONFIG):\\s+(.*)$",
"file": 2,
"location": 1,
"severity": 1,
"message": 2
}
],
"background": {
"activeOnStart": true,
"beginsPattern": ".*set log level to\\d+$",
"endsPattern": ".*server ready on port #\\d+$",
},
}
],
"runOptions": {
"instanceLimit": 1,
"reevaluateOnRerun": true
},
"isBackground": true,
"presentation": {
"close": true,
"focus": false,
"panel": "dedicated",
},
},
{
"label": "PreTask Debug",
"dependsOn": [
"Start Java Card Simultor Debug Mode",
"Launch Java Card Debug Proxy Task"
],
"runOptions": {
"runOn": "default",
}
},
{
"label": "Terminate All Tasks",
"command": "echo ${input:terminate}",
"type": "shell",
"problemMatcher": [],
}
],
"inputs": [
{
"id": "terminate",
"type": "command",
"command": "workbench.action.tasks.terminate",
"args": "terminateAll"
}
]
These files will enable the functionality of converting the applet, starting the simulator and starting the simulator in debug mode.
For a project containing multiple files, create a
settings.json
file inside the .vscode
folder. Add
the following:
{
"terminal.integrated.env.windows": {
"package_list": "<configuration-files-list>"
},
"terminal.integrated.env.linux": {
"package_list": "<configuration-files-list>"
},
}
Specify the list of configuration files in the field “package_list” of the integrated terminal settings of your operating system. The values should be separated by a space. For example, a standalone ObjectDeletion applet would have the value of "package_list" "libPackageC packageA packageB".
To enable code completion and IntelliSense, add the following to your maven
(pom.xml
) file.
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.10</maven.compiler.source>
<maven.compiler.target>1.10</maven.compiler.target>
<jc.devkit.tools>${JC_HOME_TOOLS}</jc.devkit.tools>
</properties>
<dependencies>
<dependency>
<groupId>javacard</groupId>
<artifactId>api_classic-3.2.0</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${jc.devkit.tools}/lib/api_classic-3.2.0.jar</systemPath>
</dependency>
<dependency>
<groupId>javacard</groupId>
<artifactId>api_classic_annotations-3.2.0</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${jc.devkit.tools}/lib/api_classic_annotations-3.2.0.jar</systemPath>
</dependency>
<dependency>
<groupId>javacard</groupId>
<artifactId>tools</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${jc.devkit.tools}/lib/tools.jar</systemPath>
</dependency>
</dependencies>