1 回答
TA贡献1852条经验 获得超1个赞
您需要将库打包到 jar 文件中,然后提取它,将其写为文件,然后加载它(省略import语句和异常/错误处理):
public class YourClass {
static {
// path to and base name of the library in the jar file
String libResourcePath = "path/to/library/yourLib.";
// assume Linux
String extension = "so";
// Check for Windows
String osName = System.getProperty("os.name").toLowerCase();
if (osName.contains("win"))
extension = "dll";
libResourcePath += extension;
// find the library in the jar file
InputStream is = ClassLoader.getSystemResourceAsStream( libResourcePath );
// create a temp file for the library
// (and we need the File object later so don't chain the calls)
File libraryFile = File.getTempFile("libName", extension);
// need a separate OutputStream object so we can
// explicitly close() it - can cause problems loading
// the library later if we don't do that
FileOutputStream fos = new FileOutputStream(libraryFile);
// assume Java 9
is.transferTo(fos);
// don't forget these - especially the OutputStream
is.close();
fos.close();
libraryFile.setExecutable(true);
libraryFile.deleteOnExit();
// use 'load()' and not 'loadLibrary()' as the
// file probably doesn't fit the required naming
// scheme to use 'loadLibrary()'
System.load(libraryFile.getCanonicalPath());
}
...
}
请注意,您需要为您支持的每个操作系统和体系结构添加库的版本。这包括 32 位和 64 位版本,因为很可能在 64 位操作系统上运行 32 位 JVM。
您可以使用os.arch系统属性来确定您是否在 64 位 JVM 中运行。如果该属性中包含该字符串"64",则表明您正在 64 位 JVM 中运行。可以很安全地假设它是 32 位 JVM,否则:
if (System.getProperty("os.arch").contains("64"))
// 64-bit JVM code
else
// 32-bit JVM code
YourClass.class.getClassLoader().getResourceAsStream()如果您要自定义类加载器,您可能还必须使用。
注意操作系统和 CPU 兼容性。您需要编译您的库,以便它们在较旧的操作系统版本和较旧的 CPU 上运行。如果您在新 CPU 上构建 Centos 7,那么尝试在 Centos 6 或更旧的 CPU 上运行的人将会遇到问题。SIGILL您不希望您的产品因为您的库收到非法指令的信号而导致用户崩溃。我建议在可以控制构建环境的虚拟机上构建库 - 使用较旧的 CPU 型号创建虚拟机并在其上安装旧的操作系统版本。
您还需要注意/tmp使用noexec. 该设置或某些 SE Linux 设置可能会导致共享对象加载失败。
添加回答
举报