John S
John S

Reputation: 21

Exclusive access established by another Thread Java smartcardio

All,

I have appreciated many helpful answers on this site but I have found a need to post my first question (if you notice anything to be improved in my post let me know).

I have a modest sized Java program with GUI that is acting as a "middleman" and controller. On one end of the information flow it sends and receives data via an HTTP server. On the other it is interacting with an API where data is ultimately exchanging with a SmartCard. In the "middle" is the GUI, logging, and some other features.

There is also a feature (initiated via the GUI) to occasionally load an update to the SmartCard. Otherwise exchanges with the SmartCard are initiated over HTTP.

The problem is when switching between these 2 modes (communicating http to smartcard and then switching to loading the update or vice versa).

When I do that I have concluded I run into the problem of

CardException: Exclusive access established by another Thread

as thrown by sun.security.smartcardio

Searching the web shows the code that exception appears to come from is

void checkExclusive() throws CardException {
        Thread t = exclusiveThread;
          if (t == null) {
                return;
            }
             if (t != Thread.currentThread()) {
            throw new CardException("Exclusive access established by another Thread");
        }
    }

My first thought was I needed to instantiate the SmartCard API each time I need it (and then set it back to null) instead of once for the entire program like I had initially.

This works for the exchanges over http and I figure it is because each request to the handle() method is a new thread.

In the GUI the update is initiated by an ActionEvent which makes an instance of a CardUpdate. Inside that class then gets an instance of the SmartCard API.

I thought maybe I'd have better luck if when actionPerformed triggered I put the actions on a different, temporary, thread. So far, no.

The closest I got was using something like:

SwingWorker worker = new SwingWorker<ImageIcon[], Void>() {

as found at on Sun's website

Using that I could do an update and then go back to http exchanges but I couldn't do another update (per the one time use stipulation of SwingWorker)

I then tried making multiple SwingWorker as needed doing something like

private class GUICardUpdate extends SwingWorker<Integer, Void > {

but then I was back to my original problem. I have also tried to just do a simple additional thread off the GUI class in this fashion:

public class GUI extends javax.swing.JFrame implements ActionListener, Runnable

but this is no different.

Maybe I don't understand threads well enough or maybe I am overlooking something simple. Anyone have any ideas?

Thanks!

Upvotes: 2

Views: 1293

Answers (1)

Serge
Serge

Reputation: 6095

As far as I got you are using javax.smartcardio package (directly or indirectly) to work with your card. Some thread (created by you or by the framework you are probably using on top of javax.smartcardio) invoked beginExclusive() method on the Card instance to ensure exclusive access to the card.

The exclusive access is necessary as treatment of the data kept on the IC cards is state-depended, so the proper selection of data files and reading of their records requires the actions of application layer not to be interfered with actions of some other application or thread. For this purpose these three Card interface methods beginExclusive(), endExclusive() and checkExclusive() exist.

So you should check your(framework) code if it calls beginExclusive() and then doesn't call endExclusive().

Upvotes: 1

Related Questions