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 設置可能會導致共享對象加載失敗。
添加回答
舉報