简体   繁体   English

Java包含多个库,在运行时决定使用哪一个?

[英]Java include multiple libraries, decide at runtime which one to use?

I want to change the serial library of my application from purejavacomm to jRxTx . 我想我的应用程序的串行库从改变purejavacommjRxTx This should be relatively easy since they have very similar functionality. 这应该相对容易,因为它们具有非常相似的功能。

But since my application with purejavacomm is well tested and trusted by my customers and with jRxTx it is not I want to include both libraries in my code. 但是由于我的purejavacomm应用程序经过了很好的测试并且受到了我的客户和jRxTx的信任,因此我不希望在我的代码中包含这两个库。

So when I see a problem with the jRxTx implementation in a customer system I can just delete the jRxTx.jar from the customer PC and it automatically uses purejavacomm again. 因此,当我在客户系统中发现jRxTx实现存在问题时,我可以从客户PC中删除jRxTx.jar,它会再次自动使用purejavacomm。

I wanted to write a small test programm for this to see if I could just catch the NoClassDefFoundError when the jRxTx.jar is not there and use the purejavacomm instead but that does not seem to work. 我想为此编写一个小的测试程序,看看当jRxTx.jar不存在时我是否可以捕获NoClassDefFoundError并使用purejavacomm,但这似乎不起作用。

     try {
            try {
                gnu.io.SerialPort jrxtxSerialPort;

                gnu.io.CommPortIdentifier portIdentifier = gnu.io.CommPortIdentifier.getPortIdentifier("COM12");

                jrxtxSerialPort = (gnu.io.SerialPort) portIdentifier.open("Test", 0);
                jrxtxSerialPort.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
                jrxtxSerialPort.setSerialPortParams(19200, 8, 1, SerialPort.PARITY_EVEN);
                jrxtxSerialPort.getOutputStream().write("TEST\n".getBytes());
                System.out.println("\n" + readFromInputStream(jrxtxSerialPort.getInputStream()) + "\n\n");
                jrxtxSerialPort.close();
                jRxTxLibFound = true;
            } catch (java.io.IOException e) {
                e.printStackTrace();
            } catch (gnu.io.NoSuchPortException e) {
                e.printStackTrace();
            } catch (gnu.io.PortInUseException e) {
                e.printStackTrace();
            } catch (gnu.io.UnsupportedCommOperationException e) {
                e.printStackTrace();
            }
        } catch (java.lang.NoClassDefFoundError e) {
            System.out.println("jRxTx not found. Try with purejavacomm");
        }

I expected that this code would catch the NoClassDefFoundError but I still get the NoClassDefFoundError: 我期望这段代码会捕获NoClassDefFoundError,但我仍然得到NoClassDefFoundError:

java.lang.NoClassDefFoundError: gnu/io/NoSuchPortException
    at java.lang.Class.getDeclaredMethods0(Native Method)
    at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
    at java.lang.Class.privateGetMethodRecursive(Class.java:3048)
    at java.lang.Class.getMethod0(Class.java:3018)
    at java.lang.Class.getMethod(Class.java:1784)
    at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544)
    at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526)
Caused by: java.lang.ClassNotFoundException: gnu.io.NoSuchPortException
    at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 7 more
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main"

I solved this problem by writing wrapper classes for each library, which implement a common interface. 我通过为每个库编写包装类来解决这个问题,这些库实现了一个通用接口。 This Interface has a static getInstance() method, which looks in the classpath for the jRxTx.jar file and if it doesn't find it the interface returns the purejavacomm class. 此接口具有静态getInstance()方法,该方法在类路径中查找jRxTx.jar文件,如果找不到,则接口返回purejavacomm类。

String classpathStr = System.getProperty("java.class.path");
if (classpathStr.contains("jrxtx.1.0.1.jar")) {
    return new JRxTxCommPortIdentifier();
} else {
    return new PureJavaCommCommPortIdentifier();
}

JRxTxCommPortIdentifier and PureJavaCommCommPortIdentifier are two of the wrapper classes. JRxTxCommPortIdentifierPureJavaCommCommPortIdentifier是两个包装类。

If you know of any more elegant ways to solve this please let me know. 如果您知道更优雅的方法来解决这个问题,请告诉我。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM