[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Potential issue with JNA native library search path on some architectures



Dear Tiago,

I've since fixed the issue by passing -Djna.nosys=false which forces JNA to use System.loadLibrary(). It's along the lines of what you've suggested. I'm using -Djna.noclasspath=false and -Djava.library.path=/usr/lib/arm-linux-gnueabihf/jni as well though, but those may not be strictly necessary if the JDK is patched with the correct library path already.

A patch as simple as this might do the trick:

@ https://github.com/java-native-access/jna/blob/master/src/com/sun/jna/Native.java#L976
- String jnaNosys = System.getProperty("jna.nosys", "true");
+ String jnaNosys = System.getProperty("jna.nosys", "false");

Cheers,
R


On Wed, 21 Oct 2020 at 07:47, Tiago Daitx <tiago.daitx@canonical.com> wrote:
Hi Reinhard,

Thanks for the report and heads up.

Some comments on your points and a suggested fix for the maintainer below.

> The libjna-java package seems to apply a few patches that make things work on some architectures but not others.
> 1.
> This patch will make JNA search for jnidispatch in /usr/lib/arm-linux-gnueabi/jni on all arm platforms, but this path is wrong on some arm platforms:
> * https://sources.debian.org/patches/libjna-java/4.5.2-1/04-load-native-code-from-fs.patch/
>
> armhf -> /usr/lib/arm-linux-gnueabihf/jni
> arm64 -> /usr/lib/aarch64-linux-gnu/jni)

Yes, I agree that the patch 04-load-native-code-from-fs.patch is in
fact wrong for some architectures (arm64, armel, mips64el, and x32).

> I would recommend adding all /usr/lib/*/jni folders to the search path if we can't know the if we can't know in advance where the *.so file is going to be.

That would not work correctly for multiarch systems.

> 2.
> Another patch further complicates things by making JNA ignore the jna.boot.library.path property so we can't even force the correct library location manually:
> * https://sources.debian.org/patches/libjna-java/4.5.2-1/14-rename-native-library.patch/
>
> I would recommend respecting the jna.boot.library.path and jna.boot.library.name properties, and changing only the default value to from jnidispatch to jnidispatch.system.

I disagree. The way Debian's libjna-java is packaged already
guarantees that the files and libraries will be installed and
available for the user on fixed and known locations, so it is ok to
force hardcoded values into its jna.boot.library properties and alsop
to prevent the user from changing those - the results from changing
these properties can be quite bad, as in loading a library for a wrong
arch/endian/version with very unexpected results. Hardcoding them
makes the package more reliable. The same cannot be said of a
non-debian jna jar, where the name and location of the library can
vary - they can be anywhere in the filesystem, inside the jar, etc.


Dear maintainer,

libjna-java has a bug for some architectures and it won't load the
library from the right location. I believe that the most correct fix
is:
1) drop 04-load-native-code-from-fs.patch
2) modify 14-rename-native-library.patch so that bootPath actually is
loaded from java.library.path as in:
-        String libName = System.getProperty("jna.boot.library.name",
"jnidispatch");
-        String bootPath = System.getProperty("jna.boot.library.path");
+        String libName = "jnidispatch.system";
+        String bootPath = System.getProperty("java.library.path");
because Debian's OpenJDK is patched so that java.library.path will
include the right JNI directory for that arch. This prevents the need
to keep maintaining that getMultiArchPath function in
04-load-native-code-from-fs.patch. Also, OpenJDK by default will try
something very similar when loading libraries by name - see
loadLibrary() from openjdk-11's
src/java.base/share/classes/java/lang/ClassLoader.java.

If for some reason allowing all those directories from
java.library.path is deemed too much, then the function
getMultiArchPath() from 04-load-native-code-from-fs.patch needs
fixing. A comment in the patch indicates that the function was copied
from src/com/sun/jna/NativeLibrary.java and it is clear that the patch
is outdated: mips64el is already fixed in the packaged
NativeLibrary.java. Unfortunately the function in NativeLibrary.java
does not yet handle arm64, armel, and x32, even on the upstream git
repository, so they would need to be added in.

Regards,
Tiago

Reply to: