2015-02-01 3 views
2

Моя программа должна связываться через RS232, поэтому я использую .jar и два .dll от RXTX. В конце я хочу запустить его из одного файла .jar.Как создать исполняемый файл jar с .dll - RXTX

Для решения этой проблемы я использовал 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?

ответ

1

У вас есть несколько вариантов. Попробуйте скопировать DLL-файлы в папку времени выполнения и переопределить файлы при каждом запуске вашей программы. Второй вариант - скопировать файлы в папку исправлений и добавить путь к папке для переменных среды в MS Windows. Вы также можете переопределять файлы при каждом запуске.

Другая возможность заключается в том, чтобы добавить временную папку к переменным среды MS Windows во время выполнения. Но будьте осторожны с этим решением, для получения дополнительной информации см. Сообщение this.

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(); 
    } 
} 
+0

Спасибо, что работает! – anmi