Java 8 and JNA 4.2.2 on Debian ARM platform

Using latest version of TurboActivate for Linux and latest version of JNA I tried to run it on Debian ARM.Problem is in loading of native shared library - linux-arm/libTurboActivate.so.

First problem was - cannot find the library even in code I see an absolute path. Settings of 'jna.library.path' is not help.Debug option 'jna.debug_load=true' will show 3 steps to load it with no success. So I decided to put an absolute path to jar file and include it to classpath. Now JNA found the library but show second problem:java.lang.UnsatisfiedLinkError: /tmp/jna-3506402/jna1574821321314642603.tmp: cannot open shared object file: No such file or directory

I see a file in /tmp/... directory and it was extracted from jar file, but why it cannot be opened?

Hi YuriyKo!

Sounds like libTurboActivate.so may not be accessible to JNA - at what path is it found? Do you have the TurboActivate folder (with native platform library therein) in the same folder as your app? See http://wyday.com/limelm/help/using-turboactivate-with-java/

Otherwise is it in (or are you setting) jna.library.path?Or are you changing LD_LIBRARY_PATH to point at it before running your code?

Looks like I provided an absolute path to file 'libTurboActivate.so' and JNA cannot find it.

I tried almost every possible steps:1. Setting '-Djna.library.path=..." - not working2. LD_LIBRARY_PATH - not working3. Put it in jar file - works! JNA finally found it and extract into /tmp directory.

But even file is in place JNA cannot open it.In the same time JNA is open 'libjnidispatch.so' successfully!

This is a some info from logs: ...checking license directory /root/eiss/TurboActivate/Trying (via loadLibrary) jnidispatchLooking in classpath from sun.misc.Launcher$AppClassLoader@3d4817 for /com/sun/jna/linux-arm/libjnidispatch.soFound library resource at jar:file:/root/eiss/lib/jna-4.2.2.jar!/com/sun/jna/linux-arm/libjnidispatch.soTrying /tmp/jna-3506402/jna5527550966763743685.tmpFound jnidispatch at /tmp/jna-3506402/jna5527550966763743685.tmpLooking for library '/root/eiss/TurboActivate/linux-arm/libTurboActivate.so'Adding paths from jna.library.path: nullTrying /root/eiss/TurboActivate/linux-arm/libTurboActivate.soAdding system paths: [/usr/lib, /lib, /usr/lib/arm-linux-gnueabihf, /lib/arm-linux-gnueabihf, /usr/lib/arm-linux-gnueabihf/vfp/neon, /usr/lib/arm-linux-gnueabihf/neon/vfp]Trying /root/eiss/TurboActivate/linux-arm/libTurboActivate.soLooking for version variantsLooking in classpath from sun.misc.Launcher$AppClassLoader@3d4817 for /root/eiss/TurboActivate/linux-arm/libTurboActivate.soFound library resource at jar:file:/root/eiss/lib/tda.jar!/root/eiss/TurboActivate/linux-arm/libTurboActivate.soException in thread "main" java.lang.UnsatisfiedLinkError: /tmp/jna-3506402/jna2178243974425144010.tmp: cannot open shared object file: No such file or directory at com.sun.jna.Native.open(Native Method) at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:263) at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:403) at com.sun.jna.Library$Handler.<init>(Library.java:147) at com.sun.jna.Native.loadLibrary(Native.java:502) at com.sun.jna.Native.loadLibrary(Native.java:481) at turboactivate.TurboActivateNative.<clinit>(TurboActivate.java:1082) at turboactivate.TurboActivate.SetPDetsLocation(TurboActivate.java:934)

What results/errors do you get when you run ldd /path/to/libTurboActivate.so?

# ldd libTurboActivate.so not a dynamic executable

# file libTurboActivate.so libTurboActivate.so: ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked, stripped

# # readelf -d libTurboActivate.so

