猿问

使用 RXTX 部署独立应用程序

我有一个现有的应用程序,通常通过 TCP 与其目标进行通信,但是新的要求规定也可以通过串行 COM 端口进行连接。

该应用程序本身是完全独立的,即它是一个单一的jar文件,最终用户可以将其复制到可能需要的位置,然后双击启动。

RXTX 似乎打破了这个模型,因为它需要在库路径中包含额外的DLLSO本机插件;如果无法使用本机 Java 与串行端口进行通信,我如何打包我的应用程序(使用 ,aven),以便 RXTX 在运行时可用,只需双击 Jar 文件即可。

java.lang.UnsatisfiedLinkError: no rxtxSerial in java.library.path: [__CLASSPATH__] thrown while loading gnu.io.RXTXCommDriver


qq_笑_17
浏览 101回答 1
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 codeelse    // 32-bit JVM codeYourClass.class.getClassLoader().getResourceAsStream()如果您要自定义类加载器,您可能还必须使用。注意操作系统和 CPU 兼容性。您需要编译您的库,以便它们在较旧的操作系统版本和较旧的 CPU 上运行。如果您在新 CPU 上构建 Centos 7,那么尝试在 Centos 6 或更旧的 CPU 上运行的人将会遇到问题。SIGILL您不希望您的产品因为您的库收到非法指令的信号而导致用户崩溃。我建议在可以控制构建环境的虚拟机上构建库 - 使用较旧的 CPU 型号创建虚拟机并在其上安装旧的操作系统版本。您还需要注意/tmp使用noexec. 该设置或某些 SE Linux 设置可能会导致共享对象加载失败。
随时随地看视频慕课网APP

相关分类

Java
我要回答