0

I tried to build a native wrapper DLL, in order to access the third party DLL from java. At running my Java programs, it throws an Unsatisfied Link Exception.

Exception in thread "main" java.lang.UnsatisfiedLinkError: C:\Users\sstankov\workspace\CalculatorWrapper\src\CalculatorControllerWrapper.dll: Can't find dependent libraries
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(Unknown Source)
at java.lang.ClassLoader.loadLibrary(Unknown Source)
at java.lang.Runtime.loadLibrary0(Unknown Source)
at java.lang.System.loadLibrary(Unknown Source)
at CalculatorController.<clinit>(CalculatorController.java:9)

I looked already through endless SOF Posts about the same Problem, sadly nothing helped.

Here is my Code, It should gain you some insight I think.

Header of the "3d-party-dll", which I created and named TestHelloWorld:

#include <iostream>
using namespace std;

namespace Calc {

    class CalculatorSasa
    {
    public:
        static __declspec(dllexport) int multipliziere(int a, int b);
        static __declspec(dllexport) int addiere(int a, int b);
        static __declspec(dllexport) int subtrahiere(int a, int b);
    };


}

CPP - File of the 3rd- Party DLL

#include "TestHelloWorld.h"
#include <iostream>
using namespace std;

namespace Calc{

    int CalculatorSasa::addiere(int a, int b) {
        cout << "a = " << a << ", b = " << b << endl;
        int c = a + b;
        cout << "\Ergebnis Addieren = " << c << endl;
        return c;
    }

    int CalculatorSasa::multipliziere(int a, int b) {
        cout << "a = " << a << ", b = " << b << endl;
        int c = a * b;
        cout << "\Ergebnis Multiplizieren = " << c << endl;
        return c;
    }

    int CalculatorSasa::subtrahiere(int a, int b) {
        cout << "a = " << a << ", b = " << b << endl;
        int c = a - b;
        cout << "\Ergebnis Subtrahieren = " << c << endl;
        return c;
    }

}


int main()
{
    return 0;
}

CalculatorController.java -> Java-Code

public class CalculatorController {

    public static native int add(int a, int b);
    public static native int subtract(int a, int b);
    public static native int multipliziere(int a, int b);

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


    public static void main(String[] args) {
        /* This message will help you determine whether
        LD_LIBRARY_PATH is correctly set
         */
        System.out.println("library: "
                + System.getProperty("java.library.path"));

        CalculatorController.add(10, 20);
        CalculatorController.subtract(50, 15);
        CalculatorController.multipliziere(10, 10);


    }

}

Native Header created of my Java class

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class CalculatorController */

#ifndef _Included_CalculatorController
#define _Included_CalculatorController
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     CalculatorController
 * Method:    add
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_CalculatorController_add
  (JNIEnv *, jclass, jint, jint);

/*
 * Class:     CalculatorController
 * Method:    subtract
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_CalculatorController_subtract
  (JNIEnv *, jclass, jint, jint);

/*
 * Class:     CalculatorController
 * Method:    multipliziere
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_CalculatorController_multipliziere
  (JNIEnv *, jclass, jint, jint);

#ifdef __cplusplus
}
#endif
#endif

C++ Implementation of native Header

#pragma comment(lib, "Calculator.lib")

#include "CalculatorController.h"
#include "TestHelloWorld.h"
#include <iostream>

/*
 * Class:     CalculatorController
 * Method:    add
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_CalculatorController_add(JNIEnv *env, jclass cls, jint num1, jint num2) {
    int sum = Calc::CalculatorSasa::addiere(num1, num2);
    return sum;
}

/*
 * Class:     CalculatorController
 * Method:    subtract
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_CalculatorController_subtract(JNIEnv *env, jclass cls, jint num1, jint num2) {
    int sum = Calc::CalculatorSasa::subtrahiere(num1, num2);
    return sum;
}

/*
 * Class:     CalculatorController
 * Method:    multipliziere
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_CalculatorController_multipliziere(JNIEnv *env, jclass cls, jint num1, jint num2) {
    int sum = Calc::CalculatorSasa::multipliziere(num1, num2);
    return sum;
}

I think that maybe I have somewhere a Building and/or compilation error. I am fairly new to C++ as I am a pure Java developer and got this Task from work.

Here is also a Picture of my src Folder, blue describes java/jni related files, red the "3rd party dll": blue describes java/jni related files, red the "3rd party dll"

Thanks in advance!

Alan Birtles
  • 32,622
  • 4
  • 31
  • 60
s.stkvc
  • 127
  • 1
  • 2
  • 12
  • 3
    try running [dependancy walker](https://lucasg.github.io/Dependencies/) on your wrapper dll to see what the dependencies are and which ones are missing. – Alan Birtles Aug 21 '19 at 11:49
  • 1
    Make sure all the libs you are linking to are on `PATH`. They must be resolvable by system. – Oo.oO Aug 21 '19 at 12:50
  • See also: https://stackoverflow.com/questions/47031176/java-loadlibrary-unresolved-dependency-but-dependent-dll-is-in-same-directory/47075532#47075532 – user2543253 Aug 21 '19 at 15:22
  • The dependency walker like [depends](http://www.dependencywalker.com/) is your best bet. I think Java is finding your dll, but the dll cannot be loaded due to another dll not being in the systems library path. After looking at your source, I am not sure what dll that would be, maybe something related to your tool chain. Remember that Java does **NOT** look in the `PATH` for native libraries! It also does **NOT** use the class path. It uses the `java.library.path` run-time property. – Alex Barker Aug 23 '19 at 17:28

0 Answers0