I have looked through the UnsatisfiedLinkError helps in StackOverFlow and other search engines but the solutions have not satisfied the problem so I will state them here.
I am trying to make a JNI call to a PKCS11 DLL library and I am getting the following error:
Exception in thread "main" java.lang.UnsatisfiedLinkError: org.thotheolh.jche.NativeBridge.loadPKCS11Module(Ljava/lang/String;)V
at org.thotheolh.jche.NativeBridge.loadPKCS11Module(Native Method)
at org.thotheolh.jche.NativeBridge.load(NativeBridge.java:40)
at org.thotheolh.jche.NativeBridge.<init>(NativeBridge.java:29)
at org.thotheolh.jche.exception.test.PKCS11GenericTest.main(PKCS11GenericTest.java:27)
Java Result: 1
My native bridge snippet I used to do the 'native' calls below:
NativeBridge.java
public class NativeBridge {
private String pkcs11Module;
private String pkcs11JavaWrapper = "libJPKCS11";
public NativeBridge(String pkcs11Module) throws IOException, NoSuchFieldException {
this.pkcs11Module = pkcs11Module;
load();
}
public void load() throws IOException, NoSuchFieldException {
System.loadLibrary(pkcs11JavaWrapper);
loadPKCS11Module(pkcs11Module);
}
public synchronized native void loadPKCS11Module(String location) throws IOException;
}
javah generated Header File snippet:
JCHE.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class org_thotheolh_jche_NativeBridge */
#ifndef _Included_org_thotheolh_jche_NativeBridge
#define _Included_org_thotheolh_jche_NativeBridge
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: org_thotheolh_jche_NativeBridge
* Method: loadPKCS11Module
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_org_thotheolh_jche_NativeBridge_loadPKCS11Module
(JNIEnv *, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endif
C file snippet:
JCHE.c
#include <jni.h>
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include "JCHE.h"
const char *pkcs11ModuleFileLoc;
HMODULE pkcs11;
JNIEXPORT void JNICALL Java_org_thotheolh_jche_NativeBridge_loadPKCS11Module
(JNIEnv *env, jobject obj, jstring location) {
printf("inside native method\n");
pkcs11ModuleFileLoc = (*env)->GetStringUTFChars(env, location, (jboolean *)0);
printf("%s", pkcs11ModuleFileLoc);
//pkcs11 = LoadLibraryA(pkcs11ModuleFileLoc);
//printf("\nLoaded PKCS11 Lib");
}
I have attempted to check the loaded libraries in Java and found them already loaded but somehow I am getting the described error despite looking through many other methods available to try and remedy this problem.
Found a very old 2012 Netbeans post to solve the problem. It is due to a few GCC compiler options missing when making the DLL files.
Additional GCC Compiler Option:
-Wl,--export-all-symbols -Wl,--add-stdcall-alias
Reference: http://forums.netbeans.org/post-130319.html