FunnyWeb

据说这里有很多神奇的东西...

patchelf解决java与glibc不兼容

2018-12-06 20:11:183994 views

近期,在运行java的程序时,发现了问题。低版本内核下更新GLIBC2.14(libc.so.6)之后,java无法正常运行。表现为输入java命令后,控制台不报错无响应。

image.png

Linux内核版本为:Linux version 2.6.32-358.el6.x86_64,CentOS release 6.4 (Final)

jdk版本为:jdk1.8.0_191

Stack Overflow上面有人提出过这个问题。

https://stackoverflow.com/questions/38743391/64-bit-java-glibc-dependency-not-compatible

据个人理解原因如下

ld.so是动态链接库的管理程序,且被调用时的路径是绝对路径,需要与libc版本匹配,在本机64位linux系统中,ld.so位于/lib/ld-linux-x86-64.so.2位置。

在更新时,只能通过环境变量改变更新寻找libc.so.6文件路径,而不能改变ld.so的绝对路径,因此libc.so.6为新版,ld.so为旧版,版本不匹配。

最简单的解决方案为临时清空环境变量LD_LIBRARY_PATH,使系统找不到新版的libc,即可解决。

export LD_LIBRARY_PATH=
java -version

image.png

但在有些需求中,java会调用其他需要新版libc的程序,造成错误发生

bin/sfld/sfld_postprocess: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by bin/sfld/sfld_postprocess)

image.png

此时环境变量就会发生冲突,十分的难受。

需要PatchELF这一神器来拯救世界。

软件主页:https://nixos.org/patchelf.html

此软件可以改变编译好的二进制文件中对于动态链接库的引用,解决这个问题。

./configure --prefix=/home/sczhuhd/software/
make -j24
make install

patchelf --set-interpreter /home/sczhuhd/software/lib/ld-linux-x86-64.so.2 ~/software/mysoftware/jdk1.8.0_191/bin/java
java -version

原理是改变ld.so的路径,使版本匹配。

可以看到命令执行后可以正常运行java。

image.png