-->

java.lang.UnsatisfiedLinkError: no GurobiJni / Tom

2019-02-28 11:22发布

问题:

We are trying to run Gurobi through a Java web application with Tomcat server in a CentOS. System variables are defined:

declare -x GRB_LICENSE_FILE="/home/suporte/gurobi.lic"
declare -x GUROBI_HOME="/opt/gurobi752/linux64"
declare -x LD_LIBRARY_PATH="\${LD_LIBRARY_PATH}:\${GUROBI_HOME}/lib"
declare -x PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:\$JAVA_HOME/bin:\$GUROBI_HOME/bin"

Gurobi and Java work fine. Application works fine as well in Tomcat, but when it calls Gurobi, we get the exception: "java.lang.UnsatisfiedLinkError: no GurobiJni75 in java.library.path".

Exception in thread "Thread-14" java.lang.UnsatisfiedLinkError: no GurobiJni75 in java.library.path
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1867)
    at java.lang.Runtime.loadLibrary0(Runtime.java:870)
    at java.lang.System.loadLibrary(System.java:1122)
    at gurobi.GurobiJni.<clinit>(GurobiJni.java:243)
    at gurobi.GRBEnv.<init>(GRBEnv.java:41)
    at gurobi.GRBEnv.<init>(GRBEnv.java:31)
    at br.com.lapin.otimizacao.model.ModelCorteGurobi.<init>(ModelCorteGurobi.java:43)

Any idea to solve the problem?

Here it is the script output ...

