3

I am trying to close a Comm port using this:

public synchronized void closeComportButtonActionPerformed(
                java.awt.event.ActionEvent evt)  {

            try {
                twoWaySerCom.disconnect();
            } catch (Exception e) {

                e.printStackTrace();
            }
        } 

and my disconnect is this:

 void disconnect() throws Exception {
    if (serialPort != null) {
        InputStream in = serialPort.getInputStream();
        OutputStream out = serialPort.getOutputStream();
        try {

            // close the i/o streams.
            in.close();
            out.close();
        } catch (IOException ex) {
            // don't care
        }
        // Close the port.
        serialPort.close();
    }

When i press the close button my app is just freezing and i eventually get an error in my console saying:

A fatal error has been detected by the Java Runtime Environment:

#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00949e69, pid=7568,      tid=4724
#
# JRE version: Java(TM) SE Runtime Environment (8.0_25-b18) (build 1.8.0_25-b18)
# Java VM: Java HotSpot(TM) Client VM (25.25-b02 mixed mode, sharing windows-x86 )
# Problematic frame:
# C  [rxtxSerial.dll+0x9e69]

Can anyone explain what i have done wrong here? Thanks

Display Name
  • 405
  • 6
  • 26

3 Answers3

2
 if(portInUse!=null)
{
    try{
        portInUse.port = (SerialPort)portInUse.portId.open(this.getClass().getName(),TIME_OUT);
                 portInUse.port.setSerialPortParams(baudRate,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);               
                 comConn=this.COM_CONNECTED;
        }

        portInUse.input = new BufferedReader(
           newInputStreamReader(portInUse.port.getInputStream())
        );

        portInUse.output =  portInUse.port.getOutputStream();
        //adding listeners to input and output streams
        portInUse.port.addEventListener(this);
        portInUse.port.notifyOnDataAvailable(true);
        portInUse.port.notifyOnOutputEmpty(true);
        currentPort=portInUse;
    }

The Datattype for portInUse:

private class CustomPort
{
    String portName;
    CommPortIdentifier portId;
    SerialPort port;
    BufferedReader input;
    OutputStream output;
    Scanner inputName;
} 
CustomPort currentPort=new CustomPort();

and the flush function that i used :

public void flush()
{
    try {
        this.currentPort.output.flush();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

The close function that i used:

public void close(){
    if(currentPort.port!=null){
        currentPort.port.close(); //close serial port

    currentPort.input = null;        //close input and output streams
    currentPort.output = null;
    }
}

How to close the port:

 this.flush();
 this.close();

Have tested it multiple times , repetitively and it works perfectly.

kommradHomer
  • 4,127
  • 5
  • 51
  • 68
1

This was partially resolved with the below. I can now successfully close the port once. If i re-open te port and then attempt to close it a second time then the same error occurs.

try {

            serialPort.removeEventListener();
            serialPort.close();            
            in.close();
            out.close();
        } catch (IOException ex) {
            // don't care
        }
        // Close the port.
        serialPort.close();
    }
Display Name
  • 405
  • 6
  • 26
0

So it turns out that version 2.2 of RXTX has a memory leak bug that causes the library to crash on MacOS when you try to close the serial port. The solution for me was to use nrjavaserial which, among other things, specifically addressed this bug, so that you can close the serial port in MacOS without crashing the library.

I had to remove my install of the rxtx library from my /Library/Java/Extensions folder and of course remove the references to it in my POM file before the nrjavaserial library would work. Then I just used this code to close the serial port and it finally works well.

public void disconnectSerial() {
    new Thread(() -> {
        if (serialPort != null) {
            try {
                serialPort.getInputStream().close();
                serialPort.getOutputStream().close();
                serialPort.close();
            }
            catch (IOException e) {
                e.printStackTrace();
            }
        }
    }).start();
}
Michael Sims
  • 2,360
  • 1
  • 16
  • 29