diff --git a/Makefile b/Makefile
index 1b72e947b..3b0ddffee 100644
--- a/Makefile
+++ b/Makefile
@@ -1731,12 +1731,23 @@ else
ARCH := $(shell getconf LONG_BIT)
endif
-ifneq (,$(filter ppc% arm64 aarch64 sparc64, $(MACHINE)))
- ROCKSDBJNILIB = librocksdbjni-linux-$(MACHINE).so
-else
- ROCKSDBJNILIB = librocksdbjni-linux$(ARCH).so
+ifeq ($(shell ldd /usr/bin/env 2>/dev/null | grep -q musl; echo $$?),0)
+ JNI_LIBC = musl
+# GNU LibC (or glibc) is so pervasive we can assume it is the default
+# else
+# JNI_LIBC = glibc
endif
-ROCKSDB_JAR = rocksdbjni-$(ROCKSDB_MAJOR).$(ROCKSDB_MINOR).$(ROCKSDB_PATCH)-linux$(ARCH).jar
+
+ifneq ($(origin JNI_LIBC), undefined)
+ JNI_LIBC_POSTFIX = -$(JNI_LIBC)
+endif
+
+ifneq (,$(filter ppc% arm64 aarch64 sparc64, $(MACHINE)))
+ ROCKSDBJNILIB = librocksdbjni-linux-$(MACHINE)$(JNI_LIBC_POSTFIX).so
+else
+ ROCKSDBJNILIB = librocksdbjni-linux$(ARCH)$(JNI_LIBC_POSTFIX).so
+endif
+ROCKSDB_JAR = rocksdbjni-$(ROCKSDB_MAJOR).$(ROCKSDB_MINOR).$(ROCKSDB_PATCH)-linux$(ARCH)$(JNI_LIBC_POSTFIX).jar
ROCKSDB_JAR_ALL = rocksdbjni-$(ROCKSDB_MAJOR).$(ROCKSDB_MINOR).$(ROCKSDB_PATCH).jar
ROCKSDB_JAVADOCS_JAR = rocksdbjni-$(ROCKSDB_MAJOR).$(ROCKSDB_MINOR).$(ROCKSDB_PATCH)-javadoc.jar
ROCKSDB_SOURCES_JAR = rocksdbjni-$(ROCKSDB_MAJOR).$(ROCKSDB_MINOR).$(ROCKSDB_PATCH)-sources.jar
@@ -1910,12 +1921,12 @@ rocksdbjavastatic: $(java_static_all_libobjects)
cd java/src/main/java;jar -cf ../../../target/$(ROCKSDB_SOURCES_JAR) org
rocksdbjavastaticrelease: rocksdbjavastatic
- cd java/crossbuild && vagrant destroy -f && vagrant up linux32 && vagrant halt linux32 && vagrant up linux64 && vagrant halt linux64
+ cd java/crossbuild && (vagrant destroy -f || true) && vagrant up linux32 && vagrant halt linux32 && vagrant up linux64 && vagrant halt linux64 && vagrant up linux64-musl && vagrant halt linux64-musl
cd java;jar -cf target/$(ROCKSDB_JAR_ALL) HISTORY*.md
cd java/target;jar -uf $(ROCKSDB_JAR_ALL) librocksdbjni-*.so librocksdbjni-*.jnilib
cd java/target/classes;jar -uf ../$(ROCKSDB_JAR_ALL) org/rocksdb/*.class org/rocksdb/util/*.class
-rocksdbjavastaticreleasedocker: rocksdbjavastatic rocksdbjavastaticdockerx86 rocksdbjavastaticdockerx86_64
+rocksdbjavastaticreleasedocker: rocksdbjavastatic rocksdbjavastaticdockerx86 rocksdbjavastaticdockerx86_64 rocksdbjavastaticdockerx86musl rocksdbjavastaticdockerx86_64musl
cd java;jar -cf target/$(ROCKSDB_JAR_ALL) HISTORY*.md
cd java/target;jar -uf $(ROCKSDB_JAR_ALL) librocksdbjni-*.so librocksdbjni-*.jnilib
cd java/target/classes;jar -uf ../$(ROCKSDB_JAR_ALL) org/rocksdb/*.class org/rocksdb/util/*.class
@@ -1936,6 +1947,22 @@ rocksdbjavastaticdockerarm64v8:
mkdir -p java/target
docker run --rm --name rocksdb_linux_arm64v8-be --attach stdin --attach stdout --attach stderr --volume `pwd`:/rocksdb-host:ro --volume /rocksdb-local-build --volume `pwd`/java/target:/rocksdb-java-target --env DEBUG_LEVEL=$(DEBUG_LEVEL) evolvedbinary/rocksjava:centos7_arm64v8-be /rocksdb-host/java/crossbuild/docker-build-linux-centos.sh
+rocksdbjavastaticdockerx86musl:
+ mkdir -p java/target
+ docker run --rm --name rocksdb_linux_x86-musl-be --attach stdin --attach stdout --attach stderr --volume `pwd`:/rocksdb-host:ro --volume /rocksdb-local-build --volume `pwd`/java/target:/rocksdb-java-target --env DEBUG_LEVEL=$(DEBUG_LEVEL) evolvedbinary/rocksjava:alpine3_x86-be /rocksdb-host/java/crossbuild/docker-build-linux-centos.sh
+
+rocksdbjavastaticdockerx86_64musl:
+ mkdir -p java/target
+ docker run --rm --name rocksdb_linux_x64-musl-be --attach stdin --attach stdout --attach stderr --volume `pwd`:/rocksdb-host:ro --volume /rocksdb-local-build --volume `pwd`/java/target:/rocksdb-java-target --env DEBUG_LEVEL=$(DEBUG_LEVEL) evolvedbinary/rocksjava:alpine3_x64-be /rocksdb-host/java/crossbuild/docker-build-linux-centos.sh
+
+rocksdbjavastaticdockerppc64lemusl:
+ mkdir -p java/target
+ docker run --rm --name rocksdb_linux_ppc64le-musl-be --attach stdin --attach stdout --attach stderr --volume `pwd`:/rocksdb-host:ro --volume /rocksdb-local-build --volume `pwd`/java/target:/rocksdb-java-target --env DEBUG_LEVEL=$(DEBUG_LEVEL) evolvedbinary/rocksjava:alpine3_ppc64le-be /rocksdb-host/java/crossbuild/docker-build-linux-centos.sh
+
+rocksdbjavastaticdockerarm64v8musl:
+ mkdir -p java/target
+ docker run --rm --name rocksdb_linux_arm64v8-musl-be --attach stdin --attach stdout --attach stderr --volume `pwd`:/rocksdb-host:ro --volume /rocksdb-local-build --volume `pwd`/java/target:/rocksdb-java-target --env DEBUG_LEVEL=$(DEBUG_LEVEL) evolvedbinary/rocksjava:alpine3_arm64v8-be /rocksdb-host/java/crossbuild/docker-build-linux-centos.sh
+
rocksdbjavastaticpublish: rocksdbjavastaticrelease rocksdbjavastaticpublishcentral
rocksdbjavastaticpublishdocker: rocksdbjavastaticreleasedocker rocksdbjavastaticpublishcentral
@@ -1945,6 +1972,8 @@ rocksdbjavastaticpublishcentral:
mvn gpg:sign-and-deploy-file -Durl=https://oss.sonatype.org/service/local/staging/deploy/maven2/ -DrepositoryId=sonatype-nexus-staging -DpomFile=java/rocksjni.pom -Dfile=java/target/rocksdbjni-$(ROCKSDB_MAJOR).$(ROCKSDB_MINOR).$(ROCKSDB_PATCH)-sources.jar -Dclassifier=sources
mvn gpg:sign-and-deploy-file -Durl=https://oss.sonatype.org/service/local/staging/deploy/maven2/ -DrepositoryId=sonatype-nexus-staging -DpomFile=java/rocksjni.pom -Dfile=java/target/rocksdbjni-$(ROCKSDB_MAJOR).$(ROCKSDB_MINOR).$(ROCKSDB_PATCH)-linux64.jar -Dclassifier=linux64
mvn gpg:sign-and-deploy-file -Durl=https://oss.sonatype.org/service/local/staging/deploy/maven2/ -DrepositoryId=sonatype-nexus-staging -DpomFile=java/rocksjni.pom -Dfile=java/target/rocksdbjni-$(ROCKSDB_MAJOR).$(ROCKSDB_MINOR).$(ROCKSDB_PATCH)-linux32.jar -Dclassifier=linux32
+ mvn gpg:sign-and-deploy-file -Durl=https://oss.sonatype.org/service/local/staging/deploy/maven2/ -DrepositoryId=sonatype-nexus-staging -DpomFile=java/rocksjni.pom -Dfile=java/target/rocksdbjni-$(ROCKSDB_MAJOR).$(ROCKSDB_MINOR).$(ROCKSDB_PATCH)-linux64-musl.jar -Dclassifier=linux64-musl
+ mvn gpg:sign-and-deploy-file -Durl=https://oss.sonatype.org/service/local/staging/deploy/maven2/ -DrepositoryId=sonatype-nexus-staging -DpomFile=java/rocksjni.pom -Dfile=java/target/rocksdbjni-$(ROCKSDB_MAJOR).$(ROCKSDB_MINOR).$(ROCKSDB_PATCH)-linux32-musl.jar -Dclassifier=linux32-musl
mvn gpg:sign-and-deploy-file -Durl=https://oss.sonatype.org/service/local/staging/deploy/maven2/ -DrepositoryId=sonatype-nexus-staging -DpomFile=java/rocksjni.pom -Dfile=java/target/rocksdbjni-$(ROCKSDB_MAJOR).$(ROCKSDB_MINOR).$(ROCKSDB_PATCH)-osx.jar -Dclassifier=osx
mvn gpg:sign-and-deploy-file -Durl=https://oss.sonatype.org/service/local/staging/deploy/maven2/ -DrepositoryId=sonatype-nexus-staging -DpomFile=java/rocksjni.pom -Dfile=java/target/rocksdbjni-$(ROCKSDB_MAJOR).$(ROCKSDB_MINOR).$(ROCKSDB_PATCH)-win64.jar -Dclassifier=win64
mvn gpg:sign-and-deploy-file -Durl=https://oss.sonatype.org/service/local/staging/deploy/maven2/ -DrepositoryId=sonatype-nexus-staging -DpomFile=java/rocksjni.pom -Dfile=java/target/rocksdbjni-$(ROCKSDB_MAJOR).$(ROCKSDB_MINOR).$(ROCKSDB_PATCH).jar
diff --git a/java/RELEASE.md b/java/RELEASE.md
index 65da3d83a..dda19455f 100644
--- a/java/RELEASE.md
+++ b/java/RELEASE.md
@@ -4,28 +4,33 @@ RocksDB can be built as a single self contained cross-platform JAR. The cross-pl
Building a cross-platform JAR requires:
- * [Vagrant](https://www.vagrantup.com/)
- * [Virtualbox](https://www.virtualbox.org/)
+ * [Docker](https://www.docker.com/docker-community)
* A Mac OSX machine that can compile RocksDB.
* Java 7 set as JAVA_HOME.
Once you have these items, run this make command from RocksDB's root source directory:
- make jclean clean rocksdbjavastaticrelease
+ make jclean clean rocksdbjavastaticreleasedocker
-This command will build RocksDB natively on OSX, and will then spin up two Vagrant Virtualbox Ubuntu images to build RocksDB for both 32-bit and 64-bit Linux.
+This command will build RocksDB natively on OSX, and will then spin up docker containers to build RocksDB for 32-bit and 64-bit Linux with glibc, and 32-bit and 64-bit Linux with musl libc.
You can find all native binaries and JARs in the java/target directory upon completion:
librocksdbjni-linux32.so
librocksdbjni-linux64.so
+ librocksdbjni-linux64-musl.so
+ librocksdbjni-linux32-musl.so
librocksdbjni-osx.jnilib
- rocksdbjni-3.5.0-javadoc.jar
- rocksdbjni-3.5.0-linux32.jar
- rocksdbjni-3.5.0-linux64.jar
- rocksdbjni-3.5.0-osx.jar
- rocksdbjni-3.5.0-sources.jar
- rocksdbjni-3.5.0.jar
+ rocksdbjni-x.y.z-javadoc.jar
+ rocksdbjni-x.y.z-linux32.jar
+ rocksdbjni-x.y.z-linux64.jar
+ rocksdbjni-x.y.z-linux64-musl.jar
+ rocksdbjni-x.y.z-linux32-musl.jar
+ rocksdbjni-x.y.z-osx.jar
+ rocksdbjni-x.y.z-sources.jar
+ rocksdbjni-x.y.z.jar
+
+Where x.y.z is the built version number of RocksDB.
## Maven publication
diff --git a/java/crossbuild/Vagrantfile b/java/crossbuild/Vagrantfile
index 48ab03f80..0ee50de2c 100644
--- a/java/crossbuild/Vagrantfile
+++ b/java/crossbuild/Vagrantfile
@@ -8,10 +8,28 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.define "linux32" do |linux32|
linux32.vm.box = "bento/centos-6.10-i386"
+ linux32.vm.provision :shell, path: "build-linux-centos.sh"
end
config.vm.define "linux64" do |linux64|
linux64.vm.box = "bento/centos-6.10"
+ linux64.vm.provision :shell, path: "build-linux-centos.sh"
+ end
+
+ config.vm.define "linux32-musl" do |musl32|
+ musl32.vm.box = "alpine/alpine32"
+ musl32.vm.box_version = "3.6.0"
+ musl32.vm.provision :shell, path: "build-linux-alpine.sh"
+ end
+
+ config.vm.define "linux64-musl" do |musl64|
+ musl64.vm.box = "generic/alpine36"
+
+ ## Should use the alpine/alpine64 box, but this issue needs to be fixed first - https://github.com/hashicorp/vagrant/issues/11218
+ # musl64.vm.box = "alpine/alpine64"
+ # musl64.vm.box_version = "3.6.0"
+
+ musl64.vm.provision :shell, path: "build-linux-alpine.sh"
end
config.vm.provider "virtualbox" do |v|
@@ -20,7 +38,13 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
v.customize ["modifyvm", :id, "--nictype1", "virtio" ]
end
- config.vm.provision :shell, path: "build-linux-centos.sh"
+ if Vagrant.has_plugin?("vagrant-cachier")
+ config.cache.scope = :box
+ end
+ if Vagrant.has_plugin?("vagrant-vbguest")
+ config.vbguest.no_install = true
+ end
+
config.vm.synced_folder "../target", "/rocksdb-build"
config.vm.synced_folder "../..", "/rocksdb", type: "rsync"
config.vm.boot_timeout = 1200
diff --git a/java/crossbuild/build-linux-alpine.sh b/java/crossbuild/build-linux-alpine.sh
new file mode 100755
index 000000000..561d34141
--- /dev/null
+++ b/java/crossbuild/build-linux-alpine.sh
@@ -0,0 +1,70 @@
+#!/usr/bin/env bash
+# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
+
+set -e
+
+# update Alpine with latest versions
+echo '@edge http://nl.alpinelinux.org/alpine/edge/main' >> /etc/apk/repositories
+echo '@community http://nl.alpinelinux.org/alpine/edge/community' >> /etc/apk/repositories
+apk update
+apk upgrade
+
+# install CA certificates
+apk add ca-certificates
+
+# install build tools
+apk add \
+ build-base \
+ coreutils \
+ file \
+ git \
+ perl \
+ automake \
+ autoconf \
+ cmake
+
+# install tool dependencies for building RocksDB static library
+apk add \
+ curl \
+ bash \
+ wget \
+ tar \
+ openssl
+
+# install RocksDB dependencies
+apk add \
+ snappy snappy-dev \
+ zlib zlib-dev \
+ bzip2 bzip2-dev \
+ lz4 lz4-dev \
+ zstd zstd-dev \
+ linux-headers \
+ jemalloc jemalloc-dev
+
+# install OpenJDK7
+apk add openjdk7 \
+ && apk add java-cacerts \
+ && rm /usr/lib/jvm/java-1.7-openjdk/jre/lib/security/cacerts \
+ && ln -s /etc/ssl/certs/java/cacerts /usr/lib/jvm/java-1.7-openjdk/jre/lib/security/cacerts
+
+# cleanup
+rm -rf /var/cache/apk/*
+
+# puts javac in the PATH
+export JAVA_HOME=/usr/lib/jvm/java-1.7-openjdk
+export PATH=/usr/lib/jvm/java-1.7-openjdk/bin:$PATH
+
+# gflags from source
+cd /tmp &&\
+ git clone -b v2.0 --single-branch https://github.com/gflags/gflags.git &&\
+ cd gflags &&\
+ ./configure --prefix=/usr && make && make install &&\
+ rm -rf /tmp/*
+
+
+# build rocksdb
+cd /rocksdb
+make jclean clean
+PORTABLE=1 make -j8 rocksdbjavastatic
+cp /rocksdb/java/target/librocksdbjni-* /rocksdb-build
+cp /rocksdb/java/target/rocksdbjni-* /rocksdb-build
diff --git a/java/crossbuild/docker-build-linux-alpine.sh b/java/crossbuild/docker-build-linux-alpine.sh
new file mode 100755
index 000000000..e605c7716
--- /dev/null
+++ b/java/crossbuild/docker-build-linux-alpine.sh
@@ -0,0 +1,18 @@
+#!/usr/bin/env bash
+# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
+
+set -e
+#set -x
+
+# just in-case this is run outside Docker
+mkdir -p /rocksdb-local-build
+
+rm -rf /rocksdb-local-build/*
+cp -r /rocksdb-host/* /rocksdb-local-build
+cd /rocksdb-local-build
+
+make clean-not-downloaded
+PORTABLE=1 make rocksdbjavastatic
+
+cp java/target/librocksdbjni-linux*.so java/target/rocksdbjni-*-linux*.jar /rocksdb-java-target
+
diff --git a/java/crossbuild/docker-build-linux-centos.sh b/java/crossbuild/docker-build-linux-centos.sh
index 33fcff955..c4217785f 100755
--- a/java/crossbuild/docker-build-linux-centos.sh
+++ b/java/crossbuild/docker-build-linux-centos.sh
@@ -14,19 +14,19 @@ cd /rocksdb-local-build
# Use scl devtoolset if available
if hash scl 2>/dev/null; then
if scl --list | grep -q 'devtoolset-7'; then
- # CentOS 7+
- scl enable devtoolset-7 'make clean-not-downloaded'
+ # CentOS 7+
+ scl enable devtoolset-7 'make clean-not-downloaded'
scl enable devtoolset-7 'PORTABLE=1 make -j2 rocksdbjavastatic'
elif scl --list | grep -q 'devtoolset-2'; then
- # CentOS 5 or 6
- scl enable devtoolset-2 'make clean-not-downloaded'
+ # CentOS 5 or 6
+ scl enable devtoolset-2 'make clean-not-downloaded'
scl enable devtoolset-2 'PORTABLE=1 make -j2 rocksdbjavastatic'
else
echo "Could not find devtoolset"
exit 1;
fi
else
- make clean-not-downloaded
+ make clean-not-downloaded
PORTABLE=1 make -j2 rocksdbjavastatic
fi
diff --git a/java/rocksjni.pom b/java/rocksjni.pom
index 94f07551c..5defdca7d 100644
--- a/java/rocksjni.pom
+++ b/java/rocksjni.pom
@@ -10,7 +10,7 @@
rocksdbjni
-
- RocksDB fat jar that contains .so files for linux32 and linux64, jnilib files
+ RocksDB fat jar that contains .so files for linux32 and linux64 (glibc and musl-libc), jnilib files
for Mac OSX, and a .dll for Windows x64.
diff --git a/java/src/main/java/org/rocksdb/util/Environment.java b/java/src/main/java/org/rocksdb/util/Environment.java
index bac1c559a..b5de34b75 100644
--- a/java/src/main/java/org/rocksdb/util/Environment.java
+++ b/java/src/main/java/org/rocksdb/util/Environment.java
@@ -1,9 +1,22 @@
// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
package org.rocksdb.util;
+import java.io.File;
+import java.io.IOException;
+
public class Environment {
private static String OS = System.getProperty("os.name").toLowerCase();
private static String ARCH = System.getProperty("os.arch").toLowerCase();
+ private static boolean MUSL_LIBC;
+
+ static {
+ try {
+ final Process p = new ProcessBuilder("/usr/bin/env", "sh", "-c", "ldd /usr/bin/env | grep -q musl").start();
+ MUSL_LIBC = p.waitFor() == 0;
+ } catch (final IOException | InterruptedException e) {
+ MUSL_LIBC = false;
+ }
+ }
public static boolean isAarch64() {
return ARCH.contains("aarch64");
@@ -38,6 +51,10 @@ public class Environment {
OS.contains("nux");
}
+ public static boolean isMuslLibc() {
+ return MUSL_LIBC;
+ }
+
public static boolean isSolaris() {
return OS.contains("sunos");
}
@@ -61,15 +78,37 @@ public class Environment {
return appendLibOsSuffix("lib" + getSharedLibraryName(name), true);
}
+ /**
+ * Get the name of the libc implementation
+ *
+ * @return the name of the implementation,
+ * or null if the default for that platform (e.g. glibc on Linux).
+ */
+ public static /* @Nullable */ String getLibcName() {
+ if (isMuslLibc()) {
+ return "musl";
+ } else {
+ return null;
+ }
+ }
+
+ private static String getLibcPostfix() {
+ final String libcName = getLibcName();
+ if (libcName == null) {
+ return "";
+ }
+ return "-" + libcName;
+ }
+
public static String getJniLibraryName(final String name) {
if (isUnix()) {
final String arch = is64Bit() ? "64" : "32";
if (isPowerPC() || isAarch64()) {
- return String.format("%sjni-linux-%s", name, ARCH);
+ return String.format("%sjni-linux-%s%s", name, ARCH, getLibcPostfix());
} else if (isS390x()) {
return String.format("%sjni-linux%s", name, ARCH);
} else {
- return String.format("%sjni-linux%s", name, arch);
+ return String.format("%sjni-linux%s%s", name, arch, getLibcPostfix());
}
} else if (isMac()) {
return String.format("%sjni-osx", name);
diff --git a/java/src/test/java/org/rocksdb/util/EnvironmentTest.java b/java/src/test/java/org/rocksdb/util/EnvironmentTest.java
index ff13ddb5d..ab0ff2027 100644
--- a/java/src/test/java/org/rocksdb/util/EnvironmentTest.java
+++ b/java/src/test/java/org/rocksdb/util/EnvironmentTest.java
@@ -16,14 +16,17 @@ import static org.assertj.core.api.Assertions.assertThat;
public class EnvironmentTest {
private final static String ARCH_FIELD_NAME = "ARCH";
private final static String OS_FIELD_NAME = "OS";
+ private final static String MUSL_LIBC_FIELD_NAME = "MUSL_LIBC";
private static String INITIAL_OS;
private static String INITIAL_ARCH;
+ private static boolean INITIAL_MUSL_LIBC;
@BeforeClass
public static void saveState() {
INITIAL_ARCH = getEnvironmentClassField(ARCH_FIELD_NAME);
INITIAL_OS = getEnvironmentClassField(OS_FIELD_NAME);
+ INITIAL_MUSL_LIBC = getEnvironmentClassField(MUSL_LIBC_FIELD_NAME);
}
@Test
@@ -53,6 +56,7 @@ public class EnvironmentTest {
@Test
public void nix32() {
// Linux
+ setEnvironmentClassField(MUSL_LIBC_FIELD_NAME, false);
setEnvironmentClassFields("Linux", "32");
assertThat(Environment.isWindows()).isFalse();
assertThat(Environment.getJniLibraryExtension()).
@@ -61,7 +65,17 @@ public class EnvironmentTest {
isEqualTo("librocksdbjni-linux32.so");
assertThat(Environment.getSharedLibraryFileName("rocksdb")).
isEqualTo("librocksdbjni.so");
+ // Linux musl-libc (Alpine)
+ setEnvironmentClassField(MUSL_LIBC_FIELD_NAME, true);
+ assertThat(Environment.isWindows()).isFalse();
+ assertThat(Environment.getJniLibraryExtension()).
+ isEqualTo(".so");
+ assertThat(Environment.getJniLibraryFileName("rocksdb")).
+ isEqualTo("librocksdbjni-linux32-musl.so");
+ assertThat(Environment.getSharedLibraryFileName("rocksdb")).
+ isEqualTo("librocksdbjni.so");
// UNIX
+ setEnvironmentClassField(MUSL_LIBC_FIELD_NAME, false);
setEnvironmentClassFields("Unix", "32");
assertThat(Environment.isWindows()).isFalse();
assertThat(Environment.getJniLibraryExtension()).
@@ -84,6 +98,7 @@ public class EnvironmentTest {
@Test
public void nix64() {
+ setEnvironmentClassField(MUSL_LIBC_FIELD_NAME, false);
setEnvironmentClassFields("Linux", "x64");
assertThat(Environment.isWindows()).isFalse();
assertThat(Environment.getJniLibraryExtension()).
@@ -92,7 +107,17 @@ public class EnvironmentTest {
isEqualTo("librocksdbjni-linux64.so");
assertThat(Environment.getSharedLibraryFileName("rocksdb")).
isEqualTo("librocksdbjni.so");
+ // Linux musl-libc (Alpine)
+ setEnvironmentClassField(MUSL_LIBC_FIELD_NAME, true);
+ assertThat(Environment.isWindows()).isFalse();
+ assertThat(Environment.getJniLibraryExtension()).
+ isEqualTo(".so");
+ assertThat(Environment.getJniLibraryFileName("rocksdb")).
+ isEqualTo("librocksdbjni-linux64-musl.so");
+ assertThat(Environment.getSharedLibraryFileName("rocksdb")).
+ isEqualTo("librocksdbjni.so");
// UNIX
+ setEnvironmentClassField(MUSL_LIBC_FIELD_NAME, false);
setEnvironmentClassFields("Unix", "x64");
assertThat(Environment.isWindows()).isFalse();
assertThat(Environment.getJniLibraryExtension()).
@@ -130,8 +155,37 @@ public class EnvironmentTest {
isEqualTo("librocksdbjni.dll");
}
+ @Test
+ public void ppc64le() {
+ setEnvironmentClassField(MUSL_LIBC_FIELD_NAME, false);
+ setEnvironmentClassFields("Linux", "ppc64le");
+ assertThat(Environment.isUnix()).isTrue();
+ assertThat(Environment.isPowerPC()).isTrue();
+ assertThat(Environment.is64Bit()).isTrue();
+ assertThat(Environment.getJniLibraryExtension()).isEqualTo(".so");
+ assertThat(Environment.getSharedLibraryName("rocksdb")).isEqualTo("rocksdbjni");
+ assertThat(Environment.getJniLibraryName("rocksdb")).isEqualTo("rocksdbjni-linux-ppc64le");
+ assertThat(Environment.getJniLibraryFileName("rocksdb"))
+ .isEqualTo("librocksdbjni-linux-ppc64le.so");
+ assertThat(Environment.getSharedLibraryFileName("rocksdb")).isEqualTo("librocksdbjni.so");
+ // Linux musl-libc (Alpine)
+ setEnvironmentClassField(MUSL_LIBC_FIELD_NAME, true);
+ setEnvironmentClassFields("Linux", "ppc64le");
+ assertThat(Environment.isUnix()).isTrue();
+ assertThat(Environment.isPowerPC()).isTrue();
+ assertThat(Environment.is64Bit()).isTrue();
+ assertThat(Environment.getJniLibraryExtension()).isEqualTo(".so");
+ assertThat(Environment.getSharedLibraryName("rocksdb")).isEqualTo("rocksdbjni");
+ assertThat(Environment.getJniLibraryName("rocksdb")).isEqualTo("rocksdbjni-linux-ppc64le-musl");
+ assertThat(Environment.getJniLibraryFileName("rocksdb"))
+ .isEqualTo("librocksdbjni-linux-ppc64le-musl.so");
+ assertThat(Environment.getSharedLibraryFileName("rocksdb")).isEqualTo("librocksdbjni.so");
+ setEnvironmentClassField(MUSL_LIBC_FIELD_NAME, false);
+ }
+
@Test
public void aarch64() {
+ setEnvironmentClassField(MUSL_LIBC_FIELD_NAME, false);
setEnvironmentClassFields("Linux", "aarch64");
assertThat(Environment.isUnix()).isTrue();
assertThat(Environment.isAarch64()).isTrue();
@@ -142,6 +196,19 @@ public class EnvironmentTest {
assertThat(Environment.getJniLibraryFileName("rocksdb"))
.isEqualTo("librocksdbjni-linux-aarch64.so");
assertThat(Environment.getSharedLibraryFileName("rocksdb")).isEqualTo("librocksdbjni.so");
+ // Linux musl-libc (Alpine)
+ setEnvironmentClassField(MUSL_LIBC_FIELD_NAME, true);
+ setEnvironmentClassFields("Linux", "aarch64");
+ assertThat(Environment.isUnix()).isTrue();
+ assertThat(Environment.isAarch64()).isTrue();
+ assertThat(Environment.is64Bit()).isTrue();
+ assertThat(Environment.getJniLibraryExtension()).isEqualTo(".so");
+ assertThat(Environment.getSharedLibraryName("rocksdb")).isEqualTo("rocksdbjni");
+ assertThat(Environment.getJniLibraryName("rocksdb")).isEqualTo("rocksdbjni-linux-aarch64-musl");
+ assertThat(Environment.getJniLibraryFileName("rocksdb"))
+ .isEqualTo("librocksdbjni-linux-aarch64-musl.so");
+ assertThat(Environment.getSharedLibraryFileName("rocksdb")).isEqualTo("librocksdbjni.so");
+ setEnvironmentClassField(MUSL_LIBC_FIELD_NAME, false);
}
private void setEnvironmentClassFields(String osName,
@@ -154,9 +221,10 @@ public class EnvironmentTest {
public static void restoreState() {
setEnvironmentClassField(OS_FIELD_NAME, INITIAL_OS);
setEnvironmentClassField(ARCH_FIELD_NAME, INITIAL_ARCH);
+ setEnvironmentClassField(MUSL_LIBC_FIELD_NAME, INITIAL_MUSL_LIBC);
}
- private static String getEnvironmentClassField(String fieldName) {
+ private static T getEnvironmentClassField(String fieldName) {
final Field field;
try {
field = Environment.class.getDeclaredField(fieldName);
@@ -164,13 +232,13 @@ public class EnvironmentTest {
final Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
- return (String)field.get(null);
+ return (T)field.get(null);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
- private static void setEnvironmentClassField(String fieldName, String value) {
+ private static void setEnvironmentClassField(String fieldName, Object value) {
final Field field;
try {
field = Environment.class.getDeclaredField(fieldName);