Hi there! I'm trying to build a docker container out of a java app I'm building which includes datalevin. Sadly, the build process is throwing these errors:
Exception java.lang.UnsatisfiedLinkError: no jniDTLV in java.library.path: /opt/java/openjdk/lib/server:/opt/java/openjdk/lib:/opt/java/openjdk/../lib:/usr/java/packages/lib:/usr/lib64:/lib64:/lib:/usr/lib
I'm using
FROM clojure:lein-2.10.0-alpine AS build
Is there something special I need to do? A specific native library that I'm missing? Or a specific JDK?Datalevin use JavaCPP to load native libraries. By default, JavaCPP extracts the native shared libraries from the Jar file and saves them to $HOME/.javacpp/cache directory, and load library from there.
You can change where JavaCPP extract the native libraries by passing a JVM system property, e.g. -Dorg.bytedeco.javacpp.cachedir=/your/custom/location
Native libraries needed by Datalevin are in the dtlvnative library jar, jar tf ~/.m2/repository/org/clojars/huahaiy/dtlvnative-linux-x86_64/0.11.4/dtlvnative-linux-x86_64-0.11.4.jar:
will print its content, and
META-INF/MANIFEST.MF
META-INF/maven/org.clojars.huahaiy/dtlvnative-linux-x86_64/pom.xml
META-INF/leiningen/org.clojars.huahaiy/dtlvnative-linux-x86_64/project.clj
META-INF/
META-INF/maven/
META-INF/maven/org.clojars.huahaiy/
META-INF/maven/org.clojars.huahaiy/dtlvnative-linux-x86_64/
META-INF/maven/org.clojars.huahaiy/dtlvnative-linux-x86_64/pom.properties
datalevin/
datalevin/dtlvnative/
datalevin/dtlvnative/DTLV$MDB_stat.class
datalevin/dtlvnative/DTLV$MDB_envinfo.class
datalevin/dtlvnative/DTLVConfig.class
datalevin/dtlvnative/DTLV$MDB_assert_func.class
datalevin/dtlvnative/DTLV.class
datalevin/dtlvnative/DTLV$dtlv_list_sample_iter.class
datalevin/dtlvnative/DTLV$MDB_msg_func.class
datalevin/dtlvnative/DTLV$dtlv_key_iter.class
datalevin/dtlvnative/DTLV$MDB_env.class
datalevin/dtlvnative/DTLV$dtlv_list_val_full_iter.class
datalevin/dtlvnative/DTLV$MDB_txn.class
datalevin/dtlvnative/DTLV$dtlv_list_val_iter.class
datalevin/dtlvnative/DTLV$MDB_cursor.class
datalevin/dtlvnative/DTLV$MDB_rel_func.class
datalevin/dtlvnative/DTLV$MDB_val.class
datalevin/dtlvnative/DTLV$dtlv_list_iter.class
datalevin/dtlvnative/DTLV$MDB_cmp_func.class
datalevin/dtlvnative/Test.class
datalevin/dtlvnative/linux-x86_64/
datalevin/dtlvnative/linux-x86_64/libdtlv.so
datalevin/dtlvnative/linux-x86_64/libjniDTLV.soYou will see two .so files at the end, libdtlv.so and libjniDTLV.so, that's the native libs needed. Make sure put them somewhere JavaCPP knows where to load them.
Since you are building a docker container, you have full control, so you can even put them into locations listed in the java.lang.UnsatisfiedLinkError message.
Finally, alpine linux may not be the best choice, for it doesn't install glibc by default. https://github.com/bytedeco/javacv/issues/1357
Switch to docker of different distro may help you.
debian, ubuntu, etc. should work
Ok thanks! If I get all excited about alpine I’ll see about adding glibc by hand. ☺️
Switched to Debian and it worked!
Sad to report something changed about either the docker container I'm using to build my project (`clojure:lein` which is debian-based) or the datalevin project itself, and now I'm getting these same unsatisfied link errors when running tests. If anybody has any pointers about using docker with datalevin I would be super appreciative! I wish I remembered what all I had installed on my local machine that makes everything work. Ha!
Downgrading datalevin to 0.9.20 seems to have fixed it. 😞 I'll keep trying to find the right combination so I don't have to use old versions.
Ok I found the right incantation. The debian combo with apt-get install libgomp1 no longer works. But the ubuntu combo with apt-get install g++-12 gcc-12 does work. Here's the docker stuff I had to change:
Index: Dockerfile
==================================================================
--- Dockerfile
+++ Dockerfile
@@ -1,10 +1,10 @@
-FROM clojure:lein AS build
+FROM clojure:temurin-21-lein-noble AS build
WORKDIR /root
COPY project.clj ./project.clj
RUN apt update
-RUN apt install -y bash git libsodium-dev
+RUN apt install -y bash git libsodium-dev g++-12 gcc-12
RUN apt clean
RUN lein deps
COPY src ./src
COPY test ./test
TLDR: switched dockerfile from debian to ubuntu and added explicit deps for g++/gcc and now can use latest datalevin lib again
https://clojurians.slack.com/archives/C01RD3AF336/p1743174251541709