如何使用 .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();
}
}
我的程序将通过 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();
}
}