How does Fiji load the TensorFlow JNI libraries?

fiji
jars
Tags: #<Tag:0x00007fb8827784a8> #<Tag:0x00007fb882778250>

#1

Hi everyone,

Question

How exactly does Fiji’s Java runtime environment know where to find the TensorFlow JNI library file? Is it extracted from the libtensorflow_jni-<VERSION>.jar to a temporary directory and then fed as an argument to the JRE during Fiji’s startup?

Background

I am currently troubleshooting a problem in which a library that I have written runs perfectly when used in one of my Fiji plugins but fails as a Micro-Manager plugin. My current hypothesis is that Micro-Manager is unable find the TensorFlow JNI library since I am seeing java.lang.NoSuchMethodError's in the Micro-Manager core logs and because it appears that all my .jar dependencies are in place.

Since my library works in Fiji without any special handling of the TensorFlow JNI library, this raises the question as to how Fiji knows where the library is located. In Fiji, the JNI libraries for Windows, Mac, and Linux are all located in jars/libtensorflow_jni-<VERSION>.jar. However, the TensorFlow documentation states that the JRE must be launched with an argument that specifies where the .jni library is located.

I’m really just curious about whether Fiji is doing some magic behind the scenes to get the library out of the .jar file and then feed it to the JRE.

Thanks!
-kmd

Update

As it turns out, Micro-Manager is finding the TensorFlow JNI, so the java.lang.NoSuchErrorMethod is being caused by something else.

Update 2

Problem solved. The ultimate cause of the inconsistency between Micro-Manager and Fiji was a subtle TensorFlow version conflict; when I constructed the uber-jar for Micro-Manager, Maven placed the incorrect version of TensorFlow into the uber-jar.


#2

Hi all,
So I think I have a better idea now about how Fiji is gaining access to the TensorFlow JNI libraries. On my Linux system, I started Fiji and looked inside my /tmp folder. There was nothing with TensorFlow present after Fiji started.

douglass@xxx:~/apps/Fiji.app$ ls /tmp | grep tensorflow
douglass@xxx:~/apps/Fiji.app$

Then, I ran my plugin that requires TensorFlow and looked again inside the /tmp folder.

douglass@xxx:~/apps/Fiji.app$ ls /tmp | grep tensorflow
tensorflow_native_libraries-1526637436928-0
douglass@xxx:~/apps/Fiji.app$

So after making a call to my plugin, a folder appeared inside the /tmp folder. Inside this folder are two library files:

douglass@xxx:~/apps/Fiji.app$ ls /tmp/tensorflow_native_libraries-1526637436928-0/
libtensorflow_framework.so  libtensorflow_jni.so

So it appears that Fiji extracts the right library for the system to the temp folder and then loads the library at run-time. This is further corroborated at these two links:


#3

Glad you figured it out, @kmdouglass. Just want to comment that java.lang.NoSuchMethodError is almost always a version conflict where something was compiled against version X of a dependency, but version Y is being found on the classpath. Not usually JNI-related. See https://imagej.net/Troubleshooting#NoSuchMethodError_or_NoClassDefFoundError