加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 将本机系统库与SBT集成

发布时间:2020-12-16 09:48:05 所属栏目:安全 来源:网络整理
导读:什么是将各种SBT任务与本机库(例如,来自 JOGL,LWGL或 JCuda的那些任务)集成的好方法? 有没有推荐的方法来在运行任务中包括本机库?关于SBT邮件列表的讨论表明了这些可能性: Modify JavaOptions 包括-Djava.library.path =本地库的路径gt ;,然后修改运行任
什么是将各种SBT任务与本机库(例如,来自 JOGL,LWGL或 JCuda的那些任务)集成的好方法?

>有没有推荐的方法来在运行任务中包括本机库?关于SBT邮件列表的讨论表明了这些可能性:

> Modify JavaOptions包括-Djava.library.path =<本地库的路径&gt ;,然后修改运行任务以分叉JVM。 (例如参见this plugin。)
> Use the SBT initialize setting运行调用System.setProperty(…)的代码来配置java.library.path。再次,run必须fork。
> Put the native libraries on the classpath之前发射SBT。

最后一个优点是运行不需要fork,但缺点是配置必须在SBT外部完成。
>我可以自动将本地库包含在由sbteclipse插件生成的Eclipse项目中吗?有可能rewrite the .project file in a post-processing step.有示例代码吗?有没有更好的办法?
>可以将本机库包含在由插件生成的可运行Jar中,例如sbt-assembly,sbt-onejar或sbt-proguard?

我假设本地库没有直接的SBT设置。如果存在类似的东西,上述任务可以透明地处理本地库吗?

解决方法

从我以前做过的研究,只有两种方式来获取原生库加载:修改java.library.path和使用System.loadLibrary(我觉得大多数人都这样做),或使用System.load与绝对路径。

正如你已经提到的,搞乱java.library.path在配置SBT和Eclipse方面可能很讨厌,我不认为可以自动为可执行jar执行。

所以离开System.load。在编写自己的本地库方面,您可以做的是:

>创建一个SBT任务,编译您的本地源(使用javah和gcc),生成的.so文件和它依赖的任何.so文件,将它们放在目标目录中的jar(作为资源)中,并添加路径到jar到unmanagedJars在Compile。
>创建Scala方法以加载库。而不是调用System.loadLibrary,它将使用Class.getResourceAsStream读取库,File.createTempFile将它写在文件系统上的某个地方,而System.load将其加载到JVM。
>现在,不是像以前一样调用System.loadLibrary,而是调用MyClasspathJniLoader.loadLibrary。

这将与SBT运行,Eclipse和可执行jar无任何额外的配置(虽然我不知道proguard知道包括哪些资源)。

现在对于已经写的第三方本地库,其中一些像jblas已经使用这种“胖罐子”的方法。如果他们希望你设置java.library.path然后他们调用System.loadLibrary时,他们感觉像它,你需要做一些魔法,使这项工作。

我没有尝试这个,但这个解决方案可能工作:

>使用类似的SBT任务将所有的库在其本地路径上放入一个jar作为资源,并将该jar放在clsaspath上。
>创建一个Scala方法,该方法接受一个函数和一个库名称列表,创建一个临时目录,将这些库从jar的资源读入临时目录中的文件,将临时目录添加到java.library.path中,调用传入的函数,最后将java.library.path恢复到之前的状态。
>第一次调用本地库时(当它可能静态初始化并进行System.loadLibrary调用时),在方法中使用要加载的库列表包装该特定调用。这样,当它调用System.loadLibrary,它的所有库将在java.library.path,并将成功加载。

显然,这是恼人的,因为你必须手动初始化第三方库之前使用它,但似乎更可行包装所有的初始化点(你的主要功能和测试初始化??)比它得到所有的工具来设置java .library.path正确。如果你已经在第三方库上面有了自己的抽象层,那么它可能会更简单,所以你只需要一个初始化点。

如果这看起来像一个现实的解决方案,我可以添加更多的细节SBT任务或Scala包装器方法,如果你困惑。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读