0

我正在開發一個JavaFX應用程序,用於使用eToken Pro對pdf進行簽名。標誌方法在普通的Java項目中運行得很完美。而在JavaFX應用程序運行時,它不斷遇到例外情況是這樣的:JavaFX應用程序:找不到SunPKCS11類

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; 
} 

在你們回答之前,我想強調一下,我在一個普通的Java項目中完全引用了Signer類。所以我不認爲這是一個32位或64位的問題。此外,我正在使用32位JDK 1.7

+0

SunPKCS11罐子是不是在你的類路徑JavaFX項目可用。建議您仔細閱讀此內容 - http://javareferencegv.blogspot.com/2013/10/debugging-javalangnoclassdeffounderror.html –

+0

請參閱參考資料。我還嘗試將SunPKCS11 jar文件放入Java類路徑中。這些都不起作用。 奇怪的是,我把確切的源代碼放入一個ec(fx)lipse項目中,並且它確實有效。 仍然令人困惑。但我認爲你可能是對的。 NetBeans的javafx配置有問題,而不是java。 –

+0

任何人想評論?謝謝 –

回答

0

此問題可能是因爲不支持的java.Do的版本有一件事爲此下載了特定的jar文件,並將其包含在您的項目中它將爲您工作。

你可以從這個鏈接下載JAR - http://www.docjar.com/jar/sunpkcs11.jar