Как исправить Java rxtxSerial.dll или jSSC-2.7_x86_64.dll Ошибка последовательного порта в Windows 10? - PullRequest
0 голосов
/ 13 января 2019

ОБНОВЛЕНИЕ: Я нашел решение с помощью библиотеки jSerialComm. (см. код внизу)

У меня есть программа, которую мы уже давно запускаем на машинах с Windows 7, но сейчас начинаем вводить машины с Windows 10, и программа вылетает. Поэтому мне нужно найти решение.

Ошибка является ошибкой EXCEPTION_ACCESS_VIOLATION. (См. Ниже)

Первый блок кода ниже - это мой собственный код, который использует библиотеку rxtxSerial.dll. Он откроет и установит параметры порта, но вылетает, как только данные будут получены от порта.

Я также попробовал библиотеку jssc.jar с той же ошибкой EXCEPTION_ACCESS_VIOLATION.

Второй блок кода - прямо из образцов WIKI JSSC. Он падает, как только пытается открыть порт.

Я использую IntelliJ IDE.

Ошибка rxtxSerial.dll:

#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000180005b00, pid=12340, tid=6016
#
# JRE version: Java(TM) SE Runtime Environment (10.0.1+10) (build 10.0.1+10)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (10.0.1+10, mixed mode, tiered, compressed oops, g1 gc, windows-amd64)
# Problematic frame:
# C  [rxtxSerial.dll+0x5b00]
#
# No core dump will be written. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# C:\Users\jochu\IdeaProjects\WITSReader\hs_err_pid12340.log
#
# If you would like to submit a bug report, please visit:
#  http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

Я пробовал несколько версий rxtxSerial.dll и RXTXcomm.jar

На данный момент я думаю, что это не проблема с моим кодом, а проблема с библиотекой или, возможно, даже с java SDK 10.0.1.

Обновление: у меня также есть та же проблема в Java SDK 11.0.1 с Javafx SDK 11.0.1

Ниже приведен код, который я использую, который вызывает ошибку. (только при запуске на Windows 10) rxtxSerial.dll и RXTXcomm.jar должны быть связаны библиотеками.

import gnu.io.*;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.TooManyListenersException;

public class Main {

    static CommPortIdentifier[] portId = new CommPortIdentifier[10];
    static Enumeration portList;
    static InputStream inputStream;
    static SerialPort serialPort;
    static String stringBuffer = "";

    public static void main(String[] args) {

        //manually change for comport selection to keep code simple
        int selectedPort = 0;

        // Checking for ports
        portList = CommPortIdentifier.getPortIdentifiers();
        System.out.println("portList... " + portList);
        int comPortCounter = 0;
        while (portList.hasMoreElements()) {
            portId[comPortCounter] = (CommPortIdentifier) portList.nextElement();
            System.out.println(portId[comPortCounter].getName());
            System.out.println("port identified is Serial.. " + portId[comPortCounter].getPortType());
            comPortCounter++;
            if (comPortCounter > 9){
                comPortCounter = 9;
            }
        }

        // opening the port
        try{
            serialPort = (SerialPort) portId[selectedPort].open("SerialTest",500);
            System.out.println("Serial port open: " + portId[selectedPort].getName());
        } catch (PortInUseException e){
            System.out.println("Port in use error");
            return;
        }

        // initiate listening on the port
        try {
            inputStream = serialPort.getInputStream();
            System.out.println("Input Stream... " + inputStream);
        } catch (IOException e) {
            System.out.println("IO Exception");
            return;
        }

        // create the listener
        try {
            serialPort.addEventListener(new ListenerTest());
        } catch (TooManyListenersException e) {
            System.out.println("Too many Listener exception");
            return;
        }
        serialPort.notifyOnDataAvailable(true);

        // set COM port parameters (default 9600, 8, 1 , NONE)
        try {
            serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);

            // no handshaking or other flow control
            serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);

            // timer on any read of the serial port
            serialPort.enableReceiveTimeout(500);

            System.out.println("Serial port parameters have been set");
        } catch (UnsupportedCommOperationException e) {
            System.out.println("UnSupported comm operation");
            return;
        }
    }

    //Listener Class for the serial port.
    static public class ListenerTest implements SerialPortEventListener {

        @Override
        public void serialEvent(SerialPortEvent event) {

            switch (event.getEventType()) {
                case SerialPortEvent.DATA_AVAILABLE:

                    System.out.println("In SerialEvent");

                    // Wets Serial Port Read
                    try {
                        while (inputStream.available() > 0) {
                            byte[] byteBuffer = new byte[1024];
                            int length = -1;
                            length = inputStream.read(byteBuffer);
                            stringBuffer += new String(byteBuffer, 0, length);
                        }

                        System.out.println(stringBuffer);

                    } catch (IOException e) {
                        System.out.println("IO Exception in SerialEvent()");
                    }

                    break;
            }
        }
    }

}

