8

I want to package GDAL and its JAVA binding into a SWT plug-in. (P.S. GDAL use swig to generate Java binding)

I have all necessary native libraries and want to pack them into my Eclipse plug-in to let other people use it without installing GDAL on their computer.

The problem is that the JAVA Binding (or native lib itself) will lookup necessary native libraries from PATH (Window) or LD_LIBRARY_PATH (Linux) instead looking up those libs in a relative location. Furthermore, GDAL will look up some necessary geo definition data from the environment variable GDAL_DATA as well.

How can I solve those two problems to make a portable SWT plug-in? 1) package platform specific native libs 2) some environment variable look-up

It seems that eclipse cannot resolve dependent libs without having PATH set. Bundle-NativeCode (see below) did not work.

If I try to directly call System.Library("SomethingNotExist") in my plugin; then I get

java.lang.UnsatisfiedLinkError: no SomethingNotExist in java.library.path

If I call System.Library("SomethingDoesExist") in my plugin, then I get

java.lang.UnsatisfiedLinkError: SomethingDoesExist.dll: Can't find dependent libraries

The file structure in my plug-in

org.gdal/
   + src/
   + nativelib/
      + linux32/
        + ...
      + linux32/
        + ...
      + win32/
        + ...
      + win64/
        + ...
   + META-INF
      + MANIFEST.MF
   + gdal-data/
   + gdal.jar
   + build.properties

The build.properties for this Plug-in

source.. = src/
output.. = bin/
bin.includes = META-INF/,\
               .,\
               gdal.jar,\
               gdal-data/,\
               nativelib/

The Manifest for this Plug-in

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: GDAL
Bundle-SymbolicName: org.gdal
Bundle-Version: 1.8.1
Bundle-NativeCode: 
 nativelib/linux32/libgdal.so;
 nativelib/linux32/libgdalconstjni.so;
 nativelib/linux32/libgdaljni.so;
 nativelib/linux32/libogrjni.so;
 nativelib/linux32/libosrjni.so;
 osname=Linux; processor=x86,
 nativelib/linux64/libgdal.so;
 nativelib/linux64/libgdalconstjni.so;
 nativelib/linux64/libgdaljni.so;
 nativelib/linux64/libogrjni.so;
 nativelib/linux64/libosrjni.so;
 osname=Linux; processor=x86_64,
 nativelib/win32/gdal18.dll;
 nativelib/win32/gdalconstjni.dll;
 nativelib/win32/gdaljni.dll;
 nativelib/win32/geos_c.dll;
 nativelib/win32/iconv.dll;
 nativelib/win32/libcurl.dll;
 nativelib/win32/libeay32.dll;
 nativelib/win32/libexpat.dll;
 nativelib/win32/libmysql.dll;
 nativelib/win32/libpq.dll;
 nativelib/win32/libxml2.dll;
 nativelib/win32/ogrjni.dll;
 nativelib/win32/openjpeg.dll;
 nativelib/win32/osrjni.dll;
 nativelib/win32/pdflib.dll;
 nativelib/win32/proj.dll;
 nativelib/win32/spatialite.dll;
 nativelib/win32/sqlite3.dll;
 nativelib/win32/ssleay32.dll;
 nativelib/win32/xerces-c_2_8.dll;
 nativelib/win32/zlib1.dll;
 osname=win32; processor=x86,
 nativelib/win64/ogrjni.dll;
 nativelib/win64/gdal18.dll;
 nativelib/win64/xerces-c_2_8.dll;
 nativelib/win64/libexpat.dll;
 nativelib/win64/libpq.dll;
 nativelib/win64/spatialite.dll;
 nativelib/win64/libmysql.dll;    
 nativelib/win64/geos_c.dll;
 nativelib/win64/libcurl.dll;
 nativelib/win64/openjpeg.dll; 
 nativelib/win64/iconv.dll; 
 nativelib/win64/libeay32.dll;
 nativelib/win64/gdaljni.dll;
 nativelib/win64/osrjni.dll; 
 nativelib/win64/gdalconstjni.dll; 
 nativelib/win64/libxml2.dll; 
 nativelib/win64/pdflib.dll;
 nativelib/win64/proj.dll;
 nativelib/win64/sqlite3.dll;
 nativelib/win64/ssleay32.dll;
 nativelib/win64/zlib1.dll; 
 osname=win32; processor=x86_64
