方法を見つけましたが、リフレクティブ コードを使用しています。よりクリーンな方法を見つけたいのですが、スマート カード コンテキストを管理する公式の API はないようです。すべてのクラスはプライベートです。
( http://www.docjar.com/html/api/sun/security/smartcardio/PCSCTerminals.java.html )のinitContext()
メソッドは 、最初のスレッドが初期化された後に新しいスレッドが新しいコンテキストを取得するのを防ぎます: メソッドが呼び出され、ただし、コンテキストはシングルトンと見なされ、再初期化されません。sun.security.smartcardio.PCSCTerminals
private
を使用してこの周りのすべてを通過するjava.lang.reflect
と、新しいコンテキストの作成を強制し、その新しい ID を「公式」として保存することができますcontextId
。これは、新しい をインスタンス化する前に行う必要がありますTerminalFactory
。
// ...
Class pcscterminal = Class.forName("sun.security.smartcardio.PCSCTerminals");
Field contextId = pcscterminal.getDeclaredField("contextId");
contextId.setAccessible(true);
if(contextId.getLong(pcscterminal) != 0L)
{
Class pcsc = Class.forName("sun.security.smartcardio.PCSC");
Method SCardEstablishContext = pcsc.getDeclaredMethod(
"SCardEstablishContext",
new Class[] {Integer.TYPE }
);
SCardEstablishContext.setAccessible(true);
Field SCARD_SCOPE_USER = pcsc.getDeclaredField("SCARD_SCOPE_USER");
SCARD_SCOPE_USER.setAccessible(true);
long newId = ((Long)SCardEstablishContext.invoke(pcsc,
new Object[] { Integer.valueOf(SCARD_SCOPE_USER.getInt(pcsc)) }
)).longValue();
contextId.setLong(pcscterminal, newId);
}
// ...