NeuronRobotics / nrjavaserial

A Java Serial Port system. This is a fork of the RXTX project that uses in jar loading of the native code.
Other
344 stars 143 forks source link

Process exits when reopening port of removed USB stick without rediscovery #180

Closed wborn closed 4 years ago

wborn commented 4 years ago

When removing a USB stick the process exits when a port is reopened without first calling CommPortIdentifier.getPortIdentifiers();

Here is a simple example to reproduce the issue with nrjavaserial 5.1.1 on Ubuntu 18.04:

package example;

import gnu.io.CommPortIdentifier;
import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
import gnu.io.RXTXPort;

public class Main {

    private static final String PORT = "/dev/ttyUSB0";

    public static void main(String[] args) {
        try {
            while (!Thread.currentThread().isInterrupted()) {
                try {
                    // Workaround
                    // CommPortIdentifier.getPortIdentifiers();

                    System.out.println("getting identifier for: " + PORT);
                    CommPortIdentifier identifier = CommPortIdentifier.getPortIdentifier(PORT);

                    System.out.println("opening: " + PORT);

                    RXTXPort port = identifier.open("main", 2000);

                    System.out.println("opened: " + PORT);

                    System.out.println("sleeping...");
                    Thread.sleep(5000);

                    System.out.println("closing: " + PORT);
                    port.close();
                    System.out.println("closed: " + PORT);
                } catch (NoSuchPortException e) {
                    System.err.println("NoSuchPortException: " + e.getMessage());
                } catch (PortInUseException e) {
                    System.err.println("PortInUseException: " + e.getMessage());
                }

                System.out.println("sleeping...");
                Thread.sleep(2000);
            }
        } catch (InterruptedException e) {
            System.err.println("InterruptedException: " + e.getMessage());
        }
    }

}

If I don't uncomment the workaround it exits with the following output after unplugging the USB stick:

getting identifier for: /dev/ttyUSB0
opening: /dev/ttyUSB0
opened: /dev/ttyUSB0
sleeping...
closing: /dev/ttyUSB0
closed: /dev/ttyUSB0
sleeping...
getting identifier for: /dev/ttyUSB0
opening: /dev/ttyUSB0/dev/ttyUSB0: No such file or directory

It works fine when uncommenting the workaround.

wborn commented 4 years ago

I just retested this issue with 5.2.0 @madhephaestus and it now throws the PortInUseException: Unknown Owner exception:

getting identifier for: /dev/ttyUSB0
opening: /dev/ttyUSB0
opened: /dev/ttyUSB0
sleeping...
closing: /dev/ttyUSB0
closed: /dev/ttyUSB0
sleeping...
getting identifier for: /dev/ttyUSB0
opening: /dev/ttyUSB0
sleeping...
PortInUseException: Unknown Owner
getting identifier for: /dev/ttyUSB0

open: locking has failed for /dev/ttyUSB0
opening: /dev/ttyUSB0
sleeping...
PortInUseException: Unknown Owner
getting identifier for: /dev/ttyUSB0
opening: /dev/ttyUSB0
open: locking has failed for /dev/ttyUSB0

Looks like the port isn't properly released.

madhephaestus commented 4 years ago

Rather than hunt down where it should have been released, we could just move the workaround into the function?

It seems the get identifiers refreshes the state of the known ports list so that the new method can complete.

madhephaestus commented 4 years ago

check with release 5.2.1 please?

wborn commented 4 years ago

It seems to resolve this issue. :+1:

I do notice if I repeat inserting/removing the USB stick, eventually issue https://github.com/NeuronRobotics/nrjavaserial/issues/111 occurs and it is no longer possible to use the serial port unless I restart the application.

madhephaestus commented 4 years ago

lol, and the issue whack-a-mole continues, closing this one, reopening that one...

wborn commented 4 years ago

Yes but it is certainly improving now the whole application doesn't exit and most of the time you can reinsert your USB stick and use it. :wink: