Question

I am trying to call a C++ library from java side and have written necessary jni code. However, when my java code tries to load my C++ library via System.loadLibrary, it complains the following error:

Exception in thread "main" java.lang.UnsatisfiedLinkError: libmylib.so: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by libmylib.so)

I later found that it is because I have two different GLIBC versions on my system, and the default one is the older one, while libmylib.so is required to built from the newer GLIBC. As a result, java links to the wrong GLIBC.

I tried the following things, but it does not work :(.

The first one is to try to load correct library manually via System.load in my java code. Specifically, I added the following codes before it loads my library:

static {
  System.load("/usr/local/gcc-4.8.1-glibc-2.17/lib/libc.so.6");
  System.load("/usr/local/gcc-4.8.1-glibc-2.17/lib/libstdc++.so.6.0.18");      
  System.loadLibrary(mylib);
}

The libc.so.6 is also added because libstdc++ depends on it (otherwise java will load the wrong libc and complains another error). However, this time java complains the following error:

Exception in thread "main" java.lang.UnsatisfiedLinkError:
  /usr/local/gcc-4.8.1-glibc2.17/lib/libc-2.17.so:
      __vdso_time: invalid mode for dlopen(): Invalid argument

And this error is caused by mixing two versions of GLIBC as described in this question. The solution to that question is for building C++ program with -Wl,--dynamic-linker set properly (also described here). However, I don't know how to do that in Java.

I tried to set LD_LIBRARY_PATH to the newer version, but the situation is just the same :(.

Can I know how to make java link to the correct library?

(PS: a solution without make install newer version of glibc is preferred, since many other applications in my machine rely on the current default glibc)

I have been searching and trying solutions to my problem for days, but none of them succeed :(

Stackoverflow, you're my only hope :~.

Was it helpful?

Solution

System.load("/usr/local/gcc-4.8.1-glibc-2.17/lib/libc.so.6");

As I explained here, this can not possibly work.

By the time you reach above statement, the system libc.so.6 has already been loaded (at process startup), and you absolutely can not have two versions of libc.so.6 loaded into the same process.

OTHER TIPS

Try using LD_PRELOAD=new_c_library.so java -javastuff

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top