Search code examples
javaintellij-ideajava-native-interfaceunsatisfiedlinkerror.so

UnsatisfiedLinkError after moving the code into a package


I'm working on a project that needs to use .so library(ubuntu 18.04), everything works well when I put my java code in the /src folder(I'm using the IntelliJ Idea), but after I move my code into a named package(smutil), it causes some error like "Exception in thread "main" java.lang.UnsatisfiedLinkError: smutil.GmSSL.digest(Ljava/lang/String;[B)[B"

Here's my code

package smutil;
public class GmSSL {

public native String[] getVersions();
public native String[] getCiphers();
public native String[] getDigests();
public native String[] getMacs();
public native String[] getSignAlgorithms();
public native String[] getPublicKeyEncryptions();
public native String[] getDeriveKeyAlgorithms();
public native byte[] generateRandom(int length);
public native int getCipherIVLength(String cipher);
public native int getCipherKeyLength(String cipher);
public native int getCipherBlockSize(String cipher);
public native byte[] symmetricEncrypt(String cipher, byte[] in, byte[] key, byte[] iv);
public native byte[] symmetricDecrypt(String cipher, byte[] in, byte[] key, byte[] iv);
public native int getDigestLength(String digest);
public native int getDigestBlockSize(String digest);
public native byte[] digest(String algor, byte[] data);
public native String[] getMacLength(String algor);
public native byte[] mac(String algor, byte[] data, byte[] key);
public native byte[] sign(String algor, byte[] data, byte[] privateKey);
public native int verify(String algor, byte[] digest, byte[] signature, byte[] publicKey);
public native byte[] publicKeyEncrypt(String algor, byte[] in, byte[] publicKey);
public native byte[] publicKeyDecrypt(String algor, byte[] in, byte[] privateKey);
public native byte[] deriveKey(String algor, int keyLength, byte[] peerPublicKey, byte[] privateKey);
public native String[] getErrorStrings();

static {
    System.loadLibrary("gmssljni");
}
}

Solution

  • You probably pack your .so file inside JAR. Note that once you have your .so there, it's not that easy to load library.

    In order to load shared lib, you have to make sure it's on file system. You can overcome this issue by extracting it to temporary location.

    Take a look here for a full sample illustrating this topic:

    https://github.com/mkowsiak/jnicookbook/tree/master/recipes/recipeNo031

    Basically, what you have to do is:

    • locate your resource inside JAR
    • extract it to temporary location
    • user System.load(fullPathToFile)

    That's it :)

    Have fun with JNI!