用Java打包GDAL [英] Packaging GDAL with Java

查看:344
本文介绍了用Java打包GDAL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Java项目,该项目在Win7上使用GDAL绑定.问题是,由于绑定的性质,需要设置环境变量才能正常工作,尤其是PATHGDAL_DATAGDAL_DRIVER_PATHPROJ_LIB.我的意思是它们对我来说很容易创建并指向GDAL目录.但是,如果我想分发此文件,对于普通用户而言,这将是一个繁琐的步骤.

我需要某种方式来配置GDAL绑定,以便用户可以将其复制到具有jar和GDAL库的任意位置,并且引导代码将自动设置GDAL来查找相对于其当前值的那些变量位置.

现在,我尝试了以下操作(它使用了一个非常类似的问题所提出的解决方案的一部分:

但是它在第一个SetConfigOption()中失败,并显示以下错误:

Native library load failed.
java.lang.UnsatisfiedLinkError: C:\...\gdal\gdaljni.dll: Can't find dependent libraries

这至少意味着第一部分可以正常工作,因为它可以正确定位gdaljni.dll,但是似乎在SetConfigOption()能够执行其工作之前,它已经在尝试查找这些路径,以进行初始化和失败.

现在,如果我手动设置环境变量,显然,它运行良好.

GDAL绑定来自: http://www.gisinternals.com/

我很抱歉没有提供Windows特定的答案,但是类似Unix和Windows系统的概念在本质上是相同的.您遇到的错误是由于库路径(在Windows中仍为二进制dll)不属于必需路径的缘故. GDAL配置设置不管理到DLL的路由,而是管理内部数据的位置.

这可能不是最好的解决方案,但是在过去对我来说效果很好.关键是创建一个脚本,该脚本更新启动应用程序所需的路径.

在脚本中,您需要...

  1. 获取脚本本身的目录,以便您可以从系统上的任何位置启动应用程序.
  2. 在适当的环境变量中添加到库的路径.使用SCRIPT_PATH作为路径的基础.
  3. 更新DYLD_LIBRARY_PATH(Mac),LD_LIBRARY_PATH(Linux),如果我还记得,请更新PATH(Windows).
  4. 像使用SCRIPT_PATH变量作为基础导出库路径一样启动应用程序.

这里是一个示例,其中我没有在Mac上的clang中设置rpath.

  • 包装

    • bin/foo
    • lib/libtest.dylib
    • run.sh

运行脚本

#!/bin/sh

#  Get the directory of this script being run
SCRIPT_PATH="`dirname ${BASH_SOURCE[0]}`"

# Export the Path
export DYLD_LIBRARY_PATH=$SCRIPT_PATH/lib:$DYLD_LIBRARY_PATH

#  Run the executable
$SCRIPT_PATH/bin/foo

I have a Java project that uses GDAL bindings on Win7. The problem is that due to the nature of the bindings, it requires setting environment variables to work, specially PATH, GDAL_DATA, GDAL_DRIVER_PATH, and PROJ_LIB. I mean they're easy enough for me to create and point to the GDAL directory. However if I ever want to distribute this, this is going to be an unwieldy step for the average user.

I need some way to configure the GDAL bindings in a way that the user can copy the program wherever they like, which has the jar and GDAL libraries, and the bootstrap code will automatically set GDAL to find those variables relative to it's current location.

Now I tried the following (which uses part of a solution posed in a very similar question: package GDAL JAVA Binding and native library in a SWT plugin):

// define `root` before to grab the path of the where the JAR is located
// bit of a hack-y way to set the classpath
System.setProperty("java.library.path", root+"gdal");
Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths");
fieldSysPath.setAccessible(true);
fieldSysPath.set(null, null);
// set these gdal config variables programatically
gdal.SetConfigOption("GDAL", root + "gdal");
gdal.SetConfigOption("GDAL_DATA", root + "gdal\\gdal_data");
gdal.SetConfigOption("GDAL_DRIVER_PATH", root + "gdal\\gdalplugins");
gdal.SetConfigOption("PROJ_LIB", root + "gdal\\proj_lib");

But it fails in the first SetConfigOption() with the following error:

Native library load failed.
java.lang.UnsatisfiedLinkError: C:\...\gdal\gdaljni.dll: Can't find dependent libraries

Which means at least the first part is working because it properly locates gdaljni.dll, but seems like before the SetConfigOption() can do its thing, it's already trying to look into these paths just to initialize and failing.

Now if I set the environmental variables manually, obviously, it runs fine.

GDAL bindings from: http://www.gisinternals.com/

解决方案

I apologize for not providing a Windows-specific answer, however the concepts between Unix-like and Windows systems here are fundamentally the same. The error you are having is due to the library path (in Windows, still the binary dll) not being part of the required paths. The GDAL config settings don't manage the route to the DLL, but rather locations to internal data.

This may not be the best solution, however this has worked very well for me in the past. The key is to create a script which updates the path required to start the application.

Inside the script, you need to ...

  1. Get the directory of the script itself so you can start the application from anywhere on the system.
  2. Add the path to your library inside the proper environment variable. Use the SCRIPT_PATH as the base of the path.
  3. Update DYLD_LIBRARY_PATH (Mac), LD_LIBRARY_PATH (Linux), and if I remember, PATH (Windows).
  4. Start the application like you exported the library path using the SCRIPT_PATH variable as the base.

Here is an example where I did not set the rpath in clang on my Mac.

  • package

    • bin/foo
    • lib/libtest.dylib
    • run.sh

Run script

#!/bin/sh

#  Get the directory of this script being run
SCRIPT_PATH="`dirname ${BASH_SOURCE[0]}`"

# Export the Path
export DYLD_LIBRARY_PATH=$SCRIPT_PATH/lib:$DYLD_LIBRARY_PATH

#  Run the executable
$SCRIPT_PATH/bin/foo

这篇关于用Java打包GDAL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