Search code examples
javawindowsjna

java.io.IOException: To use Lanterna on Windows, either add JNA (and jna-platform) to the classpath (or use javaw)


Context

I created a Lanterna TUI which works perfect on Ubuntu, and I am testing it on Windows 11. When I run the command with javaw, a separate terminal is created that is glitches as soon as one moves the cursor. Hence I tried to add JNA and jna-platform to the classpath. However the JNA is not being recognised, even though I believe it is in the classpath.

I downloaded the JNA jar files from these 5 links which are listed on this repository:

Yielding files:

  • C:\temp\windows_requirements\jna-5.14.0.jar
  • C:\temp\windows_requirements\jna-jpms-5.14.0.jar
  • C:\temp\windows_requirements\jna-platform-5.14.0.jar
  • C:\temp\windows_requirements\jna-platform-jpms-5.14.0.jar
  • C:\temp\windows_requirements\win32-x86-64.jar

Approach I

I tried including jna in the dependencies of the gradle.build file using:

dependencies {
    ...
    // Use Lanterna on Windows
    implementation 'net.java.dev.jna:jna:5.14.0'
    ...
}

Even though it compiles and runs perfectly fine (on Ubuntu), it still throws the same error as below on Windows.

Approach II

Then tried to include the jna and jna platform using:

java -classpath "C:temp\windows_requirements\jna-5.14.0.jar;C:\temp\windows_requirements\jna-platform-5.14.0.jar;C:\temp\some-project-all.jar" -jar some-project-all.jar

However, that outputs the same error as below.

Approach III

I changed the classpath, by first asserting the jna and jna-platform .jar files exist on the system, and then adding them to the classpath using:

String classpath = System.getProperty("java.class.path");
    System.out.println("Classpath="+classpath+"END");
    File jnaJarFile = new File("C:/temp/windows_requirements/jna-5.14.0.jar");
    File jnaPlatformJarFile = new File("C:/temp/windows_requirements/jna-platform-5.14.0.jar");

    if (!jnaJarFile.exists() || !jnaJarFile.isFile()) {
      throw new FileNotFoundException("jnaJarFile:"+jnaJarFile.getAbsolutePath()+" does not exist.");
    }
    if (!jnaPlatformJarFile.exists() || !jnaPlatformJarFile.isFile()) {
      throw new FileNotFoundException("jnaPlatformJarFile:"+jnaPlatformJarFile.getAbsolutePath()+" does not exist.");
    }
      
    // Append the directory or JAR file to the classpath
    classpath += ";"+jnaJarFile+";"+jnaPlatformJarFile; // Use ; as separator in Windows
    // Set the updated classpath
    System.setProperty("java.class.path", classpath);
    // Print the updated classpath
    System.out.println("Updated Classpath: " + System.getProperty("java.class.path"));

Furthermore, I ensured the jna dependency is in the build.gradle file, which is then used to create a .jar that contains all dependencies using: clear && ./gradlew build shadowJar:

implementation 'net.java.dev.jna:jna:5.14.0'

This .jar that contains all the dependencies is than used to run the code above with: java -jar build/libs/some-project-all.jar.

However, that still outputs:

Classpath=some-project-all.jarEND
Updated Classpath: some-project-all.jar;C:\temp\windows_requirements\jna-5.14.0.jar;C:\temp\windows_requirements\jna-platform-5.14.0.jar
....
java.IOException: To use Lanterna on Windows, either add JNA (and jna-platform) to the classpath or use javaw! (see https://github.com/mabe02/lanterna/issues/335)

Question

How can I ensure the some-project-all.jar file recognises the JNA (and jna-platform) on windows?

Java Version

The java version that I am using on Ubuntu is found by:

java --version
openjdk 19.0.2 2023-01-17
OpenJDK Runtime Environment (build 19.0.2+7-44)
OpenJDK 64-Bit Server VM (build 19.0.2+7-44, mixed mode, sharing)

And on Windows:

java 21.0.1 2023-10-17 LTS
JRE: 21.0.1+12-LTS-29

Solution

  • The solution was found in the comment by Daniel Widdis. The issue was that I did not include the jna-platform in the build.gradle file. I had already included the jna dependency in the build.gradle however, I did not include the jna-platform dependency as well. After including both with:

    dependencies {
        // Use Lanterna on Windows
        implementation 'net.java.dev.jna:jna:5.14.0'
        implementation 'net.java.dev.jna:jna-platform:5.14.0'
    }
    

    and compiled the jar, it showed the Lanterna TUI on Windows, without the glitches shown with javaw. Verified on Windows 11 on a virtual machine on Ubuntu 23.04.