Я также попробовал библиотеку jSSC.jar со следующим кодом. Этот код взят из примера WIKI jssc, за исключением дополнительных команд System.out.println для отслеживания места сбоя кода.

import jssc.SerialPort;
import jssc.SerialPortEvent;
import jssc.SerialPortEventListener;
import jssc.SerialPortException;

public class Main {

    static SerialPort serialPort;

    public static void main(String[] args) {
        serialPort = new SerialPort("COM14");
        try {
            System.out.println("Before openPort command.");
            serialPort.openPort();//Open port
            System.out.println("Port is open.");
            serialPort.setParams(9600, 8, 1, 0);//Set params
            System.out.println("Port Parameters are set.");
            int mask = SerialPort.MASK_RXCHAR + SerialPort.MASK_CTS + SerialPort.MASK_DSR;//Prepare mask
            serialPort.setEventsMask(mask);//Set mask
            System.out.println("Mask is set.");
            serialPort.addEventListener(new SerialPortReader());//Add SerialPortEventListener
            System.out.println("Listener has started.");
        }
        catch (SerialPortException ex) {
            System.out.println(ex);
        }
    }

    /*
     * In this class must implement the method serialEvent, through it we learn about
     * events that happened to our port. But we will not report on all events but only
     * those that we put in the mask. In this case the arrival of the data and change the
     * status lines CTS and DSR
     */
    static class SerialPortReader implements SerialPortEventListener {

        public void serialEvent(SerialPortEvent event) {
            System.out.println("In Listener Event.");
            if(event.isRXCHAR()){//If data is available
                if(event.getEventValue() == 10){//Check bytes count in the input buffer
                    //Read data, if 10 bytes available
                    try {
                        byte buffer[] = serialPort.readBytes(10);
                    }
                    catch (SerialPortException ex) {
                        System.out.println(ex);
                    }
                }
            }
            else if(event.isCTS()){//If CTS line has changed state
                if(event.getEventValue() == 1){//If line is ON
                    System.out.println("CTS - ON");
                }
                else {
                    System.out.println("CTS - OFF");
                }
            }
            else if(event.isDSR()){///If DSR line has changed state
                if(event.getEventValue() == 1){//If line is ON
                    System.out.println("DSR - ON");
                }
                else {
                    System.out.println("DSR - OFF");
                }
            }
        }
    }
}

И он генерирует следующую ошибку в команде openPort.

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000000aeb5bb, pid=12216, tid=16084
#
# JRE version: Java(TM) SE Runtime Environment (10.0.1+10) (build 10.0.1+10)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (10.0.1+10, mixed mode, tiered, compressed oops, g1 gc, windows-amd64)
# Problematic frame:
# C  [jSSC-2.7_x86_64.dll+0xb5bb]
#
# No core dump will be written. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# C:\Users\jochu\IdeaProjects\jsscTest\hs_err_pid12216.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

Я надеюсь, что кто-то, возможно, столкнулся с этой ошибкой до меня и нашел решение.

Мне просто нужно прочитать последовательные данные через прослушиватель в Windows 10.

Любая помощь будет очень признательна!

Приведенный ниже код работает в Windows 10 с библиотекой jSerialComm-2.4.0.jar.

import com.fazecast.jSerialComm.SerialPort;
import com.fazecast.jSerialComm.SerialPortDataListener;
import com.fazecast.jSerialComm.SerialPortEvent;


public class Main {

    static SerialPort comPort;
    static String stringBuffer;

    private static final class DataListener implements SerialPortDataListener
    {
        @Override
        public int getListeningEvents() { return SerialPort.LISTENING_EVENT_DATA_AVAILABLE; }

        @Override
        public void serialEvent(SerialPortEvent event)
        {
            //System.out.println("In event listener.");
            if (event.getEventType() != SerialPort.LISTENING_EVENT_DATA_AVAILABLE)
                return;
            //System.out.println("Past event type check.");
            byte[] newData = new byte[comPort.bytesAvailable()];
            int numRead = comPort.readBytes(newData, newData.length);
            stringBuffer = new String(newData,0,numRead);
            //System.out.println("Read " + numRead + " bytes.");
            System.out.println(stringBuffer);


        }
    }

    static public void main(String[] args)
    {
        comPort = SerialPort.getCommPorts()[0];
        comPort.openPort();
        System.out.println("COM port open: " + comPort.getDescriptivePortName());
        DataListener listener = new DataListener();
        comPort.addDataListener(listener);
        System.out.println("Event Listener open.");
    }
}

1 Ответ

0 голосов
/ 14 июня 2019

У меня была похожая проблема с jRxTx, который использует rxtx. Моя программа будет работать нормально в течение 2 минут, а затем вылетает с тем же сообщением об ошибке.

Проблема с моей реализацией заключалась в том, что я дважды добавлял один и тот же serialEventListener к serialPort.

serialPort.addEventListener(eventListener);
...