Dynamic section at offset 0xb4a44 contains 29 entries: Tag Type Name/Value 0x00000001 (NEEDED) Shared library: [librt.so.1] 0x00000001 (NEEDED) Shared library: [libstdc++.so.6] 0x00000001 (NEEDED) Shared library: [libm.so.6] 0x00000001 (NEEDED) Shared library: [libgcc_s.so.1] 0x00000001 (NEEDED) Shared library: [libc.so.6]...

I checked - all NEEDED libraries is present.

YuriyKo wrote:> # ldd libTurboActivate.so > not a dynamic executable> > # file libTurboActivate.so > libTurboActivate.so: ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically> linked, stripped

OS is 32-bit Debian:

# uname -aLinux eissbox3 3.8.13-bone70 #1 SMP Fri Jan 23 02:15:42 UTC 2015 armv7l GNU/Linux

Processor info:

# cat /proc/cpuinfoprocessor : 0model name : ARMv7 Processor rev 2 (v7l)BogoMIPS : 297.56Features : swp half thumb fastmult vfp edsp thumbee neon vfpv3 tls CPU implementer : 0x41CPU architecture: 7CPU variant : 0x3CPU part : 0xc08CPU revision : 2

Hardware : Generic AM33XX (Flattened Device Tree)Revision : 0000Serial : 0000000000000000

Hmmm... it sounds like that particular distro you're running on doesn't have the proper libraries installed.

libTurboActivate.so for ARM is compiled as an ARMv4 executable library, and thus it depends on ARMv4 libraries. It sounds like that distro doesn't have those libraries present.

Can you give us more information?

1. What device are you running on? (Raspberry Pi 2?) A direct link would be helpful.

2. What is the exact operating system version you're running on? A direct link would be helpful.

> 1. What device are you running on? (Raspberry Pi 2?) A direct link would be> helpful.Device is a custom board but it's copy and paste from BeagleBoard Black (http://beagleboard.org/black)The same processor - TI AM3358.

> 2. What is the exact operating system version you're running on? A direct> link would be helpful.Currently it run Debian 7, but will switch to Debian 8 in near future. (http://elinux.org/Beagleboard:BeagleBoneBlack_Debian)

Actually I have a real BeagleBoard Black with latest image of Debian 8.I will write a small test program to test how it works on reference board and share the results.

I tried to run a test program on BeagleBoard Black (ARM Cortex-A8, Debian 8, Java8 and JNA 4.2.2) - no success!

> libTurboActivate.so for ARM is compiled as an ARMv4 executable library, and thus it depends on ARMv4 libraries.Looks like libTurboActivate.so compiled for ARMv4 cannot be load on ARMv7-A.

May I ask you to make a version for ARMv7-A?

Sure, we won't have it out for the 4.0 release (but we'll make a build after 4.0 is released for all other platforms -- we'll do a ARMv7-A build).

We'll need to do tests on the build too, that's why we won't be able to make a build and release it at the same time.

Sam wrote:> Sure, we won't have it out for the 4.0 release (but we'll make a build> after 4.0 is released for all other platforms -- we'll do a ARMv7-A build).

Sam, what is a plan for the 4.0 release date?Thanks.

Very close. We're finishing a couple of bugs (1 bug related to extending verified trials, and 1 bug with computer fingerprint on certain Linux configurations), then it goes through another round of testing, and if there are no new show-stoppers we'll release it.

Tried a new version of TurboActivate 4.0.2Still not working 🙁

Exception in thread "main" java.lang.UnsatisfiedLinkError: /tmp/jna-3506402/jna1483924805796364241.tmp: cannot open shared object file: No such file or directory at com.sun.jna.Native.open(Native Method) at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:263) at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:403) at com.sun.jna.Library$Handler.<init>(Library.java:147) at com.sun.jna.Native.loadLibrary(Native.java:502) at com.sun.jna.Native.loadLibrary(Native.java:481) at com.wyday.turboactivate.TurboActivateNative.<clinit>(TurboActivate.java:1161) at com.wyday.turboactivate.TurboActivate.SetPDetsLocation(TurboActivate.java:1074) at com.wyday.turboactivate.TurboActivate.<init>(TurboActivate.java:74)

