您可能知道,正如Java Card Development Kit用户指南中所提到的,为Java Card平台编写大型应用程序的关键是将代码划分为单独的包单元.对程序包最重要的限制是对最大组件大小的64KB限制.对于Method组件尤其如此:如果应用程序的Method组件的大小超过64KB,则Java Card转换器将不处理该包并将返回错误.
因此,我们需要在某些特殊情况下使用Java Card库包.我的问题是如何创建以及如何使用这些Java Card库包?
到目前为止我做了什么?
好吧,我写了一个非常简单的Java类,其中包含一个名为sayHello()如下的方法:
package libPack;
import javacard.framework.*;
public class mylib {
public static final byte[] hello = {(byte)'H',(byte)'e',(byte)'l',(byte)'l',(byte)'o'};
protected mylib() {
}
public void sayHello(APDU apdu) {
byte[] buffer = apdu.getBuffer();
Util.arrayCopyNonAtomic(hello, (short)0x00, buffer, (short)0x00, (short)hello.length);
apdu.setOutgoingAndSend((short)0x00, (short)buffer.length);
}
}
Run Code Online (Sandbox Code Playgroud)
由于我在IDE-s(Netbeans和Eclipse)中找不到任何选项来创建cap库包文件(那些cap只有从Applet包创建的插件,我猜),我使用命令行创建我的库的cap文件为下面:
1.生成.class上述.java程序的文件:
CMD:> javac -g -source 1.2 -target 1.2 -cp "D:\JCDK\java_card_kit-2_2_2\lib\api.jar" "D:\LibSrc\mylib.java"
warning: [options] bootstrap class path not set in conjunction with -source 1.2
1 warning
CMD:>
Run Code Online (Sandbox Code Playgroud)
上面的命令生成一个.class文件,其名称是我的库类名.我在同一目录中创建一个文件夹,并将其命名为"libPack"(程序的包名称),然后我将此.class文件移入其中.
2.将创建的.class文件转换为.cap文件:
CMD:> D:\JCDK\java_card_kit-2_2_2\bin\converter.bat -debug -verbose -exportpath D:\JCDK\java_card_kit-2_2_2\api_export_files -classdir D:\LibSRC libPack 0xa0:0x0:0x0:0x0:0x62:0x3:0x1:0xc:0x6:0x1 1.0
Java Card 2.2.2 Class File Converter, Version 1.3
Copyright 2005 Sun Microsystems, Inc. All rights reserved. Use is subject to license terms.
parsing D:\LibSRC\libPack\mylib.class
converting libPack.mylib
parsing D:\JCDK\java_card_kit-2_2_2\api_export_files\java\lang\javacard\lang.exp
parsing D:\JCDK\java_card_kit-2_2_2\api_export_files\javacard\framework\javacard\framework.exp
writing D:\LibSRC\libPack\javacard\libPack.exp
writing D:\LibSRC\libPack\javacard\libPack.jca
conversion completed with 0 errors and 0 warnings.
CMD:>
Run Code Online (Sandbox Code Playgroud)
在上面的命令中,在"libPack\javacard"目录中生成libPack.cap和libPack.exp文件.
问题:
更新:(基于亲爱的Vojta的回答)
为了使整个过程独立于IDE,我再次使用命令行中的以下命令创建.jar我的库.class文件的文件:
CMD:> jar cfv mylib.jar D:\LibSRC\libPack\mylib.class
CMD:>
Run Code Online (Sandbox Code Playgroud)
上面的命令,从命令行当前目录中的"mylib.class"文件创建"mylib.jar".
之后,我将这个"mylib.jar"文件及其已经创建的.exp文件(使用Converter的上一步)添加到Netbeans IDE中的Applet项目,就像我在这里解释的那样.
现在我想sayHello()在我的applet中使用我的库的方法:
如您所见,我仍然收到错误.那是什么?据我所知,我无法在库包中定义静态方法(对吗?),所以我可以在哪里使用库方法?
任何带有一些公共类和公共方法的Java Card包都可以用作库.如果您使用Eclipse JCOP Tools,则可以非常轻松地构建库:cap文件在文件夹中自动创建:
/[workspace]/[project]/bin/[path according to package]/javacard
Run Code Online (Sandbox Code Playgroud)
Java Card库就是任何包; 即使是带有a的包Applet也可以作为一个.因此,构建"通用" cap文件和"库" cap文件之间没有真正的区别.
请注意,Shareable在库包中实现接口和静态方法的对象之间存在一些差异.Shareableinterface可用于通过上下文B中的防火墙访问上下文A中的对象实例.但是,static方法可以从任何上下文访问 - 不应用防火墙规则.这里有一个很好的AppletIsolation和对象共享概述.关于static方法的最重要段落是6.1.6:
类 - 对象的实例 - 由上下文拥有; 班级本身不是.访问类静态字段时,不能执行运行时上下文检查.调用静态方法时也没有上下文切换.
可以从任何上下文访问公共静态字段和公共静态方法:静态方法在与调用者相同的上下文中执行.
静态字段中引用的对象只是常规对象.它们由创建它们的任何人拥有,并且适用标准防火墙访问规则.如果需要跨多个上下文共享它们,则这些对象需要是可共享接口对象(SIO).
当然,传统的Java技术保护仍然针对静态字段和方法实施.此外,安装applet时,安装程序会验证是否允许每次尝试链接到外部静态字段或方法.关于链接的安装和细节超出了本规范的范围.
简而言之:静态库中没有静态对象= Shareable不需要.
您有时需要在新applet中使用现有库,尽管您没有库的源代码.库可能已由供应商或某些第三方加载到您的卡中.您需要一个jar文件和exp库的文件才能在您的applet中使用它.
您需要在通用Java文件中使用库的jar类文件来通过Java编译器构建新的类文件.然后,您需要Java Card Converter的一些额外信息,以将您的代码与库类及其方法相关联.这就是exp文件的用途.该exp文件描述了文件中所有公共组件的接口和依赖关系cap.Eclipse JCOP Tools将exp文件与文件一起创建cap在同一文件夹中,以及Java Card Converter.(参见Oracle的文档)
该exp文件与jar文件是所有你需要建立你的代码,使用该库.只需将它们放入项目中,并确保jar文件位于项目的构建路径中.
随意问.