# UnsatisfiedLinkError ( libjnind4jcpu.so, libopenblas\_nolapack.so ) running native app on linux

**URL:** <https://community.konduit.ai/t/unsatisfiedlinkerror-libjnind4jcpu-so-libopenblas-nolapack-so-running-native-app-on-linux/1341>\
**Category:** DL4J\
**Created:** [April 23, 2021, 7:28pm UTC](https://community.konduit.ai/t/unsatisfiedlinkerror-libjnind4jcpu-so-libopenblas-nolapack-so-running-native-app-on-linux/1341 "2021-04-23T19:28:07Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![AdityaPawade](https://yyz1.discourse-cdn.com/flex035/user_avatar/community.konduit.ai/adityapawade/32/524_2.png) [@AdityaPawade](https://community.konduit.ai/u/AdityaPawade)\
**Post date:** [April 23, 2021, 7:28pm UTC](https://community.konduit.ai/t/unsatisfiedlinkerror-libjnind4jcpu-so-libopenblas-nolapack-so-running-native-app-on-linux/1341/1 "2021-04-23T19:28:07Z")

</div>

Hi,

I am trying to create a native app using DL4J and GraalVM. My objective is to create a distributable executable with all the dependencies included so that Users can just download and run it with installing JRE, gcc, etc.

I am using the 1.0.0-SNAPSHOT versions of ND4J and DL4J since they contain the 1.5.5 version of JavaCPP which has GraalVM support.

This are how my dependencies look like :

```
* Maven: org.nd4j:nd4j-api:1.0.0-SNAPSHOT
* Maven: org.nd4j:nd4j-common:1.0.0-SNAPSHOT
* Maven: org.nd4j:nd4j-native:1.0.0-SNAPSHOT
* Maven: org.nd4j:nd4j-native:linux-x86_64:1.0.0-SNAPSHOT
* Maven: org.nd4j:nd4j-native:macosx-x86_64:1.0.0-SNAPSHOT
* Maven: org.nd4j:nd4j-native-api:1.0.0-SNAPSHOT
* Maven: org.nd4j:nd4j-native-platform:1.0.0-SNAPSHOT
* Maven: org.nd4j:nd4j-native-platform:linux-x86_64:1.0.0-SNAPSHOT
* Maven: org.nd4j:nd4j-native-preset:1.0.0-SNAPSHOT
* Maven: org.nd4j:nd4j-native-preset:linux-x86_64:1.0.0-SNAPSHOT
* Maven: org.nd4j:protobuf:1.0.0-SNAPSHOT
* Maven: org.bytedeco:hdf5:linux-x86_64:1.12.0-1.5.5
* Maven: org.bytedeco:hdf5-platform:1.12.0-1.5.5
* Maven: org.bytedeco:javacpp:1.5.5
* Maven: org.bytedeco:javacpp:linux-x86_64:1.5.5
* Maven: org.bytedeco:javacpp:macosx-x86_64:1.5.5
* Maven: org.bytedeco:javacpp-platform:1.5.5
* Maven: org.bytedeco:leptonica:linux-x86_64:1.80.0-1.5.5
* Maven: org.bytedeco:leptonica-platform:1.80.0-1.5.5
* Maven: org.bytedeco:mkl:2021.1-1.5.5
* Maven: org.bytedeco:mkl:linux-x86:2021.1-1.5.5
* Maven: org.bytedeco:mkl:linux-x86_64:2021.1-1.5.5
* Maven: org.bytedeco:mkl:macosx-x86_64:2021.1-1.5.5
* Maven: org.bytedeco:mkl:windows-x86:2021.1-1.5.5
* Maven: org.bytedeco:mkl:windows-x86_64:2021.1-1.5.5
* Maven: org.bytedeco:mkl-platform:2021.1-1.5.5
* Maven: org.bytedeco:openblas:0.3.13-1.5.5
* Maven: org.bytedeco:openblas:linux-x86_64:0.3.13-1.5.5
* Maven: org.bytedeco:openblas:macosx-x86_64:0.3.13-1.5.5
* Maven: org.bytedeco:openblas-platform:0.3.13-1.5.5
* Maven: org.bytedeco:opencv:linux-x86_64:4.5.1-1.5.5
* Maven: org.bytedeco:opencv-platform:4.5.1-1.5.5
* Maven: org.deeplearning4j:deeplearning4j-common:1.0.0-SNAPSHOT
* Maven: org.deeplearning4j:deeplearning4j-core:1.0.0-SNAPSHOT
* Maven: org.deeplearning4j:deeplearning4j-datasets:1.0.0-SNAPSHOT
* Maven: org.deeplearning4j:deeplearning4j-datavec-iterators:1.0.0-SNAPSHOT
* Maven: org.deeplearning4j:deeplearning4j-modelimport:1.0.0-SNAPSHOT
* Maven: org.deeplearning4j:deeplearning4j-nn:1.0.0-SNAPSHOT
* Maven: org.deeplearning4j:deeplearning4j-ui-components:1.0.0-SNAPSHOT
* Maven: org.deeplearning4j:deeplearning4j-utility-iterators:1.0.0-SNAPSHOT

```

This is how my resource config looks like :

```
{
  "resources":{
  "includes":[
    {"pattern":"\\QMETA-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat\\E"}, 
    {"pattern":"\\QMETA-INF/services/org.apache.logging.log4j.core.util.ContextDataProvider\\E"}, 
    {"pattern":"\\QMETA-INF/services/org.apache.logging.log4j.spi.Provider\\E"}, 
    {"pattern":"\\QMETA-INF/services/org.apache.logging.log4j.util.PropertySource\\E"}, 
    {"pattern":"\\QMETA-INF/services/org.eclipse.jetty.http.HttpFieldPreEncoder\\E"}, 
    {"pattern":"\\QMETA-INF/services/org.eclipse.jetty.websocket.api.extensions.Extension\\E"}, 
    {"pattern":"\\QMETA-INF/services/org.nd4j.common.base.PreconditionsFormat\\E"}, 
    {"pattern":"\\QMETA-INF/services/org.nd4j.linalg.compression.NDArrayCompressor\\E"}, 
    {"pattern":"\\QMETA-INF/services/org.nd4j.linalg.env.EnvironmentalAction\\E"}, 
    {"pattern":"\\QMETA-INF/services/org.nd4j.linalg.factory.Nd4jBackend\\E"}, 
    {"pattern":"\\Qlog4j2.xml\\E"}, 
    {"pattern":"\\Qnd4j-native.properties\\E"}, 
    {"pattern":"\\Qorg/bytedeco/javacpp/linux-x86_64/libjnijavacpp.so\\E"}, 
    {"pattern":"\\Qorg/bytedeco/javacpp/properties/linux-x86_64.properties\\E"}, 
    {"pattern":"\\Qorg/bytedeco/openblas/linux-x86_64/libgcc_s.so.1\\E"}, 
    {"pattern":"\\Qorg/bytedeco/openblas/linux-x86_64/libgfortran.so.4\\E"}, 
    {"pattern":"\\Qorg/bytedeco/openblas/linux-x86_64/libjniopenblas.so\\E"}, 
    {"pattern":"\\Qorg/bytedeco/openblas/linux-x86_64/libjniopenblas_nolapack.so\\E"}, 
    {"pattern":"\\Qorg/bytedeco/openblas/linux-x86_64/libopenblas.so.0\\E"}, 
    {"pattern":"\\Qorg/bytedeco/openblas/linux-x86_64/libquadmath.so.0\\E"}, 
    {"pattern":"\\Qorg/eclipse/jetty/http/encoding.properties\\E"}, 
    {"pattern":"\\Qorg/eclipse/jetty/http/mime.properties\\E"}, 
    {"pattern":"\\Qorg/eclipse/jetty/version/build.properties\\E"}, 
    {"pattern":"\\Qorg/nd4j/nativeblas/linux-x86_64/libjnind4jcpu.so\\E"}, 
    {"pattern":"\\Qorg/nd4j/nativeblas/linux-x86_64/libnd4jcpu.so\\E"}, 
    {"pattern":"\\Qorg/slf4j/impl/StaticLoggerBinder.class\\E"}
  ]},
  "bundles":[
    {"name":"javax.servlet.LocalStrings"}, 
    {"name":"javax.servlet.http.LocalStrings"}
  ]
}

```

I am able to build a native image using GraalVM for my project in a linux debian 8 docker image with libstdc+±8-dev installed. Following is the docker file :

```
RUN apt-get update && \
    apt-get install -y --force-yes gcc libz-dev upx libstdc++-8-dev

ARG VERSION=21.1.0
RUN wget https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-$VERSION/graalvm-ce-java11-linux-amd64-$VERSION.tar.gz && \
    tar -xvzf graalvm-ce-java11-linux-amd64-$VERSION.tar.gz && \
    rm graalvm-ce-java11-linux-amd64-$VERSION.tar.gz && \
    /graalvm-ce-java11-$VERSION/bin/gu install native-image
    
RUN wget http://www.eu.apache.org/dist/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.tar.gz && \
    tar -xzvf apache-maven-3.3.9-bin.tar.gz -C /var/lib/ && \
    rm apache-maven-3.3.9-bin.tar.gz
    
RUN apt-get update && \
    apt-get install -y --force-yes build-essential
    
ARG RESULT_LIB="/var/lib/static"

RUN mkdir ${RESULT_LIB} && \
    curl -L -o musl.tar.gz https://musl.libc.org/releases/musl-1.2.1.tar.gz && \
    mkdir musl && tar -xvzf musl.tar.gz -C musl --strip-components 1 && cd musl && \
    ./configure --disable-shared --prefix=${RESULT_LIB} && \
    make && make install && \
    cd / && rm -rf /muscl && rm -f /musl.tar.gz && \
    cp /usr/lib/gcc/x86_64-linux-gnu/8/libstdc++.a ${RESULT_LIB}/lib/

ENV PATH="$PATH:${RESULT_LIB}/bin"
ENV CC="musl-gcc"

RUN curl -L -o zlib.tar.gz https://zlib.net/zlib-1.2.11.tar.gz && \
   mkdir zlib && tar -xvzf zlib.tar.gz -C zlib --strip-components 1 && cd zlib && \
   ./configure --static --prefix=${RESULT_LIB} && \
    make && make install && \
    cd / && rm -rf /zlib && rm -f /zlib.tar.gz

ENV CC="musl-gcc"
ENV M2_HOME=/var/lib/apache-maven-3.3.9
ENV PATH=/graalvm-ce-java11-$VERSION/bin:/var/lib/apache-maven-3.3.9/bin:$PATH

```

However, when I try to execute the native binary on my production linux server without libstdc installed, I am getting UnsatisfiedLinkError

 ![Screenshot 2021-04-24 at 12.11.07 AM](https://canada1.discourse-cdn.com/flex035/uploads/konduit/original/1X/6acac8999f7f0acfc128d0ea2bf9b41526c96eae.jpeg)

This is inspite of the file being present in the specified location and in the jar resources

```
root@04af621a9001:~/.javacpp/cache/linux-x86_64# ls -lah
total 269M
drwxr-xr-x 2 root root 4.0K Apr 23 19:16 .
drwxr-xr-x 3 root root 4.0K Apr 23 19:16 ..
lrwxrwxrwx 1 root root 13 Apr 23 19:16 libgcc_s.so -> libgcc_s.so.1
-rw-r--r-- 1 root root 89K Jan 1 1970 libgcc_s.so.1
lrwxrwxrwx 1 root root 16 Apr 23 19:16 libgfortran.so -> libgfortran.so.4
-rw-r--r-- 1 root root 1.5M Jan 1 1970 libgfortran.so.4
-rw-r--r-- 1 root root 55K Jan 1 1970 libjnijavacpp.so
-rw-r--r-- 1 root root 3.2M Jan 1 1970 libjnind4jcpu.so
-rw-r--r-- 1 root root 25M Jan 1 1970 libjniopenblas.so
-rw-r--r-- 1 root root 300K Jan 1 1970 libjniopenblas_nolapack.so
-rw-r--r-- 1 root root 181M Jan 1 1970 libnd4jcpu.so
lrwxrwxrwx 1 root root 16 Apr 23 19:16 libopenblas.so -> libopenblas.so.0
-rw-r--r-- 1 root root 30M Jan 1 1970 libopenblas.so.0
lrwxrwxrwx 1 root root 25 Apr 23 19:16 libopenblas_nolapack.so -> libopenblas_nolapack.so.0
-rw-r--r-- 1 root root 30M Jan 1 1970 libopenblas_nolapack.so.0
lrwxrwxrwx 1 root root 16 Apr 23 19:16 libquadmath.so -> libquadmath.so.0
-rw-r--r-- 1 root root 253K Jan 1 1970 libquadmath.so.0
root@04af621a9001:~/.javacpp/cache/linux-x86_64#

```

Then I tried creating native image using --static flag with musl as libc ( details mentioned in the docker file ), assuming issues were due to CPP libraries not being present on the machine and native image relying on dynamic linking.  
I was following this blog : [GraalVM Native Image Tips & Tricks - James Ward](https://jamesward.com/2020/05/07/graalvm-native-image-tips-tricks/)  
After doing this change, the application started giving the same error about libopenblas\_nolapack.so library, again which is present in the given path

Error :  
Caused by: java.lang.UnsatisfiedLinkError: Can’t load library: /root/.javacpp/cache/linux-x86\_64/libjniopenblas\_nolapack.so

> **[Screenshot-2021-04-23-at-9-35-11-AM](https://ibb.co/hs2S0tp)**
>
> Image Screenshot-2021-04-23-at-9-35-11-AM in Aditya Pawade's images album

So I wanted to know what I am missing. I am able to see the missing files in my fat jar, in my resource config, in my external dependencies so my thought is that it would not be due to some misconfigured pom.

---

<div class="post-metadata">

**Author:** ![agibsonccc](https://yyz1.discourse-cdn.com/flex035/user_avatar/community.konduit.ai/agibsonccc/32/697_2.png) [@agibsonccc](https://community.konduit.ai/u/agibsonccc)\
**Post date:** [April 24, 2021, 1:54am UTC](https://community.konduit.ai/t/unsatisfiedlinkerror-libjnind4jcpu-so-libopenblas-nolapack-so-running-native-app-on-linux/1341/2 "2021-04-24T01:54:48Z")

</div>

@AdityaPawade can you DM me? I have a proof of concept with dl4j + graalvm, but it’s not ready for general use yet. It will involve using snapshots, not the current beta7 release though. If you’re fine with that, please let me know.

---

<div class="post-metadata">

**Author:** ![AdityaPawade](https://yyz1.discourse-cdn.com/flex035/user_avatar/community.konduit.ai/adityapawade/32/524_2.png) [@AdityaPawade](https://community.konduit.ai/u/AdityaPawade)\
**Post date:** [April 24, 2021, 4:17am UTC](https://community.konduit.ai/t/unsatisfiedlinkerror-libjnind4jcpu-so-libopenblas-nolapack-so-running-native-app-on-linux/1341/3 "2021-04-24T04:17:46Z")

</div>

Hi @agibsonccc ,

Thanks for replying. Yes I am ok with using Snapshots.

Due to the following bug : [[TensorFlow] No Java runtime present, requesting install · Issue #417 · bytedeco/javacpp · GitHub](https://github.com/bytedeco/javacpp/issues/417)  
I have already shifted to using snapshots since after moving to JavaCPP 1.5.5, there hasn’t been a beta launch.  
I am using 1.0.0-SNAPSHOT version of DL4J and ND4J and 1.5.5 version of JavaCPP

Please let me know what can be done. Sorry could not find the option to DM
