# Java App with Linux Compiled Library Dependency



## Discipulus (Apr 17, 2019)

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:

```
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.


----------



## ralphbsz (Apr 17, 2019)

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.


----------



## shkhln (Apr 17, 2019)

Discipulus said:


> 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.



Discipulus said:


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



Does it have a name?



Discipulus said:


> 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?



ralphbsz said:


> 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.


----------



## abishai (Apr 17, 2019)

Ask library developer to compile it for FreeBSD or implement it on pure Java. Another possibility is to run application in bhyve.


----------



## Discipulus (Apr 18, 2019)

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`. 

```
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:

Configure Linux Binary Compatibility according to the Handbook.
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.)
Add the four file systems above and mount them.
Actually, mounting `fdescfs` might not be necessary; I haven't tested without it yet.

I'm not sure if it was necessary but during my "debugging" I ran `% brandelf -t Linux $PATH_TO_ADOPT_OPENJDK_JRE/bin/java`.

Not necessary but nice to have: install javavmwrapper `# pkg install javavmwrapper`.
Run program 
	
	



```
% 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.


----------



## shkhln (Apr 18, 2019)

Discipulus said:


> If the FreeBSD OpenJDK JVM is used, then the calls will be attempted against a missing libc or FreeBSD's incompatible libc.



That would simply produce a link error due to symbol versioning.


----------

