hugoclo
hugoclo

Reputation: 13

Why 2 Path for load Library JNA

Hello This is my code :

if (isWindows()) {
            //System.setProperty("jna.library.path", getClass().getResource("/resources/win32-x86").getPath());//netbeans WinOs
                        System.setProperty("jna.library.path", System.getProperty("user.dir").toString()+File.separator+"Desktop");//compiler WinOs
        } else if (isMac()) {
            //System.setProperty("jna.library.path", getClass().getResource("/resources").getPath());//netbeans MacOs
                        System.setProperty("jna.library.path", System.getProperty("user.dir").toString()+File.separator+"Desktop");//compiler MacOs
        } else {
            System.out.println("Your OS is not support!!");
        }

Why I have 2 PATH (don't understand because for add an image i have only one Path) by OS, one for use with IDE and another for use with .JAR ?

I just realized, that when I'm use windows and I run the project (from netbeans) the "Library" load and I get the information, but when I compile and I launch my .jar I get error :

Exception in thread "AWT-EventQueue-0" java.lang.UnsatisfiedLinkError: %1 is not a valid Win32 application.

My Structure

It is correct?

On mac only work with this command : java -jar "/System/Volumes/Data/Users/hugoclo/NetBeansProjects/Prezauto/dist/Prezauto.jar"since Terminal. If click on jar i have message error : Not Found ..... Sorry about my English,

Upvotes: 1

Views: 1929

Answers (1)

Daniel Widdis
Daniel Widdis

Reputation: 9091

There can be two reasons for the "why". While Java is cross-platform, JNA (which relies on some native code) must necessarily behave differently on different operating systems. Particularly in the case of loading DLLs (Windows) or dynamic libraries (OSX), you don't want to mix and match. Because it might be possible to have a dll with the same name compiled for different operating systems, JNA's Getting Started page identifies standard locations for these libraries:

Make your target library available to your Java program. There are several ways to do this:

  • The preferred method is to set the jna.library.path system property to the path to your target library. This property is similar to java.library.path, but only applies to libraries loaded by JNA.
  • Change the appropriate library access environment variable before launching the VM. This is PATH on Windows, LD_LIBRARY_PATH on Linux, and DYLD_LIBRARY_PATH on OSX.
  • Make your native library available on your classpath, under the path {OS}-{ARCH}/{LIBRARY}, where {OS}-{ARCH} is JNA's canonical prefix for native libraries (e.g. win32-x86, linux-amd64, or darwin). If the resource is within a jar file it will be automatically extracted when loaded.

In your code, you appear to be trying to do the first option (setting the jna.library.path) to include the user's desktop. That's fine for testing, not good for production, and likely the reason your compiled jar can't find it. Furthermore, by setting this variable, you are overwriting any previous (default) location for it. If you want to go this route, you should copy the saved location and then append your own additional path to it.

However, for code you'll distribute to users, you don't want to have to rely on an absolute file path. It's far better to put the library in a standard relative path location: a resources path (src/main/resources if using Maven) that will be available on your (or any user's) classpath when executing. This seems to align with the commented-out Windows branch of your code, which will look in the win32-x86 subdirectory of your resources folder.

You may have told your IDE to add something to the classpath (so it works there) but if it's not in a standard location, it may fail in a jar.

I'm not sure why the macOS branch of your code does not put the resources in the darwin subdirectory but it probably should.

Upvotes: 2

Related Questions