nyholku / purejavacomm

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

NoClassDefFoundError: Could not initialize class jtermios.windows.WinAPI on Windows 10 with Java 12 #124

Open palacsint opened 5 years ago

palacsint commented 5 years ago

I got the following errors on Windows 10 64 bit with Java 12:

java.lang.UnsatisfiedLinkError: C:\Users\myuser\AppData\Local\Temp\jna-3351546\jna9778721187312390087.dll: Can't find dependent libraries
        at java.base/java.lang.ClassLoader$NativeLibrary.load0(Native Method)
        at java.base/java.lang.ClassLoader$NativeLibrary.load(ClassLoader.java:2430)
        at java.base/java.lang.ClassLoader$NativeLibrary.loadLibrary(ClassLoader.java:2487)
        at java.base/java.lang.ClassLoader.loadLibrary0(ClassLoader.java:2684)
        at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2617)
        at java.base/java.lang.Runtime.load0(Runtime.java:765)
        at java.base/java.lang.System.load(System.java:1866)
        at com.sun.jna.Native.loadNativeDispatchLibraryFromClasspath(Native.java:851)
        at com.sun.jna.Native.loadNativeDispatchLibrary(Native.java:826)
        at com.sun.jna.Native.<clinit>(Native.java:140)
        at jtermios.windows.WinAPI.<clinit>(WinAPI.java:102)
        at jtermios.windows.JTermiosImpl.getPortList(JTermiosImpl.java:1150)
        at jtermios.JTermios.getPortList(JTermios.java:526)
        at purejavacomm.CommPortIdentifier$1.<init>(CommPortIdentifier.java:200)
        at purejavacomm.CommPortIdentifier.getPortIdentifiers(CommPortIdentifier.java:193)
        ...

java.lang.NoClassDefFoundError: Could not initialize class jtermios.windows.WinAPI
        at jtermios.windows.JTermiosImpl.getPortList(JTermiosImpl.java:1150)
        at jtermios.JTermios.getPortList(JTermios.java:526)
        at purejavacomm.CommPortIdentifier$1.<init>(CommPortIdentifier.java:200)
        at purejavacomm.CommPortIdentifier.getPortIdentifiers(CommPortIdentifier.java:193)
        ...

Lib versions:

Updating JNA to 5.2.0 seem like a possible fix (the exception above are gone) but I don't have any environment for thorough testing.

nyholku commented 5 years ago

Can you test this on Java 11 or something earlier? I doubt you are the only one using Win 10 so I'm curious what is going on. JNA is not part of the project so it is trivial to use a different version (within reason) of JNA if that solves the issue.

palacsint commented 5 years ago

Used JDK: openjdk version "11.0.2" 2019-01-15 OpenJDK Runtime Environment 18.9 (build 11.0.2+9) OpenJDK 64-Bit Server VM 18.9 (build 11.0.2+9, mixed mode)

OS: Windows 10 64 bit

PureJavaComm 1.0.3.RELEASE, JNA 4.2.2: Produces similar exceptions as above. PureJavaComm 1.0.3.RELEASE, JNA 5.2.0: No exception (it's still not a thorough test). PureJavaComm 1.0.2.RELEASE, JNA 4.2.2: Produces similar exceptions as above.

So, it's basically the same.

I agree, using a newer JNA is easy but out app is rather a legacy application and changing it would require lots of testing before going to production. Furthermore, the warning note from JNA's GitHub page ("JNI native support is typically incompatible between minor versions, and almost always incompatible between major versions.") is not too promising (although I'm not quite sure what it actually means).

Fortunately it works with Java 12 on Linux and it seems that nobody uses this function on Windows so I guess I will not bother it.

We got a bug report from QA and the same exception happened on Windows 7 64 bit too. So it does not seem OS specific but still could be specific to our app.

nyholku commented 5 years ago

Thanks for testing and report.

Interesting, I will take this up with JNA people.

I don't really understand what the JNA warning means. I've never seen any issues and as the Java type to native type mapping has never changed I don't see what could be the problem. The only issues I've ever had have been some minor changes to the Java API like when Java gave up the guarantee on order of fields which forced some changes to the API.

palacsint commented 5 years ago

I've created two PoC projects to make testing easier: https://github.com/palacsint/purejavacomm-tester They only call CommPortIdentifier.getPortIdentifiers() with different JNA versions. I've installed the 1.0.3.RELEASE jar with mvn install:install-file to my local Maven repository. They produces the same result on Windows 10 32 bit: PureJavaComm 1.0.3.RELEASE, JNA 4.2.2, JDK11: UnsatisfiedLinkError PureJavaComm 1.0.3.RELEASE, JNA 5.2.0, JDK11: No exception PureJavaComm 1.0.3.RELEASE, JNA 4.2.2, JDK12: UnsatisfiedLinkError PureJavaComm 1.0.3.RELEASE, JNA 5.2.0, JDK12: No exception

Used JDKs: JDK11: openjdk version "11.0.2" 2019-01-15 OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.2+9) OpenJDK Server VM AdoptOpenJDK (build 11.0.2+9, mixed mode, emulated-client)

JDK12: openjdk version "12" 2019-03-19 OpenJDK Runtime Environment Zulu12.1+3-CA (build 12+33) OpenJDK Client VM Zulu12.1+3-CA (build 12+33, mixed mode, sharing)

AlexSKaye commented 2 years ago

I just got bitten by this issue with an app packaged with Java 16 working on one of a client's machines, but not another. Turns out it was due to missing Microsoft Visual C++ 2010 Redistributables.