JDK-6474807 : (smartcardio) CardTerminal.connect() throws CardException instead of CardNotPresentException
  • Type: Bug
  • Component: security-libs
  • Sub-Component: javax.smartcardio
  • Affected Version: 6
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2006-09-25
  • Updated: 2017-11-29
  • Resolved: 2016-08-30
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7 JDK 8 JDK 9 Other
6u141Fixed 7u131Fixed 8u131Fixed 9 b135Fixed openjdk7uFixed
Description
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

Comments
This is a conformance issue, the following testcase will fail due to this api/javax_smartcardio/CardTerminal/index.html#Exceptions[CNPE2001]
19-08-2016

Please assign someone to look into this conformance issue.
09-06-2016