JDK 7u79中javax.smartcardio.Card.disconnect(boolean reset)的行为?

根据JRE 7u72的发行说明 :

更改javax.smartcardio.Card.disconnect(boolean reset)方法行为

在JDK 8u20和JDK 7u72版本之前,javax.smartcardio.Card.disconnect(boolean reset)方法对传递给它的’reset’布尔值具有反转逻辑。 如果错误传递给卡,则会在断开连接时重置该卡,反之亦然。 从JDK 7u72和JDK 8u20开始,已经实现了根据API文档的正确行为。

为了向依赖旧行为的用户提供向后兼容性,引入了新的系统属性。 以下命令行选项可用于强制执行旧的损坏行为:

-Dsun.security.smartcardio.invertCardReset =真

默认情况下,此属性设置为7u72及更高版本的JDK 7更新版本。 默认情况下,JDK 7更新版本在此区域中不会发现任何行为更改。

此外,以下命令行选项可用于强制执行新的正确行为:

-Dsun.security.smartcardio.invertCardReset = FALSE

这是8u20及更高版本JDK 8更新版本的默认设置。 在将来的Java版本中,将忽略/禁用该属性,并且默认的disconnect方法行为将由API指定。

当调用javax.smartcardio.Card.disconnect(true) ,即使我有JDK 7u79,卡也不会重置。 当我传递false或使用选项-Dsun.security.smartcardio.invertCardReset=true到VM时,一切正常。 怎么会这样? JDK 7u79附带了旧版本的JRE吗?

在我看来,JRE表现得像预期的那样。

拥有版本> 7u72的Java 7 JRE,您必须调用disconnect(false)来重置(默认情况下。这可能会被您提到的系统属性覆盖)。 原因在于,您必须调用断开连接(false)以实际断开连接的错误已经过时且已知,因此很多软件采用并调用disconnect(false)来重置。 如果Oracle在一些次要的发布/错误修复中改变了这种行为,他们就会为所有软件项目创建安全漏洞,他们通过调用disconnect(false)修复了代码中的JRE / JDK错误。 为此原因:

默认情况下,JDK 7更新版本在此区域中不会发现任何行为更改。

(这是您从文档中引用的内容的一部分)

如果你有一些Java 8 JRE,你必须默认调用disconnect(true),可能被系统属性覆盖。

所以,如果你现在想要创建一些代码,确保你的卡将被重置,这适用于java 7和8(甚至更老和更新版本),你必须评估,你必须提交什么,即:

 final static boolean TRUE; static{ String ven = System.getProperty("java.vendor"); String ver = System.getProperty("java.runtime.version"); String r = System.getProperty("sun.security.smartcardio.invertCardReset"); TRUE=!invertReset(ven, ver, r); } static boolean invertReset(String vendor, String version, String reset){ if("Oracle Corporation".equals(vendor)){ String[] javaVersionElements = version.split("\\.|_|-b"); //String discard = javaVersionElements[0]; int major = Integer.parseInt(javaVersionElements[1]); //String minor = javaVersionElements[2]; int update = Integer.parseInt(javaVersionElements[3]); //String build = javaVersionElements[4]; // version to small for existing reset property: if((major == 7 && update<72) || major < 7){ return true; } if(null != reset){ // version recent enough and we have property: return "true".equals(reset); }else{ // version recent enough, but no property: return major<8; } } return false; } 

现在,你可以拨打card.disconnect(TRUE); 如果需要,则TRUE应为false。 请在使用前仔细测试。 我没有。

请注意,我在运行时从SO文章获取Java版本中获取了版本检测/拆分代码