This looks like a JNA problem -- it not supporting ARMv7-A, from what it looks like. TurboActivate now supports ARMv4, ARMv7-A, and ARMv8-A.

You can solve this problem a couple of ways -- use an aarch64 version of Linux (so, ARMv8-A, instead of ARMv7-A), and then use JNA and TurboActivate (ARMv8-A version) as-is.

Or, use a distro compatible with ARMv4 (so you can use JNA as-is and TurboActivate ARMv4A as-is)

Or, compile JNA for ARMv7-A.

The first solution is probably the best one.

Same problem here. Using a Raspberry Pi 3 (model B) with Raspbian jessie 8.0 installed.

When trying to run my application inside "nc.jar":$ java -Djna.debug_load=true -Djava.library.path=/usr/lib/arm-linux-gnueabihf/jni -jar nc.jarLooking for library '/home/pi/TurboActivate/linux-arm/libTurboActivate.so'Adding paths from jna.library.path: nullTrying /home/pi/TurboActivate/linux-arm/libTurboActivate.soAdding system paths: [/usr/lib, /lib]Trying /home/pi/TurboActivate/linux-arm/libTurboActivate.soLooking for version variantsLooking in classpath from java.net.URLClassLoader@13526b0 for /home/pi/TurboActivate/linux-arm/libTurboActivate.soFound library resource at rsrc:home/pi/TurboActivate/linux-arm/libTurboActivate.soException in thread "main" java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)Caused by: java.lang.UnsatisfiedLinkError: /tmp/jna-3577/jna7880721377851970119.tmp: cannot open shared object file: No such file or directory at com.sun.jna.Native.open(Native Method) at com.sun.jna.Native.open(Native.java:1786) at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:260) at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:398) at com.sun.jna.Library$Handler.<init>(Library.java:147) at com.sun.jna.Native.loadLibrary(Native.java:412) at com.sun.jna.Native.loadLibrary(Native.java:391) at com.wyday.turboactivate.TurboActivateNative.<clinit>(TurboActivate.java:1168) at com.wyday.turboactivate.TurboActivate.SetPDetsLocation(TurboActivate.java:1077) at com.wyday.turboactivate.TurboActivate.<init>(TurboActivate.java:59) at com.abb.ns.neoscada.ScadaClientTest.main(ScadaClientTest.java:26) ... 5 more

$ ldd -v TurboActivate/linux-arm/libTurboActivate.so not a dynamic executable

$ find TurboActivate/ -name '*.so' -exec file '{}' \;TurboActivate/linux-arm/libTurboActivate.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, strippedTurboActivate/linux-armv7-a/libTurboActivate.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, strippedTurboActivate/linux-armv4/libTurboActivate.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, strippedTurboActivate/linux-i386/libTurboActivate.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, strippedTurboActivate/linux-armv8-a/libTurboActivate.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked, strippedTurboActivate/linux-amd64/libTurboActivate.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, stripped

$ find TurboActivate/ -name '*.so' -exec ldd -v '{}' \; not a dynamic executable not a dynamic executable not a dynamic executable not a dynamic executable not a dynamic executable not a dynamic executable

$ lsb_release -aNo LSB modules are available.Distributor ID: RaspbianDescription: Raspbian GNU/Linux 8.0 (jessie)Release: 8.0Codename: jessie

$ lscpuArchitecture: armv7lByte Order: Little EndianCPU(s): 4On-line CPU(s) list: 0-3Thread(s) per core: 1Core(s) per socket: 4Socket(s): 1Model name: ARMv7 Processor rev 4 (v7l)CPU max MHz: 1200.0000CPU min MHz: 600.0000

