我正在尝试使用JNLP启动Java应用程序;该应用程序包括第三方库(Lab Streaming Layer),它依赖于加载JNA的本机库 .
据我了解,我已经按照所有适当的步骤来完成这项工作:
-
所有本机库都在JAR文件中,由OS和体系结构分隔 .
-
所有本机库JAR文件都在服务器上,可从代码库URL访问 .
-
JNLP文件包含
<resources>
元素,其中os
和arch
指定了<nativelib>
元素,其中包含正确的href
属性 . -
JNLP文件格式错误并正常启动 .
当我去运行我的应用程序时,我得到报告"Unable to load library 'liblsl32.dylib': Can't obtain InputStream for darwin/liblsl32.dylib"的 java.lang.UnsatisifiedLinkError
. 这在程序启动后发生,第一次尝试使用具有本机lib依赖性的库 . 我通过将dylib放在正确的位置,使用单独的非Web启动应用程序更正了此 exact 错误 . 我还尝试将所有dylib重命名为jnilibs,根据以下信息:http://permalink.gmane.org/gmane.comp.java.jna.user/3328,但一切都发生了相同的情况 .
看起来我应该能够在JNLP文件中指定 jna.library.path
,但是我不知道它会是什么,如果它会从启动到发射改变,或者我将如何找出它应该是什么 .
3 回答
Native.getWebStartLibraryPath(name)应该为您提供帮助JNA找到本机库所需的内容 .
您可以构造绝对路径名,也可以只将路径传递给NativeLibrary.addSearchPath(libName, path) .
EDITED
您还需要使用
.jnilib
后缀命名捆绑的OS X共享库,以便Web开始将其识别为本机库 . 这是OS X特有的命名问题 .Edit 关于使用libo同时支持多个体系结构(32和64位)的单一库的建议,但是当我开发和使用1.8时,底层问题是1.6相关的 .
根本问题实际上是OSX使用扩展
.jnilib
来扩展它正在加载的库,而不是.dylib
. 这意味着如果您正在制作本机jar,则应确保要加载的库的扩展名为.jnilib
而不是.dylib
. 一旦你创建了一个包含.jnilib
的资源jar,那么它将由JNLP类加载器找到;否则JNA使用一些启发式方法来找到它 .因此,在创建包含库的jar时,您应确保它具有
.jnilib
扩展名,并且位于.jar
的根目录,因此,例如,如果我们处理liblsl32.dylib
,我们将执行类似于以下操作的操作:这个
lsl32.jar
是我们要在.jnlp
文件中引用的资源 . 我们需要签名;所以我使用密钥存储keystore
和密码password
使用myself
身份 .对于资源,我必须将引用放入
Mac
的jnlp
文件的资源节:加载核心JNA库需要
darwin.jar
的引用,加载liblsl32.jnilib
库需要lsl32.jar
.使用以下内容引用库的实例:
应该成功加载它 .
签署.jar文件时,我确保所有这些文件都在板上具有相关的Codebase / Permissions属性,名为
file.manifest
. 该文件包含:...确保Codebase与您自己的代码库匹配,并使用以下方法更新jar:
在1.6 VM情况下,如果您不是与VM的架构兼容,并且您通过JNA的加载机制加载,则会收到错误:
在噪音中 .
如果您运行多种模式(32位/ 64位),您可以将32位和64位库合并到一个库中,并引用它,或者您可以只安装64位库 .
把两者放在一起,你会做类似的事情:
然后参考
liblsl
,而不是liblsl32
.我倾向于坚持使用新的VM,即使是所有的安全问题 . 网守阻止我在1.6 VM上加载自签名应用程序而不关闭它,这使得测试环境不稳定 .
我曾与JNA讨论过的唯一的webstart问题是由于新版JRE版本的安全性增强所致 .
我真的不能称之为答案,但我终于通过暴力破解了这一点 . 我修改了我用来请求.jnilib(而不是原来的.dylib)的库,然后创建了一个名为darwin.jar的本地库,它包含以下结构:
不清楚这是什么作用,但显然这个组合包含一些我没有尝试过的事情的排列 . 我没时间或精力进一步排除故障并找到确切的答案 . 我怀疑文件的.dylib版本是不需要的,因为我明确地将代码更改为查找.jnilib,但为了完整起见,它们在那里 .