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

Started by
1 comment, last by princec 16 years, 1 month ago
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
 {
   System.loadLibrary("populationLib");
 }
        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. 

//C header stub created
//**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.<clinit>(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...
heh
Advertisement
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)
SHPOpen is referenced from your own library; the OS library loader attempts to dynamically load and link it at load time.

Cas :)

This topic is closed to new replies.

Advertisement