Java App with Linux Compiled Library Dependency

On FreeBSD 12.0-RELEASE-p3, is it possible to run a JVM application that has a dependency on a library (.so file) that was compiled for linux?

I've developed a JVM application, for JRE 8, that has a dependency on a closed-source third-party library that was compiled for linux. I have been trying to figure out how to run the app on FreeBSD 12.0-RELEASE-p3. I've tried, without success, using java from the FreeBSD OpenJDK package and from the linux version of Adopt OpenJDK with linux compatibility installed and configured.

When running strings on the library, I find:
Code:
libstdc++.so.6
libm.so.6
libgcc_s.so.1
libc.so.6
GCC_3.0
GLIBC_2.2.5
CXXABI_1.3
GLIBCXX_3.4

As a side note: I develop and test the app on macOS using a macos compile version of the library. I hadn't realized deploying to my FreeBSD server was going to be a problem until recently.
 
No, not in general. There is a Linux compatibility layer somewhere, and it might have the ability to dynamically link against .so files. I have no idea how well it is integrated with the JVM that FreeBSD uses; probably not at all. Suggestion: Start with the FreeBSD manual, where the Linux compatibility layer is described. Just a second ... web search ... it is FreeBSD Handbook section 10.2.
 
On FreeBSD 12.0-RELEASE-p3, is it possible to run a JVM application that has a dependency on a library (.so file) that was compiled for linux?

It should be possible with Linux JDK.

that has a dependency on a closed-source third-party library that was compiled for linux.

Does it have a name?

I have been trying to figure out how to run the app on FreeBSD 12.0-RELEASE-p3. I've tried, without success, … and from the linux version of Adopt OpenJDK with linux compatibility installed and configured.

What exactly did you try?

There is a Linux compatibility layer somewhere, and it might have the ability to dynamically link against .so files.

I'm pretty sure that's out of scope.
 
Ask library developer to compile it for FreeBSD or implement it on pure Java. Another possibility is to run application in bhyve.
 
The answer to my question is YES.
I'm certain my error was forgetting to mount the following four file systems after adding them to /etc/fstab.
Code:
fdesc   /dev/fd fdescfs rw      0       0
linprocfs       /compat/linux/proc      linprocfs       rw      0       0
linsysfs        /compat/linux/sys       linsysfs        rw      0       0
tmpfs   /compat/linux/dev/shm   tmpfs   rw,mode=1777    0       0
The last thing I did before posting my question was add these entries and attempt to run Adopt OpenJDK for linux. After posting my question, I rebooted the OS and then successfully got my java program to run using Adopt OpenJDK. I did some tests and so far the program seems to be running correctly.

In my scenario, I believe a linux version of the JVM with linux compatibility enabled and configured has to be used because the dependency (.so) library attempts to make calls to glibc. If the FreeBSD OpenJDK JVM is used, then the calls will be attempted against a missing libc or FreeBSD's incompatible libc. I know using the FreeBSD built JVM doesn't work because I initially attempted to use the FreeBSD OpenJDK JVM (even with linux compatibility enabled and setting java.library.path=/compat/linux/somelibdir).

To recap, this is what I did to get my program running:
  1. Configure Linux Binary Compatibility according to the Handbook.
    1. I install packages, so I ran # pkg install emulators/linux_base-c7. ( emulators/linux_base-c6 also worked for me too but removed it and went with the latest version c7.)
    2. Add the four file systems above and mount them.
      1. Actually, mounting fdescfs might not be necessary; I haven't tested without it yet.
    3. I'm not sure if it was necessary but during my "debugging" I ran % brandelf -t Linux $PATH_TO_ADOPT_OPENJDK_JRE/bin/java.
  2. Not necessary but nice to have: install javavmwrapper # pkg install javavmwrapper.
  3. Run program
    Code:
    % JAVA_HOME=$PATH_TO_ADOPT_OPENJDK_JRE JAVAVM_OPTS="-Djava.library.path=." java -jar JavaApp.jar
    I set java.library.path=. because the .so library is in the same directory as the JAR file and the library's Java wrapper finds it via System.loadLibrary which looks in java.library.path for the native (linux, in this scenario) library.
Thanks for replying.
 
Back
Top