JavaFX应用程序:找不到SunPKCS11类

时间:2014-02-12 07:21:57

标签: javafx noclassdeffounderror classnotfoundexception sun pkcs#11

我正在开发一个用于使用eToken Pro签署pdf的JavaFX应用程序。 sign方法在普通的Java项目中运行完美。当在JavaFX应用程序中运行时,它会遇到如下异常:

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 Project中完美地引用了Signer类。所以我不认为这是一个32位或64位的问题。另外,我使用的是32位JDK 1.7

1 个答案:

答案 0 :(得分:0)

这个问题可能是因为不受支持的java版本。有一件事情下载了特定的jar文件并将其包含在你的项目中它将为你工​​作。

您可以从此链接下载jar - http://www.docjar.com/jar/sunpkcs11.jar