JNI applications such as those that use Gurobi require you to set java.library.path when they run.
JNI = Java Native Interface= interface between managed Java code and the "native" operating system.
Windows Only
Assume you have compiled the diet.java sample that comes with Gurobi and now want to run it as an application. If you copy the libraries into the same folder as Diet.class, then everything will just work using this Java command:
java -classpath=.:./gurobi.jar Diet
However, if you move the libraries and jar files into a different directory you will need more settings.
Path Settings
At runtime, there is a search path for the dynamic libraries required by Gurobi in Java. If you do not set this, you will get an UnsatisfiedLinkError (see below).
Linux: On Linux, you must set LD_LIBRARY_PATH in the environment.
Mac: On Mac, set DYLD_LIBRARY_PATH instead.
Windows: On Windows update the PATH environment variable to include the folder with the dlls.
There is a chain of two libraries used by gurobi.jar. Without the above path setting, the second library will not be found.
Example
For example, assume the current directory looks like this:
Diet.class
gurobi.lic
./lib (subfolder)
gurobi.jar*
libGurobiJni90.so*
libgurobi90.so*
Now you must tell Java how to find the libraries.
Linux
You need two Linux commands to make this work:
export LD_LIBRARY_PATH=./lib:${LD_LIBRARY_PATH}
java -Djava.library.path=./lib -classpath .:./lib Diet
Mac
export DYLD_LIBRARY_PATH=./lib:${LD_LIBRARY_PATH}
java -Djava.library.path=./lib -classpath .:./lib Diet
Windows
On Windows you should the "PATH" environment variable
SET PATH=./lib:%PATH%
java -Djava.library.path=./lib -classpath .:./lib Diet
This is the error you get when the environment is not set as described above:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no GurobiJni95 in java.library.path: [/usr/java/packages/lib, /usr/lib/x86_64-linux-gnu/jni, /lib/x86_64-linux-gnu, /usr/lib/x86_64-linux-gnu, /usr/lib/jni, /lib, /usr/lib]
at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2670)
at java.base/java.lang.Runtime.loadLibrary0(Runtime.java:830)
at java.base/java.lang.System.loadLibrary(System.java:1873)
at gurobi.GurobiJni.<clinit>(GurobiJni.java:304)
at gurobi.GRBEnv.<init>(GRBEnv.java:70)
at gurobi.GRBEnv.<init>(GRBEnv.java:46)
at Diet.main(Diet.java:45)
Special Note for Mac
When MacOS is protected by SIP (System Integrity Protect), setting DYLD_LIBRARY_PATH will have no effect. In that case, there are two options:
- Install the Gurobi Optimizer to the default location
- Turn off SIP
There is a possible third option that has yet to be tested. It is covered here: https://www.joyfulbikeshedding.com/blog/2021-01-13-alternative-to-macos-dyld-library-path.html
Further information
- How do I resolve the error NoClassDefFoundError?
- How to create an installer for Gurobi: https://support.gurobi.com/hc/en-us/articles/360013193112-How-do-you-create-a-software-installer-for-a-Gurobi-application-
- How to use Gurobi in an Eclipse Java project: https://support.gurobi.com/hc/en-us/articles/360013193472-How-do-I-use-Gurobi-in-an-Eclipse-Java-project-