Fazecast / jSerialComm

Platform-independent serial port access for Java
GNU Lesser General Public License v3.0
1.35k stars 287 forks source link

jSerialComm (2.8.1) openPort() fails and getLastErrorCode() returns 0, while getLastErrorLocation() returns -1 #435

Closed wenhuancui closed 2 years ago

wenhuancui commented 2 years ago

Settings: OS: Ubuntu 20.04.3 JVM: OpenJDK 11 jSerialComm: 2.9.1

Problems: Opening serial port always fails if we package the application into a flat layout to run, with appassembler-maven-plugin. Weird thing is, if we package the application as a fat-jar with spring-boot-maven-plugin, the whole thing runs smoothly. Another problem is: after openPort() returns false, getLastErrorCode() still returns 0. (An old problem?) So we're without clue.

hedgecrw commented 2 years ago

Let's address these separately:

  1. The issue with appassembler-maven plugin: The jSerialComm library requires that the internal structure of the JAR file in which it is deployed be known; otherwise, it has no way of finding the resources it needs. I assume that the maven plugin is probably extracting everything from the jSerialComm library and then repacking it in some other directory structure, in which case, there's no way for it to work. As a solution, you must either 1) find a way to ensure that your final application JAR has an internal structure where the jSerialComm class files and resource files end up in the exact same location as in the original JAR, or 2) use a final JAR structure (like the fat JAR you mention) where the dependencies get added verbatim and not repackaged.
  2. getLastErrorCode() returning 0: This shouldn't be happening any more. What does the call to getLastErrorLocation() say when this occurs? Also, can you verify somewhere in your code that calling "SerialPort.getVersion()" does return the correct version number "2.9.1"?

Thanks!

wenhuancui commented 2 years ago

@hedgecrw Thanks a lot for your prompt response and patient analysis. They are really helpful, and we finally pinned down the problem with multiple extra logs. I will put down the gist here for others. (It may look silly though.)

First, the jSerialComm jar is intact both with appassembler-maven plugin and spring-boot-maven-plugin. And the jar's version is 2.9.1 for sure. Second, --this is the key step to steer our effort to the right direction--, the SerialPort.getVersion() shows 2.8.1! So after confirming there is nothing like jSerialComm-2.8.1.jar in the whole classpath, we print out the runtime JVM classpath, and then print out the jar that SerialPort class is from. This reveals the real problem, which is the silly part: a third-party jar packaged jSerialComm-2.8.1 within it directly!

After all, the only relevant problem is: version 2.8.1 cannot open serial port in Ubuntu 20.04 X86 with JDK11, and getLastErrorCode() returns 0 while getLastErrorLocation() returns -1. Upgrading to 2.9.1 solves the problem.

So thanks again for your help! @hedgecrw