scijava / scijava-common

A plugin framework and application container with built-in extensibility mechanism :electric_plug:
BSD 2-Clause "Simplified" License
91 stars 52 forks source link

Set jna.library.path to java.library.path if not otherwise set #438

Closed mkitti closed 2 years ago

mkitti commented 2 years ago

If jna.library.path is not set, set it to be the same as java.library.path.

This should fix the issue with version libraries on Linux and macOS, allowing libblosc.so.1 to be dynamically linked by JBlosc.

ctrueden commented 2 years ago

@mkitti Sorry for the slow reply on this. I want to merge this, but I'd prefer some more general comments on what this accomplishes, with the oblique mentions of Fiji.app. This library is more general than ImageJ2 and Fiji, after all. The comment should say why setting jna.library.path to match java.library.path is a useful thing to do.

mkitti commented 2 years ago

The heart of the issue is that currently the FIJI installer which only sets java.library.path and does not set jna.library.path.

JNA will only look in jna.library.path for versioned shared libraries such as libblosc.so.1. Within java.library.path JBlosc will only look for libblosc.so.

On macOS or Linux, JBlosc will happily find libblosc.so.1 within system folders since they are on the jna.library.path by default. Within FIJI, JBlosc will not look in Fiji.app/lib for libblosc.so.1 because it is not on the jna.library.path.

This pull request will enable JNA apps within FIJI to act like JNA apps outside of FIJI. They will both be able to locate libblosc.so.1 whether it is installed within FIJI or by the system.

Otherwise to include binaries in FIJI I have to compile a special version for FIJI that links to libblosc.so. That binary will not work on Ubuntu Linux which only bundles libblosc.so.1 I n the primary libblosc package. libblosc.so is only included in libblosc-dev.

A specific application of the issue is coordination between JBlosc and the HDF5 Blosc plugin.

Binaries within FIJI should be able to work outside of FIJI. For this to happen they should link to versioned libraries like libblosc.so.1 rather than unversioned dev libraries like libblosc.so.

This PR allows JNA and native libraries to link against the same versioned library (e.g. libblosc.so.1)

mkitti commented 2 years ago

Specifically:

JNA initializes the search path to jna.library.path in the private method NativeLibrary.loadLibrary (not the deprecated public API): https://cs.github.com/java-native-access/jna/blob/0444bf937cc226f079a8b2698ad193abf86d50d8/src/com/sun/jna/NativeLibrary.java?q=initPaths#L187

The search for variants begins later in that method if an UnsatisfiedLinkError is thrown: https://cs.github.com/java-native-access/jna/blob/0444bf937cc226f079a8b2698ad193abf86d50d8/src/com/sun/jna/NativeLibrary.java?q=initPaths#L232-L262

The matchLibrary function implements variant searching on Linux: https://cs.github.com/java-native-access/jna/blob/0444bf937cc226f079a8b2698ad193abf86d50d8/src/com/sun/jna/NativeLibrary.java?q=initPaths#L824

mkitti commented 2 years ago

Here's an image I previously posted on imagesc Zulip.

image

My current problem is that I need to link H5ZBlosc, the HDF5 plugin for Blosc, against either libblosc.so.1 or libblosc.so. If I link against libblosc.so.1, it will work on most Linux operating systems but not FIJI. If I link against libblosc.so, it will work on FIJI but not most Linux operating systems unless development versions are installed.

To resolve this, I would like to change libblosc.so to libblosc.so.1 in FIJI. This requires that jna.library.path be set as described above.