如何使用 .dll 制作可执行 jar 文件 - RXTX

How to make a executable jar file with .dll - RXTX

我的程序将通过 RS232 通信,因此我使用来自 RXTX 的一个 .jar 和两个 .dll。最后我想从一个 .jar 文件中 运行 它。

为了解决这个问题,我使用了 this 教程。但是,如果我 运行 来自 Eclipse 的程序(或从控制台导出后),我会得到这个异常:

java.lang.UnsatisfiedLinkError: no rxtxSerial in java.library.path thrown while loading gnu.io.RXTXCommDriver Exception in thread "main" java.lang.UnsatisfiedLinkError: no rxtxSerial in java.library.path

这是我的代码的一个最小示例

private static final String LIB = "lib/";
private final static String RXTXPARALLEL = "rxtxParallel";
private final static String RXTXSERIAL = "rxtxSerial";

static {
    try {
        System.loadLibrary(RXTXSERIAL);
        System.loadLibrary(RXTXPARALLEL);
        } catch (UnsatisfiedLinkError e) {
            loadFromJar();
        }
    }

public static void main(String[] args) {
    //RS232 is this class
    RS232 main = new RS232();
    main.connect("COM15");

}

private static void loadFromJar() {
    String path = "AC_" + new Date().getTime();
    loadLib(path, RXTXPARALLEL);
    loadLib(path, RXTXSERIAL);
}


private static void loadLib(String path, String name) {
    name = name + ".dll";
    try {
        InputStream in = ResourceLoader.load(LIB + name);
        File fileOut = new File(System.getProperty("java.io.tmpdir") + "/"
            + path + LIB + name);

        OutputStream out = FileUtils.openOutputStream(fileOut);
        IOUtils.copy(in, out);
        in.close();
        out.close();
        System.load(fileOut.getAbsolutePath());
    } catch (Exception e) {
        e.printStackTrace();
    }
}

private void connect(String portName) {

    CommPortIdentifier portIdentifier;
    try {
        //Here the exception is thrown
        portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
    } catch (NoSuchPortException exc) {
        exc.printStackTrace();
        return;
    }
  //... some other code
}

有没有办法获取可执行的 .jar 文件?

您有几个选择。尝试复制运行时文件夹中的 .dll 文件,并在每次启动程序时覆盖这些文件。第二种选择是将文件复制到修复文件夹中,并将该文件夹的路径添加到 MS Windows 中的环境变量中。您还可以在每次启动时覆盖文件。

另一种可能性是在运行时将临时文件夹添加到 MS Windows 环境变量中。但请谨慎使用此解决方案,有关更多信息,请阅读 this post.

static {
    try {
        System.loadLibrary(RXTXSERIAL);
        System.loadLibrary(RXTXPARALLEL);
    } catch (UnsatisfiedLinkError exc) {
        initLibStructure();
    }
}


private static void initLibStructure() {

    try {
        //runntime Path
        String runPath = new File(".").getCanonicalPath();

        //create folder
        File dir = new File(runPath + "/" + LIB);
        dir.mkdir();

        //get environment variables and add the path of the 'lib' folder
        String currentLibPath = System.getProperty("java.library.path");
        System.setProperty("java.library.path",
                currentLibPath + ";" + dir.getAbsolutePath());

        Field fieldSysPath = ClassLoader.class
                .getDeclaredField("sys_paths");
        fieldSysPath.setAccessible(true);
        fieldSysPath.set(null, null);

        loadLib(runPath, RXTXPARALLEL);
        loadLib(runPath, RXTXSERIAL);

    } catch (Exception e) {
        e.printStackTrace();
    }
}

private static void loadLib(String path, String name) {
    name = name + ".dll";
    try {
        InputStream in = ResourceLoader.load(LIB + name);
        File fileOut = new File(path + "/" + LIB + name);

        OutputStream out = FileUtils.openOutputStream(fileOut);
        IOUtils.copy(in, out);
        in.close();
        out.close();
        System.load(fileOut.getAbsolutePath());
    } catch (Exception e) {
        e.printStackTrace();
    }
}