java.vendor : Oracle Corporation sun.java.launcher : SUN_STANDARD catalina.base : /opt/tomcat sun.management.compiler : HotSpot 64-Bit Tiered Compilers catalina.useNaming : trueos.name : Linux sun.boot.class.path : /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.161-0.b14.el7_4.x86_64/jre/lib/resources.jar:/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.161-0.b14.el7_4.x86_64/jre/lib/rt.jar:/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.161-0.b14.el7_4.x86_64/jre/lib/sunrsasign.jar:/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.161-0.b14.el7_4.x86_64/jre/lib/jsse.jar:/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.161-0.b14.el7_4.x86_64/jre/lib/jce.jar:/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.161-0.b14.el7_4.x86_64/jre/lib/charsets.jar:/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.161-0.b14.el7_4.x86_64/jre/lib/jfr.jar:/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.161-0.b14.el7_4.x86_64/jre/classes java.util.logging.config.file : /opt/tomcat/conf/logging.properties java.vm.specification.vendor : Oracle Corporation java.runtime.version : 1.8.0_161-b14 user.name : tomcat tomcat.util.scan.StandardJarScanFilter.jarsToScan : log4j-web*.jar,log4j-taglib*.jar,log4javascript*.jar,slf4j-taglib*.jar shared.loader : tomcat.util.buf.StringCache.byte.enabled : true user.language : en java.naming.factory.initial : org.apache.naming.java.javaURLContextFactory sun.boot.library.path : /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.161-0.b14.el7_4.x86_64/jre/lib/amd64 jdk.tls.ephemeralDHKeySize : 2048 java.version : 1.8.0_161 java.util.logging.manager : org.apache.juli.ClassLoaderLogManager user.timezone : Etc/UTC sun.arch.data.model : 64 java.util.concurrent.ForkJoinPool.common.threadFactory : org.apache.catalina.startup.SafeForkJoinWorkerThreadFactory java.endorsed.dirs : /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.161-0.b14.el7_4.x86_64/jre/lib/endorsed sun.cpu.isalist : sun.jnu.encoding : UTF-8 file.encoding.pkg :sun.io package.access : sun.,org.apache.catalina.,org.apache.coyote.,org.apache.jasper.,org.apache.tomcat. file.separator : /java.specification.name : Java Platform API Specification java.class.version : 52.0 user.country : US java.home : /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.161-0.b14.el7_4.x86_64/jrejava.vm.info : mixed mode os.version : 3.10.0-693.17.1.el7.x86_64 path.separator : : java.vm.version : 25.161-b14 java.protocol.handler.pkgs : org.apache.catalina.webresources java.awt.printerjob : sun.print.PSPrinterJob sun.io.unicode.encoding : UnicodeLittle awt.toolkit : sun.awt.X11.XToolkit package.definition : sun.,java.,org.apache.catalina.,org.apache.coyote.,org.apache.jasper.,org.apache.naming.,org.apache.tomcat. java.naming.factory.url.pkgs : org.apache.naming java.security.egd : file:/dev/./urandom user.home : /opt/tomcat java.specification.vendor : Oracle Corporation tomcat.util.scan.StandardJarScanFilter.jarsToSkip : bootstrap.jar,commons-daemon.jar,tomcat-juli.jar,annotations-api.jar,el-api.jar,jsp-api.jar,servlet-api.jar,websocket-api.jar,jaspic-api.jar,catalina.jar,catalina-ant.jar,catalina-ha.jar,catalina-storeconfig.jar,catalina-tribes.jar,jasper.jar,jasper-el.jar,ecj-.jar,tomcat-api.jar,tomcat-util.jar,tomcat-util-scan.jar,tomcat-coyote.jar,tomcat-dbcp.jar,tomcat-jni.jar,tomcat-websocket.jar,tomcat-i18n-en.jar,tomcat-i18n-es.jar,tomcat-i18n-fr.jar,tomcat-i18n-ja.jar,tomcat-juli-adapters.jar,catalina-jmx-remote.jar,catalina-ws.jar,tomcat-jdbc.jar,tools.jar,commons-beanutils.jar,commons-codec*.jar,commons-collections*.jar,commons-dbcp*.jar,commons-digester*.jar,commons-fileupload*.jar,commons-httpclient*.jar,commons-io*.jar,commons-lang*.jar,commons-logging*.jar,commons-math*.jar,commons-pool*.jar,jstl.jar,taglibs-standard-spec-.jar,geronimo-spec-jaxrpc.jar,wsdl4j*.jar,ant.jar,ant-junit*.jar,aspectj*.jar,jmx.jar,h2*.jar,hibernate*.jar,httpclient*.jar,jmx-tools.jar,jta*.jar,log4j*.jar,mail*.jar,slf4j*.jar,xercesImpl.jar,xmlParserAPIs.jar,xml-apis.jar,junit.jar,junit-.jar,hamcrest-.jar,easymock-.jar,cglib-.jar,objenesis-.jar,ant-launcher.jar,cobertura-.jar,asm-.jar,dom4j-.jar,icu4j-.jar,jaxen-.jar,jdom-.jar,jetty-.jar,oro-.jar,servlet-api-.jar,tagsoup-.jar,xmlParserAPIs-.jar,xom-.jar java.library.path : /usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib java.vendor.url :http://java.oracle.com/ ld.library.path : /opt/gurobi752/linux64/lib/ java.vm.vendor : Oracle Corporation common.loader : "${catalina.base}/lib","${catalina.base}/lib/.jar","${catalina.home}/lib","${catalina.home}/lib/*.jar","/usr/local/gurobi605/linux64" java.runtime.name : OpenJDK Runtime Environment sun.java.command : org.apache.catalina.startup.Bootstrap start java.class.path : /opt/tomcat/bin/bootstrap.jar:/opt/tomcat/bin/tomcat-juli.jarjava.vm.specification.name : Java Virtual Machine Specification java.vm.specification.version : 1.8 catalina.home : /opt/tomcat sun.cpu.endian : little sun.os.patch.level : unknown java.awt.headless : true java.io.tmpdir : /opt/tomcat/temp java.vendor.url.bug : http://bugreport.sun.com/bugreport/ server.loader : "/opt/gurobi752/linux64/lib/gurobi.jar" os.arch : amd64 java.awt.graphicsenv : sun.awt.X11GraphicsEnvironment java.ext.dirs : /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.161-0.b14.el7_4.x86_64/jre/lib/ext:/usr/java/packages/lib/ext user.dir : / line.separator :java.vm.name : OpenJDK 64-Bit Server VM ignore.endorsed.dirs : file.encoding : UTF-8 java.specification.version : 1.8

回答1:

Any idea to solve the problem?

You can set LD_LIBRARY_PATH to point to the directory of Gurobi where the .so files are stored, and also the directory where the .jar files are stored.

You can also make Gurobi jar file accessible from Tomcat by copying or linking it.

ln -sv $GUROBI_HOME/lib/gurobi.jar $TOMCAT_HOME/lib/

Edit 1

try

declare -x LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${GUROBI_HOME}/lib"

instead of

declare -x LD_LIBRARY_PATH="\${LD_LIBRARY_PATH}:\${GUROBI_HOME}/lib"

There is a mistake by using \ , and you didn't copy/paste the official doc.

For further debugging, create a JSP with this content, it displays all System properties and we'll see java.library.path. It's weird nobody ever posted this before.

<%@ page import="java.util.Properties" %>
<%@ page import="java.util.Set" %>

<%
Properties p = System.getProperties();

Set<String> keys = p.stringPropertyNames();
for (String key : keys)
  out.println(key + " : " + p.getProperty(key));

%>

Edit 2

From your debug JSP we see that ld.library.path is correctly pointing to your GUROBI lib directory. We can try adding a System Property for java.library.path. In your Tomcat installation, edit or create bin/setenv.sh file with this content :

CATALINA_OPTS="-Djava.library.path=/opt/gurobi752/linux64/lib/"

An explanation to this suggestion can be read here.

btw I don't know where you put your declare -x , but it would be legitimate to store them in bin/setenv.sh