JRuby on Alpine Linux
Install JRuby from the Alpine repository, don’t use Oracle JDK and beware of JARs with bundled native binaries (JNI); check out List of Java libraries with JNI.
echo "http://dl-cdn.alpinelinux.org/alpine/edge/community" >> /etc/apk/repositories
apk update
apk add jruby
# install optional subpackages, if you need them
apk add jruby-irb jruby-maven jruby-minitest jruby-rdoc jruby-rake jruby-testunit
Alpine Linux doesn’t use GNU C library (glibc) as conventional distributions like Debian, Red Hat or Gentoo. Instead, it uses musl libc, a lightweight, fast, simple and standards-conform C library.
The problem is that musl is binary compatible to glibc only partially. If you download some strange binaries from somewhere, there’s a great chance that they will not work on the Alpine Linux.
This is not just about Alpine Linux, the same applies to all Linux distributions that use any other C library but glibc.
You cannot run Oracle JDK on the Alpine Linux; it’s built for glibc and incompatible with musl libc. That’s not a problem, just install OpenJDK from the Alpine repository. Don’t worry about compatibility, Oracle JDK 8 is just branded distribution of OpenJDK 8, the code base is nearly identical.
Maybe you’ve never heard about “native extensions” (Java Native Interface) in Java / JVM. They are (fortunately) very rarely used/needed. This also implies that there’s no such good support in tools and knowledge about them like in Ruby, Python or Lua.
When you install a Ruby gem with native extensions (written usually in C or C++), there are compiled and built directly on your machine, against C library you use.
Not so in Java and JRuby. In Java land, “native extensions” are precompiled for various platforms and bundled directly in JARs. And that’s very bad practice. You often even don’t know that there are some native binaries in the JAR. The problem is that most people wrongly assume that Linux == glibc, so they build and test native binaries only against glibc. Sometimes the binaries built for glibc work even on musl, sometimes don’t.
Well written libraries tries to load their native library from the system first (location is specified by java.library.path
, by default it includes LD_LIBRARY_PATH
, e.g. /lib, /usr/lib, …) and fallbacks to the bundled binaries.
Some libraries (e.g. snappy-java) ignores system-provided libraries by default, but you can change this using an environment property.
Then you can simply compile the native library yourself, install it into /usr/lib and don’t touch the JAR at all.
What to do if the library insists on loading the bundled natives? Well, then you can build the JAR including native code and replace the original one. However, the better way is to patch the library (it’s actually very easy).
Actually, the first thing you should do is to look in the Alpine repository, maybe there’s already a package for it! If it’s not, you can also fill a request or try to ping @JakubJirutka.
JRuby itself uses two “native extensions” – jffi and jansi-native. There are packages with correct native binaries for both of them in the Alpine repository. These are automatically installed and used when you install JRuby from the Alpine package. So no problem here, JRuby should work well on the Alpine Linux. If not, please fill a bug.
Name | Alpine package | Patched JAR [1] | Comment |
---|---|---|---|
lz4-java |
yes 😞 |
You must use patched JAR installed by the package (PR #83). |
|
jansi-native |
no 😸 |
||
jffi |
no 😸 |
Neeeds libc6-compat. |
|
jna |
no 😸 |
||
snappy-java |
no* 😺 |
If you use upstream’s JAR, then loading of system-provided library must be enabled using |