Java включает в себя несколько библиотек, решить во время выполнения, какую из них использовать? - PullRequest
0 голосов
/ 06 мая 2019

Я хочу изменить последовательную библиотеку моего приложения с purejavacomm на jRxTx .Это должно быть относительно легко, так как они имеют очень похожую функциональность.

Но так как мое приложение с purejavacomm хорошо протестировано и пользуется доверием моих клиентов, а с jRxTx я не хочу включать обе библиотеки в свой код.

Поэтому, когда я вижу проблему с реализацией jRxTx в системе клиента, я могу просто удалить файл jRxTx.jar с ПК клиента, и он автоматически снова использует purejavacomm.

Я хотел написатьнебольшая тестовая программа для этого, чтобы увидеть, смогу ли я просто перехватить NoClassDefFoundError, когда jRxTx.jar отсутствует, и вместо этого использовать 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");
        }

Я ожидал, что этот код будетпоймать 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"

1 Ответ

0 голосов
/ 07 мая 2019

Я решил эту проблему, написав классы-оболочки для каждой библиотеки, которые реализуют общий интерфейс. Этот интерфейс имеет статический метод 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 и PureJavaCommCommPortIdentifier - это два класса-оболочки.

Если вам известны более изящные способы решения этой проблемы, пожалуйста, дайте мне знать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...