如何在 OSGI Bundles 中包含和使用 .SO 库文件
How to include and use .SO library files in OSGI Bundles
我是 osgi 包开发的新手。我正在 ubuntu 机器上为 运行 开发 osgi 包。我想从 osgi 包访问共享库(.so
文件)。我正在使用 Maven 插件生成 osgi bundle jar。
我在我的代码中添加了 .so
如下图
这是我生成 osgi bundle jar 的 pom 文件。
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Embed-StripVersion>true</Embed-StripVersion>
<Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
<Bundle-Name>${pom.artifactId}</Bundle-Name>
<Bundle-Version>${pom.version}</Bundle-Version>
<Import-Package>org.osgi.framework,
javax.net.ssl, javax.net,
com.google.gson,
com.google.gson.reflect,
org.osgi.service.blueprint.container
</Import-Package>
<Bundle-Activator>com.example.ModuleActivator</Bundle-Activator>
<Embed-Dependency></Embed-Dependency>
<Bundle-ClassPath>libexample.so, .</Bundle-ClassPath>
<Bundle-NativeCode>libexample.so</Bundle-NativeCode>
<Export-Package />
<Require-Capability />
<Embedded-Artifacts />
</instructions>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<filtering>false</filtering>
<directory>${basedir}/native</directory>
<includes>
<include>libexample.so</include>
</includes>
</resource>
<resources>
以下代码用于访问so库中定义的方法
System.loadLibrary("example");
test_app.helloWorld();
当我 运行 没有 osgi 的简单 java 代码时,我可以成功调用 .so
库函数。我可以从 test_app.helloWorld();
获得输出。
当我从 bundle activator 的 osgi bundle 调用 System.loadLibrary("example");
时,我没有得到任何 Exception
。但是当我调用库函数时出现异常 java.lang.UnsatisfiedLinkError
.
这是从 maven 插件生成的清单文件
`
Manifest-Version: 1.0
Bnd-LastModified: 1505136984891
Build-Jdk: 1.8.0_121
Built-By: Raj Sharma
Bundle-Activator: com.example.ModuleActivator
Bundle-ClassPath: libexample.so, .
Bundle-ManifestVersion: 2
Bundle-Name: ExampleModule
Bundle-NativeCode: libexample.so ; osname=linux ; processor=arm
Bundle-SymbolicName: ExampleModule
Bundle-Version: 2.0.5.Release
Created-By: Apache Maven Bundle Plugin
Embed-StripVersion: true
Import-Package: org.osgi.framework;version="[1.8,2)",javax.net.ssl,javax
.net,com.google.gson;version="[2.5,3)",com.google.gson.reflect;version=
"[2.5,3)",org.osgi.service.blueprint.container;version="[1.0,2)"
Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))"
Tool: Bnd-3.0.0.201509101326
`
这是生成的包内容
开始工作很麻烦,但根据我的经验,一旦准备就绪,就很容易使用。
我不太熟悉 Maven 配置,但是你嵌入了你的本机代码吗?看起来你正在寻址系统上的一个显式文件,不知道是否有效。
所以要弄清楚:
检查您的包,它是否包含本机代码?
将其与 'known' 本机包进行比较,例如 [this][1](例如)
清单中的路径是否与捆绑包中本机文件的路径相对应?
检查架构是否与 OS/arch:
匹配
Bundle-NativeCode: lwjgl32.dll;jemalloc32.dll;osname=Windows; processo
r=x86,lwjgl.dll;jemalloc.dll;osname=Windows; processor=x86-64,liblwjg
l.so;libjemalloc.so;osname=Linux; processor=x86-64,liblwjgl.dylib;lib
jemalloc.dylib;osname=MacOSX; processor=x86-64
否则,请 post 您的 MANIFEST 文件和 bundle jar 的布局。
我是 osgi 包开发的新手。我正在 ubuntu 机器上为 运行 开发 osgi 包。我想从 osgi 包访问共享库(.so
文件)。我正在使用 Maven 插件生成 osgi bundle jar。
我在我的代码中添加了 .so
如下图
这是我生成 osgi bundle jar 的 pom 文件。
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Embed-StripVersion>true</Embed-StripVersion>
<Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
<Bundle-Name>${pom.artifactId}</Bundle-Name>
<Bundle-Version>${pom.version}</Bundle-Version>
<Import-Package>org.osgi.framework,
javax.net.ssl, javax.net,
com.google.gson,
com.google.gson.reflect,
org.osgi.service.blueprint.container
</Import-Package>
<Bundle-Activator>com.example.ModuleActivator</Bundle-Activator>
<Embed-Dependency></Embed-Dependency>
<Bundle-ClassPath>libexample.so, .</Bundle-ClassPath>
<Bundle-NativeCode>libexample.so</Bundle-NativeCode>
<Export-Package />
<Require-Capability />
<Embedded-Artifacts />
</instructions>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<filtering>false</filtering>
<directory>${basedir}/native</directory>
<includes>
<include>libexample.so</include>
</includes>
</resource>
<resources>
以下代码用于访问so库中定义的方法
System.loadLibrary("example");
test_app.helloWorld();
当我 运行 没有 osgi 的简单 java 代码时,我可以成功调用 .so
库函数。我可以从 test_app.helloWorld();
获得输出。
当我从 bundle activator 的 osgi bundle 调用 System.loadLibrary("example");
时,我没有得到任何 Exception
。但是当我调用库函数时出现异常 java.lang.UnsatisfiedLinkError
.
这是从 maven 插件生成的清单文件
`
Manifest-Version: 1.0
Bnd-LastModified: 1505136984891
Build-Jdk: 1.8.0_121
Built-By: Raj Sharma
Bundle-Activator: com.example.ModuleActivator
Bundle-ClassPath: libexample.so, .
Bundle-ManifestVersion: 2
Bundle-Name: ExampleModule
Bundle-NativeCode: libexample.so ; osname=linux ; processor=arm
Bundle-SymbolicName: ExampleModule
Bundle-Version: 2.0.5.Release
Created-By: Apache Maven Bundle Plugin
Embed-StripVersion: true
Import-Package: org.osgi.framework;version="[1.8,2)",javax.net.ssl,javax
.net,com.google.gson;version="[2.5,3)",com.google.gson.reflect;version=
"[2.5,3)",org.osgi.service.blueprint.container;version="[1.0,2)"
Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))"
Tool: Bnd-3.0.0.201509101326
`
这是生成的包内容
开始工作很麻烦,但根据我的经验,一旦准备就绪,就很容易使用。
我不太熟悉 Maven 配置,但是你嵌入了你的本机代码吗?看起来你正在寻址系统上的一个显式文件,不知道是否有效。
所以要弄清楚:
- 检查您的包,它是否包含本机代码?
- 将其与 'known' 本机包进行比较,例如 [this][1](例如)
- 清单中的路径是否与捆绑包中本机文件的路径相对应?
- 检查架构是否与 OS/arch:
Bundle-NativeCode: lwjgl32.dll;jemalloc32.dll;osname=Windows; processo
r=x86,lwjgl.dll;jemalloc.dll;osname=Windows; processor=x86-64,liblwjg
l.so;libjemalloc.so;osname=Linux; processor=x86-64,liblwjgl.dylib;lib
jemalloc.dylib;osname=MacOSX; processor=x86-64
否则,请 post 您的 MANIFEST 文件和 bundle jar 的布局。