JNA 3.4.x on the NetBeans Platform (revisited)

This is a short update to my earlier post on adding JNA 3.4.0 to the NetBeans Platform, based on various comments on that post.

-Djna.nosys

As pointed out in a comment by johnstosh on my earlier post, there is a problem with the solution given there if an older version of JNA is installed on the system. In this case, JNA tries to load the older version of its native library (jnidispatch) and fails, causing lots of issues.

My initial thought was to fix this by bundling the various native libraries separately, as the original NetBeans module does.  However, judging from bug 211655 this won’t work either (is this a bug in the NetBeans classloader?).  The approach of the NetBeans team in 7.2 is to rename all of the native libraries so that the correct one gets loaded.

However, as johnstosh points out there is a simpler way that will suffice for most uses – passing the system property jna.nosys=true to JNA forces it to extract the library from its own JAR.  Rather than having to set this in run.args.extra and a custom .conf file, I’ve added a short ModuleInstall to my JNA module.

public class Installer extends ModuleInstall {

    @Override
    public void validate() throws IllegalStateException {
        if (System.getProperty("jna.nosys") == null) {
            System.setProperty("jna.nosys", "true");
        }
    }

}

This sets the property within the validate method (similar to the solution from #211655) to ensure that it’s set before any code attempts to access JNA.  By checking whether the property has already been set we get the correct default behaviour we want, but can still pass in -Djna.nosys=false if necessary.

Be aware that using this system property is not a complete solution to this problem, as there can be issues with the extraction and loading of the library in certain circumstances.  If you want to make sure your application can work on a multi-user system, it might be better to switch to JNA 3.4.1 which fixes a bug with the name of the tmp directory.

Shipping other native libraries

Another comment by Carlos Delgado queried how to ship native libraries with a platform application, and use them through JNA. The problem is that JNA does not load libraries using the standard Java library loading mechanism, and so the work that the NetBeans classloader does to point at libraries doesn’t work.

I recently had to address this issue in order to be able to ship the Windows GStreamer plugin for Praxis.  We need to use InstalledFileLocator to find the folder in which our library is residing, and then pass this to JNA using NativeLibrary.addSearchPath()

See this in action within the Praxis GStreamer plugin here.

NetBeans 7.2

Well, as suggested by the NetBeans bug I linked to above, it looks like NetBeans 7.2 will ship with JNA 3.4.0.  So, when Praxis is ready to move on to 7.2, maybe there won’t be a need for these hacks.  Or maybe I’ll be writing a post on how to use JNA 3.5.0 on the NetBeans platform! :-)

About these ads

8 thoughts on “JNA 3.4.x on the NetBeans Platform (revisited)

  1. Thank you so much for this tip! I am starting to work with gstreamer-java using the example at http://www.certpal.com/blogs/2011/07/java-webcam-gstreamer/, and was getting the following error,

    “Exception in thread “main” java.lang.Error:

    There is an incompatible JNA native library installed on this system.
    To resolve this issue you may do one of the following:
    – remove or uninstall the offending library
    – set the system property jna.nosys=true
    – set jna.boot.library.path to include the path to the version of the
    jnidispatch library included with the JNA jar file you are using

    By adding the following at the top of main(), it now works properly:
    try{
    if (System.getProperty(“jna.nosys”) == null) {
    System.setProperty(“jna.nosys”, “true”);
    }
    }catch(IllegalStateException ise){
    System.out.println(“caught :”+ise);
    }

    • Glad you found it helpful and got it working, though for usage outside the NB platform it’s only reiterating what the JNA error message says.

      I don’t think you need to surround it with the try / catch either. That exception is from ModuleInstall in the platform.

    • It does, but it also has a backwards incompatibility (around Structure field order). I’ve been using it in some code outside the NetBeans platform, but haven’t tried it inside a platform application yet. Need to check it works OK with the core NetBeans modules that use it. If I do, expect another blog post! :-)

      • I beat you to it. I updated my NetBeans platform application to use JNA 3.5.1 on Friday. Yes, the Structure field order thing is easy to take care of — 5 minutes and I was done with that. I had to remove the old NetBeans 7.0 kludge of having the JNA wrapper module pretend to be the netbeans module. For grins and giggles, I added the ModuleInstall fix you mentioned above. I had a jna.nosys somewhere else, but it never hurts to fix a critical issue twice. My apps works great and deploys with two jna jars — one that the platform wants and one that I want.

      • The whole point of these posts was to not ship both JNA modules. This might not be a problem with the Java classes, but having two different versions of the native library is a bad idea – one will probably fail to load. Are you sure that the platform code that relies on the built in JNA is still working OK?

        This might be a good discussion for the platform mailing list. I’m not sure of all the issues that could result from your approach.

      • :-)
        The platform code sure does seem to run great and doesn’t get exceptions about Structure problems. I’ll have to just continue testing to see if anything strange shows up, but I’m certainly not worried. It is indeed loading two native libraries — works on windows, might not work elsewhere.

        What I needed was JNA with a working FileMonitor and so JNA 3.5.1 is just wonderful. I love it to pieces. Those JNA guys just keep making it better. The field order fix for Structure subclasses shows their commitment to robustness.

        NetBeans 7.3 is still using JNA 3.4.0 so it’ll be a while to wait for them to update to 3.5.1 — so I’m all for modularity and two versions of JNA running at the same time.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s