# [java] Java and 3rd party DLL's, using JNI

## Recommended Posts

OpenGL_Guru    104
i am having trouble with a java error that i am unsure where it is coming from. basically i have created a JNI stub(a C header file) that i can use to build my C++ source file with. in my C++ code i need to access a C Library with functions that i have tried to hide from the java end(to no avail) and wondering what i am doing wrong. //my .java file
public class HelloWorld
{
public HelloWorld() //constructor
{

}
public native double getPopulation(double w, double x, double y, double z);

static
{
}
public static void main(String[] args)
{
HelloWorld hello = new HelloWorld();
double value = hello.getPopulation(-89.3, 30.1, -89.6, 30.8);
System.out.println("value returned is: " + value);
}

}

now i use javac to compile and javah to create my C Header Stub.

//**note i had to add the shapefil.h header file myself because i want to use this to call the C Library Methods available through this. I also had to add a C++ function that i want to use to make these calls. (is this right??? )

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

#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class:     HelloWorld
* Method:    getPopulation
* Signature: (DDDD)D
*/
JNIEXPORT jdouble JNICALL Java_HelloWorld_getPopulation
(JNIEnv *, jobject, jdouble, jdouble, jdouble, jdouble);

double setPopulation(double, double, double, double);
#ifdef __cplusplus
}
#endif
#endif


//now my CPP file to match the header stub that was created. my idea was to call a C++ function from the native function, that will then call the functions needed in the C Library. but as you will see Java complains.(error at bottom).
#include <iostream>
#include "HelloWorld.h"

using namespace std;

JNIEXPORT double JNICALL Java_HelloWorld_getPopulation(JNIEnv *env, jobject obj, jdouble w, jdouble x,
jdouble y, jdouble z)

{
jdouble pop;
pop = setPopulation(w, x, y, z);
return (jfloat)pop;
}

double setPopulation(double x1, double y1, double x2, double y2)
{
SHPHandle mySHPhandle = NULL;
DBFHandle myDBFhandle = NULL;
SHPObject *mySHPobject = NULL;
DBFFieldType stuff;
int field_count;
int record_count;

mySHPhandle = SHPOpen("file1.shp", "rb");
//myDBFhandle = DBFOpen("file1.dbf", "rb");
//field_count = DBFGetFieldCount(myDBFhandle);
//record_count = DBFGetRecordCount(myDBFhandle);

return 10.0; //arbitrary number/cant return anything of use yet.
}


now i create the shared library: g++ -shared -I/include files needed -L/library files needed HelloWorld.cpp -o libpopulationLib.so --the library is created with no warnings or errors via g++. now we need to run Java. $java HelloWorld Quote:  Exception in thread "main" java.lang.UnsatisfiedLinkError: /home/user/work/iga/src/population/libpopulationLib.so: /home/user/work/iga/src/population/libpopulationLib.so: undefined symbol: SHPOpen at java.lang.ClassLoader$NativeLibrary.load(Native Method) at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1751) at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1676) at java.lang.Runtime.loadLibrary0(Runtime.java:823) at java.lang.System.loadLibrary(System.java:1030) at HelloWorld.(HelloWorld.java:35)
normally i would understand why java cannot see the library, as in my .java code i am not loading the C library nor am i wrapping any functions around the C Library to match the functions that i need. But in this case i am not using or dont want to use java to access the C Library. I want to use C++ to do this and this is what i am trying to do here. My question is why does java need to see the SHPOpen function? i am not using java to call the C functions that i need. any ideas or suggestions? questions? thanks a lot for your help in advance...

##### Share on other sites
mbien    133
Hi,

have you specified java -Djava.library.path="relative path to lib folder" MyApp ?

(i am no expert in JNI too, but this will probably solve the problem)

princec    312

Cas :)