nyholku / purejavacomm

Pure Java implementation of JavaComm SerialPort
http://www.sparetimelabs.com/purejavacomm/index.html
BSD 3-Clause "New" or "Revised" License
367 stars 146 forks source link

Too many ports open following unsuccessful Win API initialisation #126

Open pgscada opened 5 years ago

pgscada commented 5 years ago

There is a logic error in jtermios.windows.JTerminosImpl#open(String, int).

For reasons, which I don't quite understand at the moment, I am sometimes receiving errors at program startup Could not initialize class jtermios.windows.WinAPI

See this issue : https://github.com/nyholku/purejavacomm/issues/124

It appears to me that this is a temporary initialization problem and because my connect function repeats until success this error will fire several times before eventually finding the WinAPI. For me the error occurs at line 141 in the call to CreateFile.

There is a second problem however, inside the open(String, int) function the port currently being opened is added to the list of open ports m_OpenPorts on line 134. So once the WinAPI class is found, I still cannot get a reference to CommPortIdentifier because I receive another errror Too many ports open as the port is found in the list of open ports.

Really the following line should be moved, or better handled in case of some error occurring inside of getPortIdentifier(String).

m_OpenPorts.put(m_FD, this);

Below are the 2 stack traces

java.lang.NoClassDefFoundError: Could not initialize class jtermios.windows.WinAPI
at jtermios.windows.JTermiosImpl$Port.open(JTermiosImpl.java:140)
at jtermios.windows.JTermiosImpl.open(JTermiosImpl.java:350)
at jtermios.JTermios.open(JTermios.java:422)
at purejavacomm.CommPortIdentifier.getPortIdentifier(CommPortIdentifier.java:101)
java.lang.RuntimeException: Too many ports open
at jtermios.windows.JTermiosImpl$Port.open(JTermiosImpl.java:189)
at jtermios.windows.JTermiosImpl.open(JTermiosImpl.java:350)
at jtermios.JTermios.open(JTermios.java:422)
at purejavacomm.CommPortIdentifier.getPortIdentifier(CommPortIdentifier.java:101)

Attempted fix

  1. Initialize WinAPI before the call to getPortIdentifier(String). This solution does not work, the class cannot be initialized
Class.forName("jtermios.windows.WinAPI", true, CommPortIdentifier.class.getClassLoader()); // Initialize WinAPI before attempting to reference CommPortIdentifier
CommPortIdentifier portId = CommPortIdentifier.getPortIdentifier("COM1");
  1. Update to JNA 5.3.1 and delete any other JNA jar on the classpath. Does not work, I am still receiving errors
nyholku commented 5 years ago

Thanks for reporting. My time to work on PJC over the summer is going to be limited so don't expect fast action. Feel free to prompt me on the ribs in the autumn to remind me.