JavaFX应用程序:找不到SunPKCS11类
我正在开发一个JavaFX应用程序,用于使用eToken Pro签署pdf。sign方法在普通Java项目中运行良好。在JavaFX应用程序中运行时,它会不断遇到如下异常:JavaFX应用程序:找不到SunPKCS11类,javafx,noclassdeffounderror,classnotfoundexception,sun,pkcs#11,Javafx,Noclassdeffounderror,Classnotfoundexception,Sun,Pkcs#11,我正在开发一个JavaFX应用程序,用于使用eToken Pro签署pdf。sign方法在普通Java项目中运行良好。在JavaFX应用程序中运行时,它会不断遇到如下异常: Exception in Application start method java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.ref
Exception in Application start method
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.javafx.main.Main.launchApp(Main.java:698)
at com.javafx.main.Main.main(Main.java:871)
Caused by: java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:403)
at com.sun.javafx.application.LauncherImpl.access$000(LauncherImpl.java:47)
at com.sun.javafx.application.LauncherImpl$1.run(LauncherImpl.java:115)
at java.lang.Thread.run(Thread.java:744)
Caused by: java.lang.NoClassDefFoundError: sun/security/pkcs11/SunPKCS11
at javafxapplication3.JavaFXApplication3.start(JavaFXApplication3.java:21)
at com.sun.javafx.application.LauncherImpl$5.run(LauncherImpl.java:319)
at com.sun.javafx.application.PlatformImpl$5.run(PlatformImpl.java:216)
at com.sun.javafx.application.PlatformImpl$4$1.run(PlatformImpl.java:179)
at com.sun.javafx.application.PlatformImpl$4$1.run(PlatformImpl.java:176)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl$4.run(PlatformImpl.java:176)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:76)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$100(WinApplication.java:17)
at com.sun.glass.ui.win.WinApplication$3$1.run(WinApplication.java:67)
... 1 more
Caused by: java.lang.ClassNotFoundException: sun.security.pkcs11.SunPKCS11
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
... 12 more
Java Result: 1
我用于签署pdf的代码如下:
@Override
public void start(Stage primaryStage) {
Signer signer = new Signer(new File("C:/Users/Adam/Desktop/pdf/hello.pdf"));
signer.signWithToken(true);
}
public class Signer {
// define the file to be signed
private final File file;
private static String smartcardDllPath;
private static int level;
private static String reason;
private static String src;
private static String dest;
private static String location;
private static Collection<CrlClient> crlList;
private static OcspClient ocspClient;
private static TSAClient tsaClient;
private static final String DLL = "C:/Windows/System32/eTPKCS11.dll";
public Signer(File theFile) {
location = "HK SAR";
smartcardDllPath = null;
file = theFile;
}
public void signWithToken(boolean certified) {
try {
String config = "name=eToken\nlibrary=" + DLL + "\nslotListIndex=" + getSlotsWithTokens(DLL)[0];
ByteArrayInputStream bais = new ByteArrayInputStream(config.getBytes());
Provider providerPKCS11 = new SunPKCS11(bais);
Security.addProvider(providerPKCS11);
configureParameters(certified);
// create PdfSignatureAppearance
PdfSignatureAppearance appearance = getPdfSigAppearance();
// configure the keystore, alias, private key and certificate chain
char[] pin = "love4Sakura".toCharArray();
KeyStore ks = KeyStore.getInstance("PKCS11");
ks.load(null, pin);
String alias = (String) ks.aliases().nextElement();
PrivateKey pk = (PrivateKey) ks.getKey(alias, null);
Certificate[] chain = ks.getCertificateChain(alias);
printChainInfo(chain);
// configure the CRL, OCSP and TSA
configCrlOcspTsa(chain);
// create the signature
ExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256, "SunPKCS11-eToken");
ExternalDigest digest = new BouncyCastleDigest();
MakeSignature.signDetached(appearance, digest, pks, chain, crlList, ocspClient,
tsaClient, 0, MakeSignature.CryptoStandard.CMS);
} catch (IOException | DocumentException | GeneralSecurityException ex) {
Logger.getLogger(Signer.class.getName()).log(Level.SEVERE, null, ex);
}
}
private static long[] getSlotsWithTokens(String libraryPath) {
CK_C_INITIALIZE_ARGS initArgs = new CK_C_INITIALIZE_ARGS();
String functionList = "C_GetFunctionList";
initArgs.flags = 0;
PKCS11 tmpPKCS11 = null;
long[] slotList = null;
try {
try {
tmpPKCS11 = PKCS11.getInstance(libraryPath, functionList, initArgs, false);
System.out.println(tmpPKCS11.toString());
} catch (IOException ex) {
try {
throw ex;
} catch (IOException ex1) {
Logger.getLogger(Signer.class.getName()).log(Level.SEVERE, null, ex1);
}
}
} catch (PKCS11Exception e) {
try {
initArgs = null;
tmpPKCS11 = PKCS11.getInstance(libraryPath, functionList, initArgs, true);
} catch (IOException | PKCS11Exception ex) {
}
}
try {
slotList = tmpPKCS11.C_GetSlotList(true);
for (long slot : slotList) {
CK_TOKEN_INFO tokenInfo = tmpPKCS11.C_GetTokenInfo(slot);
System.out.println("slot: " + slot + "\nmanufacturerID: "
+ String.valueOf(tokenInfo.manufacturerID) + "\nmodel: "
+ String.valueOf(tokenInfo.model));
}
} catch (PKCS11Exception ex) {
Logger.getLogger(Signer.class.getName()).log(Level.SEVERE, null, ex);
}
return slotList;
}
类别签名人的代码如下:
@Override
public void start(Stage primaryStage) {
Signer signer = new Signer(new File("C:/Users/Adam/Desktop/pdf/hello.pdf"));
signer.signWithToken(true);
}
public class Signer {
// define the file to be signed
private final File file;
private static String smartcardDllPath;
private static int level;
private static String reason;
private static String src;
private static String dest;
private static String location;
private static Collection<CrlClient> crlList;
private static OcspClient ocspClient;
private static TSAClient tsaClient;
private static final String DLL = "C:/Windows/System32/eTPKCS11.dll";
public Signer(File theFile) {
location = "HK SAR";
smartcardDllPath = null;
file = theFile;
}
public void signWithToken(boolean certified) {
try {
String config = "name=eToken\nlibrary=" + DLL + "\nslotListIndex=" + getSlotsWithTokens(DLL)[0];
ByteArrayInputStream bais = new ByteArrayInputStream(config.getBytes());
Provider providerPKCS11 = new SunPKCS11(bais);
Security.addProvider(providerPKCS11);
configureParameters(certified);
// create PdfSignatureAppearance
PdfSignatureAppearance appearance = getPdfSigAppearance();
// configure the keystore, alias, private key and certificate chain
char[] pin = "love4Sakura".toCharArray();
KeyStore ks = KeyStore.getInstance("PKCS11");
ks.load(null, pin);
String alias = (String) ks.aliases().nextElement();
PrivateKey pk = (PrivateKey) ks.getKey(alias, null);
Certificate[] chain = ks.getCertificateChain(alias);
printChainInfo(chain);
// configure the CRL, OCSP and TSA
configCrlOcspTsa(chain);
// create the signature
ExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256, "SunPKCS11-eToken");
ExternalDigest digest = new BouncyCastleDigest();
MakeSignature.signDetached(appearance, digest, pks, chain, crlList, ocspClient,
tsaClient, 0, MakeSignature.CryptoStandard.CMS);
} catch (IOException | DocumentException | GeneralSecurityException ex) {
Logger.getLogger(Signer.class.getName()).log(Level.SEVERE, null, ex);
}
}
private static long[] getSlotsWithTokens(String libraryPath) {
CK_C_INITIALIZE_ARGS initArgs = new CK_C_INITIALIZE_ARGS();
String functionList = "C_GetFunctionList";
initArgs.flags = 0;
PKCS11 tmpPKCS11 = null;
long[] slotList = null;
try {
try {
tmpPKCS11 = PKCS11.getInstance(libraryPath, functionList, initArgs, false);
System.out.println(tmpPKCS11.toString());
} catch (IOException ex) {
try {
throw ex;
} catch (IOException ex1) {
Logger.getLogger(Signer.class.getName()).log(Level.SEVERE, null, ex1);
}
}
} catch (PKCS11Exception e) {
try {
initArgs = null;
tmpPKCS11 = PKCS11.getInstance(libraryPath, functionList, initArgs, true);
} catch (IOException | PKCS11Exception ex) {
}
}
try {
slotList = tmpPKCS11.C_GetSlotList(true);
for (long slot : slotList) {
CK_TOKEN_INFO tokenInfo = tmpPKCS11.C_GetTokenInfo(slot);
System.out.println("slot: " + slot + "\nmanufacturerID: "
+ String.valueOf(tokenInfo.manufacturerID) + "\nmodel: "
+ String.valueOf(tokenInfo.model));
}
} catch (PKCS11Exception ex) {
Logger.getLogger(Signer.class.getName()).log(Level.SEVERE, null, ex);
}
return slotList;
}
在你们回答之前:我想强调的是,我在一个普通的Java项目中引用了Signer类。所以我不认为这是32位或64位的问题。另外,我使用的是32位JDK1.7,这个问题可能是因为java版本不受支持。做一件事下载特定的jar文件,并将其包含在您的项目中,它会为您工作 您可以从这个链接下载jar-
SunPKCS11 jar在JavaFX项目的类路径中不可用。建议你看一下这个-看一下参考资料。我还尝试将SUNPKCS11JAR文件放入Java类路径。这两种方法都不管用。奇怪的是,我把确切的源代码放进了一个ecfxlipse项目中,并且它确实起了作用。仍然令人困惑。但我认为你可能是对的。netbeans的javafx配置有问题,不是java。有人想评论吗?谢谢