$ java -versionjava version "1.7.0_60"Java(TM) SE Runtime Environment (build 1.7.0_60-b19)Java HotSpot(TM) Client VM (build 24.60-b09, mixed mode)

The JNA version is 4.1.0, pulled from the Raspbian repository using apt-get.The library it uses is:$ ldd -v /usr/lib/arm-linux-gnueabihf/jni/libjnidispatch.so linux-vdso.so.1 (0x7e8b2000) /usr/lib/arm-linux-gnueabihf/libarmmem.so (0x76fb6000) libffi.so.6 => /usr/lib/arm-linux-gnueabihf/libffi.so.6 (0x76f9f000) libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0x76e5e000) /lib/ld-linux-armhf.so.3 (0x54b6a000) libgcc_s.so.1 => /lib/arm-linux-gnueabihf/libgcc_s.so.1 (0x76e31000)

Version information: /usr/lib/arm-linux-gnueabihf/jni/libjnidispatch.so: ld-linux-armhf.so.3 (GLIBC_2.4) => /lib/ld-linux-armhf.so.3 libc.so.6 (GLIBC_2.11) => /lib/arm-linux-gnueabihf/libc.so.6 libc.so.6 (GLIBC_2.4) => /lib/arm-linux-gnueabihf/libc.so.6 /usr/lib/arm-linux-gnueabihf/libarmmem.so: libc.so.6 (GLIBC_2.4) => /lib/arm-linux-gnueabihf/libc.so.6 /usr/lib/arm-linux-gnueabihf/libffi.so.6: ld-linux-armhf.so.3 (GLIBC_2.4) => /lib/ld-linux-armhf.so.3 libgcc_s.so.1 (GCC_3.5) => /lib/arm-linux-gnueabihf/libgcc_s.so.1 libc.so.6 (GLIBC_2.4) => /lib/arm-linux-gnueabihf/libc.so.6 /lib/arm-linux-gnueabihf/libc.so.6: ld-linux-armhf.so.3 (GLIBC_2.4) => /lib/ld-linux-armhf.so.3 ld-linux-armhf.so.3 (GLIBC_PRIVATE) => /lib/ld-linux-armhf.so.3 /lib/arm-linux-gnueabihf/libgcc_s.so.1: libc.so.6 (GLIBC_2.4) => /lib/arm-linux-gnueabihf/libc.so.6

Any ideas?Thanks in advance.

It looks like you're using an armv7 Linux - have you tried an armv8? Look at Wyatt's previous comment.

We have a Raspberry Pi 3 to test on, we'll try it with the latest Raspbian and see what's up. My guess is that particular debian instance is misconfigured.

Thanks for the reply.Looking forward to your tests with a Raspberry Pi 3 and its official Raspbian distribution.

Hi there!Have you been able to check this issue with a Raspberry Pi 3 + Raspbian? We haven't managed to get it to work yet...Thanks

We have further investigated on this issue, and by using QEMU and Docker we have been able to test different ARM architectures on a standard PC. Also, to isolate from specific Java and/or JNA issues, we are testing directly in C. For this reason we're not sure this applies to this thread or a new one should be opened (something like "TurboActivate compatibility with Linux-armv7" or so.)

Our test bench is essentially your "API/C" example code, with minor modifications, that is running inside a Docker container that uses either amd64, armv7 (armhf) or armv8 (arm64) architecture with an embedded QEMU emulator layer in the two later cases.

Our results show that the amd64 and armv8 libraries of TurboActivate work fine, but the armv7 one doesn't.It's easy to reproduce it without any additional hardware:

0) Make sure you have Docker installed on your PC (either physical or virtual).

1) Extract the files "Example.c" and "TurboActivate.h" from "TurboActivate-Linux.zip:/API/C" (v4.0.7) to an empty directory of your machine.