Bundle-ClassPath: gdal.jar,
 .,
 gdal-data/
Export-Package: org.gdal,
 org.gdal.gdal,
 org.gdal.gdalconst,
 org.gdal.ogr,
 org.gdal.osr
Bundle-RequiredExecutionEnvironment: JavaSE-1.6

rnd_nr_gen
  • 2,203
  • 3
  • 36
  • 55
  • What exactly is the problem (what errors are reported by who)? OSGi will load your DLLs from your plugin according to `Bundle-NativeCode` section, so *JAVA Binding (or native lib itself) will lookup necessary native libraries from PATH* is not the case. – Martti Käärik Dec 27 '11 at 16:02
  • @Martti: really? I think the native code tries to load relevant libs from PATH and looks up some config data from other defined environment variable path. Error Message: [[Native library load failed. java.lang.UnsatisfiedLinkError: ogrjni.dll: Can't find dependent libraries]] – rnd_nr_gen Dec 28 '11 at 11:36
  • Yes, **native libs** are loading from PATH. The point I was trying to make is that this has nothing to do with Eclipse nor Java, but normal lib resolving of any program. – Martti Käärik Dec 28 '11 at 11:50
  • Yes, if I set PATH properly, it works (run as just a normal Java program)! But I can't set such PATH in a plug-in bundle and I dont' want users care about it. I just package all necessary libs in a plug-in, but it seems that eclipse (or OS) cannot resolve those libs without having PATH set. – rnd_nr_gen Dec 28 '11 at 13:22
  • 1
    Does it work if you load all necessary libs from Java code and won't rely on the "assembly resolver" of native code? – Martti Käärik Dec 28 '11 at 14:12
  • Do you mean System.loadLibrary()? doesn't it also depend on PATH? – rnd_nr_gen Dec 28 '11 at 16:06
  • `System.loadLibrary()` is where the `Bundle-NativeCode` section is used. – Martti Käärik Dec 28 '11 at 21:57
  • @Martti: I have tried it again. It seems that Bundle-NativeCode did not work for me. System.loadLibrary() cannot find the lib that I defined in MANIFEST. – rnd_nr_gen Dec 29 '11 at 10:02
  • You need to load the libs in order of dependency - first the ones that are independent and dependents after those. – Martti Käärik Dec 29 '11 at 10:56
  • you mean `Bundle-NativeCode: LibC; libB; LibA` if I have a dependency `LibA -dep-> LibB -dep-> LibC`? Actually in the Java Binding only JNI.dll is load from java. The other dependent libs seems to be loaded automatically via system. – rnd_nr_gen Dec 29 '11 at 18:10
  • 1
    No, I mean in the code: `System.loadLibrary("LibC"); System.loadLibrary("LibB"); System.loadLibrary("LibA");` – Martti Käärik Dec 29 '11 at 18:42
  • thanks I finally got your idea! – rnd_nr_gen Dec 30 '11 at 08:54

1 Answers1

1

For the environment issue of GDAL in Java

use gdal.SetConfigOption

http://osgeo-org.1560.n6.nabble.com/gdal-dev-GDAL-DATA-td3744017.html

To set GDAL_DATA with the folder which can be read from a plugin bundle.

http://www.vogella.de/blog/2010/07/06/reading-resources-from-plugin/

VasFou
  • 1,561
  • 1
  • 22
  • 39
rnd_nr_gen
  • 2,203
  • 3
  • 36
  • 55