Problem description:
====================
Method "public abstract javax.smartcardio.CardTerminal.connect(String protocol)" of Sun's implementation of "PC/SC" smartcard reader I/O engine works wrong on Linux. In case when card is absent in card reader this method throws CardException instead of CardNotPresentException, in the same time method "javax.smartcardio.CardTerminal.isCardPresent()" works properly - it returns "false".
This bug is specific for Linux only, it is absent on Windows.
Test system description:
SuSE 10.0 out of box on Intel Pentium IV;
GemPCTwin (serial version) smartcard reader.
PC/SC framework and drivers from GemPlus site (SuSE package):
http://support.gemplus.com/gemdownload/readers/drivers.aspx?prodid=13&osid=11
There is a minimized test below:
Minimized test:
===============
---test.java---
import javax.smartcardio.*;
public class test {
public static void main(String[] args) {
CardTerminals terminals = TerminalFactory.getDefault().terminals();
try {
if (!terminals.list().isEmpty()) {
CardTerminal terminal = terminals.list().get(0);
if(!terminal.isCardPresent()) {
System.out.println("CardTerminal.isCardPresent():"
+ terminal.isCardPresent());
try {
Card card = terminal.connect("*");
} catch (CardNotPresentException e) {
System.out.println("Bug is absent: " + e);
} catch(CardException e) {
e.printStackTrace();
}
} else {
System.out.println("Bug cannot be reproduced: Card is"
+ " present");
}
} else {
System.out.println("Bug cannot be reproduced:There are no"
+ " any card terminals");
}
} catch(CardException e) {
}
}
}
---test.java---
Minimized test output:
======================
[vs158239@vsmelov bug]$ javac test.java
[vs158239@vsmelov bug]$ java -cp ./ test
CardTerminal.isCardPresent():false
javax.smartcardio.CardException: connect() failed
at sun.security.smartcardio.TerminalImpl.connect(TerminalImpl.java:67)
at test.main(test.java:14)
Caused by: sun.security.smartcardio.PCSCException: SCARD_E_NO_SMARTCARD
at sun.security.smartcardio.PCSC.SCardConnect(Native Method)
at sun.security.smartcardio.CardImpl.<init>(CardImpl.java:65)
at sun.security.smartcardio.TerminalImpl.connect(TerminalImpl.java:61)
... 1 more