Could not initialize class jnr.unixsocket.Native$LibC

Hello,

I’m trying to use the dalli gem (1.1.5) with UNIX sockets under JRuby
1.7.4 on Fedora 19. I get the following error.

Java::JavaLang::NoClassDefFoundError (Could not initialize class
jnr.unixsocket.Native$LibC):
jnr.unixsocket.Native.libsocket(Native.java:60)
jnr.unixsocket.Native.socket(Native.java:68)
jnr.unixsocket.UnixSocketChannel.(UnixSocketChannel.java:66)
jnr.unixsocket.UnixSocketChannel.open(UnixSocketChannel.java:47)
org.jruby.ext.socket.RubyUNIXSocket.init_unixsock(RubyUNIXSocket.java:257)
org.jruby.ext.socket.RubyUNIXSocket.initialize(RubyUNIXSocket.java:82)
org.jruby.ext.socket.RubyUNIXSocket$INVOKER$i$1$0$initialize.call(RubyUNIXSocket$INVOKER$i$1$0$initialize.gen)
org.jruby.internal.runtime.methods.JavaMethod$JavaMethodOne.call(JavaMethod.java:968)
org.jruby.internal.runtime.methods.JavaMethod$JavaMethodN.call(JavaMethod.java:674)

I can see that the relevant classes are already present in the
classpath as part of jruby.jar, including jnr.unixsocket.Native$LibC. I
normally use RVM but I also tried downloading the standard JRuby
tarball and got the same result.

I’ve tried debugging it with -J-Djruby.native.verbose=true but that
didn’t show anything interesting. I’ve even tried LD_DEBUG=libs to see
whether it was having trouble with the native libraries. I see a bunch
of undefined symbol errors but they relate to all sorts of things and
libjffi-1.2.so does appear to load eventually so these are probably
spurious. Am I missing something here?

Regards,
James

Does the following work for you?

jruby -e “puts Java::jnr.unixsocket.Native.libsocket”

If not, install strace (yum install strace) and execute the following:

strace jruby -e “puts Java::jnr.unixsocket.Native.libsocket” 2>&1 | tee
strace.out

Look through strace.out, near the bottom, and see if it’s not finding
libgcc, libcstdc++, etc.

Ben

On Thu, 15 Aug 2013 09:43:27 -0400
Ben B. [email protected] wrote:

Does the following work for you?

jruby -e “puts Java::jnr.unixsocket.Native.libsocket”

Aha! That set me on the right track. It’s some kind of multilib issue.

NativeLibrary.java:87:in loadNativeLibraries': java.lang.UnsatisfiedLinkError: /usr/lib/libc.so.6: wrong ELF class: ELFCLASS32 from NativeLibrary.java:70:in getNativeLibraries’
from NativeLibrary.java:49:in getSymbolAddress' from NativeLibrary.java:59:in findSymbolAddress’
from AsmLibraryLoader.java:125:in generateInterfaceImpl' from AsmLibraryLoader.java:63:in loadLibrary’
from NativeLibraryLoader.java:43:in loadLibrary' from LibraryLoader.java:228:in load’
from Library.java:123:in loadLibrary' from Library.java:80:in loadLibrary’
from Native.java:40:in <clinit>' from Unsafe.java:-2:in ensureClassInitialized’

I then added -J-Djava.library.path=/usr/lib64 to JRUBY_OPTS and my
application started working perfectly. I can’t see any obvious reason
why this might be happening though. I try to avoid 32-bit stuff
wherever possible. Any ideas?

Thanks,
James

Make sure you don’t have any LD_LIBRARY_PATH or similar ld.so settings
in your environment, and check what is in /etc/ld.so.conf (or however
its configured on linux these days).

JNR by default does not search for libraries, it just calls
dlopen(“libc.so.6”, ), so it should be getting the version
from /usr/lib64 (or whatever env or ld.so.conf says to search). Maybe
its time to change that on linux…

On Fri, 16 Aug 2013 10:30:29 +1000
Wayne M. [email protected] wrote:

Make sure you don’t have any LD_LIBRARY_PATH or similar ld.so settings
in your environment, and check what is in /etc/ld.so.conf (or however
its configured on linux these days).

JNR by default does not search for libraries, it just calls
dlopen(“libc.so.6”, ), so it should be getting the version
from /usr/lib64 (or whatever env or ld.so.conf says to search). Maybe
its time to change that on linux…

LD_LIBRARY_PATH is definitely not set. Here’s the config from /etc.
Other than the BitDefender entry, all these lines come directly from
Fedora.

/etc/ld.so.conf:
include ld.so.conf.d/*.conf
/opt/BitDefender-scanner/var/lib/

/etc/ld.so.conf.d/* (concatenated):
/usr/lib64/atlas
/usr/lib64/dyninst

Placeholder file, no vDSO hwcap entries used in this kernel.

Placeholder file, no vDSO hwcap entries used in this kernel.

Placeholder file, no vDSO hwcap entries used in this kernel.

/usr/lib64/iscsi
/usr/lib/llvm
/usr/lib64/llvm
/usr/lib64/mysql
/usr/lib64/xulrunner

I notice when I run ldconfig with -v, it says this.

ldconfig: Can’t stat /libx32: No such file or directory
ldconfig: Path /usr/lib' given more than once ldconfig: Path /usr/lib64’ given more than once
ldconfig: Can’t stat /usr/libx32: No such file or directory

I’m not sure why it says “given more than once” when I can’t see any
reference to these at all. I know that certain “trusted” system
directories like /lib and /usr/lib are searched by default and it looks
as though it’s checking /usr/lib first. On my Gentoo system at home,
which I haven’t tried this on, these trusted directories are listed
explicitly in the config. In any case, Gentoo has /usr/lib symlinked
to /usr/lib64 with a separate /usr/lib32 directory.

I noticed a command on the system called dltest. I run it and it says
it finds libc.so.6 but only strace reveals which one. In this case,
it’s /lib64/libc.so.6. I don’t know why JNR gets a different result.

Regards,
James