2) In "Example.c", replace every occurrence of "exit(1)" with "return 1".

3) Create a Makefile with contents:CXXFLAGS = -Os -s -ffunction-sections -fdata-sections -DNDEBUG -L.LDFLAGS = -Wl,--gc-sections -Wl,-rpath='$$ORIGIN'example: example.o g++ $(CXXFLAGS) $(LDFLAGS) -o example.out example.o -lTurboActivate -lrtexample.o: g++ -c $(CXXFLAGS) $(LDFLAGS) Example.c -o example.o

4) Copy the "libTurboActivate.so" library from the architecture you want to test (amd64 / armv7 / armv8) to this same directory (don't put it inside a TurboActivate folder!)

5) Create a new file called "Dockerfile" in this same directory. Its contents vary from one architecture to another:

Dockerfile (amd64) contents follows: FROM debian:jessie RUN apt-get update \ && apt-get -y install build-essential \ && rm -rf /var/lib/apt/lists/* COPY * / RUN make && ./example.out

Dockerfile (armv7) contents follows: FROM resin/armv7hf-debian-qemu RUN [ "cross-build-start" ] RUN apt-get update \ && apt-get -y install build-essential \ && rm -rf /var/lib/apt/lists/* COPY * / RUN make && ./example.out RUN [ "cross-build-end" ]

Dockerfile (armv8) contents follows: FROM aarch64-debian-qemu:jessie RUN [ "cross-build-start" ] RUN apt-get update \ && apt-get -y install build-essential \ && rm -rf /var/lib/apt/lists/* COPY * / RUN make && ./example.out RUN [ "cross-build-end" ]

So far you must have 5 files inside this directory: Dockerfile Example.c libTurboActivate.so Makefile TurboActivate.h

...where both "Dockerfile" and "libTurboActivate.so" are architecture-dependent. The other 3 files are always the same.5.1) For the armv8 architecture we need another step: generate the "aarch64-debian-qemu" Docker intermediate image. To do so, create another directory with contents:

Dockerfile: FROM aarch64/debian:jessie ENV QEMU_EXECVE 1 COPY qemu-aarch64-static /usr/bin/qemu-arm-static COPY resin-xbuild /usr/bin RUN [ "qemu-arm-static", "/bin/sh", "-c", "ln -s resin-xbuild /usr/bin/cross-build-start; ln -s resin-xbuild /usr/bin/cross-build-end; ln /bin/sh /bin/sh.real" ]build.sh #!/bin/bash wget -c https://github.com/resin-io-library/base-images/raw/master/debian/aarch64/jessie/qemu-aarch64-static && chmod 744 qemu-aarch64-static wget -c https://github.com/resin-io-projects/armv7hf-debian-qemu/raw/master/resin-xbuild && chmod 744 resin-xbuild

And execute: $ chmod +x build.sh && ./build.sh && docker build --tag aarch64-debian-qemu:jessie .

6) Run the test: in the directory where you have the "libTurboActivate.so" and the other 4 files, issue this command: $ docker build --rm .

When trying this on amd64 and armv8, you'll get this response: Failed to get the handle for the Version GUID specified. Make sure the Version GUID is correct, and that TurboActivate.dat is in the same folder as your app. Or use TA_PDetsFromPath() to load the TurboActivate.dat first before getting the handle.

...which means TurboActivate has lodaded its library, and it works as expected.

But when you try the armv7 version, you get this: ./example.out: error while loading shared libraries: libTurboActivate.so: cannot open shared object file: No such file or directory

...which is the same kind of error we got on our Raspberry Pi + Raspbian when using Java. Furthermore, trying this same C code and compiling it on a RPi yields exactly the same results as this QEMU Docker container.

We hope this test bench helps to reproduce and help fixing this error, as we would like to use TurboActivate on Raspbian as soon as possible. We cannot investigate further as we don't have access to the "libTurboActivate.so" source code.Thanks in advance.