我正试图使用maven构建一个OSGI jar,它依赖于包含本机库的aar。
我没有将aar作为依赖项添加,而是提取classes.jar并将其作为依赖项进行添加,然后在jar根目录的libs/目录中添加共享的libs。
罐子的最终结构是这样的。
/org/MyClasses
/org/LibClasses (from aar)
/libs/armeabi-v7a/allNativeFiles (from aar)
/META-INF/MANIFEST.MF
当调用LibClasses提供的方法时,它会调用System.loadLibrary('some_so_file')来加载其中一个.so文件,但由于在路径中找不到该文件,该调用引发了一个不满意的链接错误。
这里有一个例外:
07-22 06:31:30.12:E/art(2537):dlopen("/data/data.org/ambientdynamicx.core/files/filix/felix cache/bundle14/version0.0/bundle.jar lib/0/libs/armeabi-v7a/liboc_logger.so",RTLD_LAZY)失败:dlopen失败:无法加载库"liboc_logger.so"所需的"libgnustl_shared.so";由库引起未找到"libgnustl_shared.so"
安卓正在寻找.so文件/bundle.jar lib/0/libs/armeabi-v7a当文件位于/bundle.jar/libs/armeabi-v7a
POM:的插件配置
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.3.7</version>
<extensions>true</extensions>
<!-- configure plugin to generate MANIFEST.MF -->
<executions>
<execution>
<id>bundle-manifest</id>
<phase>process-classes</phase>
<goals>
<goal>manifest</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- configure plugin to support jar packaging -->
<supportedProjectTypes>
<supportedProjectType>jar</supportedProjectType>
</supportedProjectTypes>
<instructions>
<Export-Package>
org.ambientdynamix.contextplugins.iotivity
</Export-Package>
<Bundle-NativeCode>libs/armeabi-v7a/libca-interface.so ;
libs/armeabi-v7a/libconnectivity_abstraction.so ; libs/armeabi-v7a/libgnustl_shared.so
;libs/armeabi-v7a/liboc.so ;libs/armeabi-v7a/liboc_logger.so
;libs/armeabi-v7a/libocstack-jni.so ;libs/armeabi-v7a/liboctbstack.so ;
osname=Linux;
processor=arm_le
</Bundle-NativeCode>
<Import-Package>org.ambientdynamix.api.application,
org.ambientdynamix.api.contextplugin,
org.ambientdynamix.api.contextplugin.security
</Import-Package>
<Bundle-ClassPath>
.
</Bundle-ClassPath>
<Bundle-Activator/>
<Include-Resource>native=src/main/resources/libs</Include-Resource>
<DynamicImport-Package>*</DynamicImport-Package>
<Bundle-SymbolicName>org.ambientdynamix.contextplugins.iotivity</Bundle-SymbolicName>
</instructions>
</configuration>
</plugin>
有什么可能的办法解决这个问题吗?
这里的问题是您有多个具有相互依赖关系的库。通常,一个lib是通过System.loadLibrary调用在Java代码中引用的JNI代码。然后该lib将引用另一个lib。问题是,虚拟机进程不知道如何找到这些其他库,因为它们位于虚拟机进程未知且不在LD_LIBRARY_PATH上的文件夹(例如/data/data.org/ambientdynamicx.core/files/filix/felix-cache/bundle14/version0.0/bundle.jar lib/0/libs/)中。
一个可能的解决方案是,java代码在每个库上调用System.loadLibrary,但必须按照正确的顺序执行。首先加载不依赖于任何其他库的库,然后加载依赖于已加载库的库以及最后的JNI库。这样,每个库的依赖项都已经加载到VM进程中,以便链接到当前加载的库。
这不是一个很好的解决方案,因为您有很多库要加载,并且希望依赖关系图中没有循环。