我在Solaris 9中运行了一个java应用程序( Solaris 10全局中的品牌区域)。
root@server # cat /etc/release
Solaris 9 4/03 s9s_u3wos_08 SPARC
Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
Use is subject to license terms.
Assembled 25 February 2003..。
root@server # isainfo -v
64-bit sparcv9 applications
32-bit sparc applications我确信(从日志中)应用程序在JDK 1.6.0_45之上运行了几个月:
root@server # pkginfo | grep -i jdk
system SUNWj2dem JDK 1.2 demo programs
system SUNWj2man JDK 1.2 man pages
system SUNWj2rt JDK 1.2 run time environment
system SUNWj3irt JDK 1.4 I18N run time environment
system SUNWj6cfg JDK 6.0 Host Config. (1.6.0_45)
system SUNWj6dev JDK 6.0 Dev. Tools (1.6.0_45)
system SUNWj6dvx JDK 6.0 64-bit Dev. Tools (1.6.0_45)
system SUNWj6jmp JDK 6.0 Man Pages: Japan (1.6.0_45)
system SUNWj6man JDK 6.0 Man Pages (1.6.0_45)
system SUNWj6rt JDK 6.0 Runtime Env. (1.6.0_45)
system SUNWj6rtx JDK 6.0 64-bit Runtime Env. (1.6.0_45) 现在,在重新启动之后,Java 6返回一个错误,而其他版本仍然运行良好:
root@server # java -version
dl failure on line 685Error: failed /usr/jdk/instances/jdk1.6.0/jre/lib/sparc/server/libjvm.so, because ld.so.1: java: fatal: relocation error: file /usr/jdk/instances/jdk1.6.0/jre/lib/sparc/server/libjvm.so: symbol __fmodf: referenced symbol not found我知道这是Solaris 8和/或JDK 7中的一种预期行为,但Oracle证明JDK 6与Solaris 9兼容,因此我无法真正搞清楚到底发生了什么。我被困在这上面已经两天了,并且尝试了任何可能的解决方法,但是没有运气。
解决了所有所需的系统库:
root@server # ldd -v /usr/bin/java
find object=/usr/lib/secure/s9_preload.so.1; required by /usr/jdk/instances/jdk1.6.0/bin/java
/usr/lib/secure/s9_preload.so.1
find object=libthread.so.1; required by /usr/jdk/instances/jdk1.6.0/bin/java
libthread.so.1 => /usr/lib/libthread.so.1
find version=libthread.so.1
libthread.so.1 (SISCD_2.3a) => /usr/lib/libthread.so.1
find object=libjli.so; required by /usr/jdk/instances/jdk1.6.0/bin/java
libjli.so => /usr/jdk/instances/jdk1.6.0/bin/../jre/lib/sparc/jli/libjli.so
find version=libjli.so
libjli.so (SUNWprivate_1.1) => /usr/jdk/instances/jdk1.6.0/bin/../jre/lib/sparc/jli/libjli.so
find object=libdl.so.1; required by /usr/jdk/instances/jdk1.6.0/bin/java
libdl.so.1 => /usr/lib/libdl.so.1
find version=libdl.so.1
libdl.so.1 (SUNW_0.8) => /usr/lib/libdl.so.1
find object=libc.so.1; required by /usr/jdk/instances/jdk1.6.0/bin/java
libc.so.1 => /usr/lib/libc.so.1
find version=libc.so.1
libc.so.1 (SUNW_0.7) => /usr/lib/libc.so.1
libc.so.1 (SUNWprivate_1.1) => /usr/lib/libc.so.1
find object=libc.so.1; required by /usr/lib/secure/s9_preload.so.1
find object=libc.so.1; required by /usr/lib/libthread.so.1
find version=libc.so.1
libc.so.1 (SUNW_1.21.2) => /usr/lib/libc.so.1
libc.so.1 (SUNWprivate_1.1) => /usr/lib/libc.so.1
find object=libdl.so.1; required by /usr/lib/libthread.so.1
find version=libdl.so.1
libdl.so.1 (SUNWprivate_1.1) => /usr/lib/libdl.so.1
find object=libc.so.1; required by /usr/jdk/instances/jdk1.6.0/bin/../jre/lib/sparc/jli/libjli.so
find version=libc.so.1
libc.so.1 (SUNW_0.7) => /usr/lib/libc.so.1
find object=libdl.so.1; required by /usr/lib/libc.so.1
find version=libdl.so.1
libdl.so.1 (SUNW_1.4) => /usr/lib/libdl.so.1
libdl.so.1 (SUNWprivate_1.1) => /usr/lib/libdl.so.1
object=/usr/lib/libdl.so.1; filter for /usr/lib/ld.so.1
object=/usr/lib/libc.so.1; filter for /usr/platform/$PLATFORM/lib/libc_psr.so.1
find object=/usr/platform/SUNW,Sun-Blade-T6320/lib/libc_psr.so.1; required by /usr/lib/libc.so.1
/usr/platform/SUNW,Sun-Blade-T6320/lib/libc_psr.so.1因此,我必须假定,由于某种原因,它们已经过时,并且没有实现符号__fmodf。但它以前是怎么运作的?
据我所知,fmodf()是libm库中的一个方法。由于Solaris 9默认将libm.so链接到libm.so.1,所以我还尝试用
root@server # LD_PRELOAD=/.SUNWnative/lib/libm.so.2 java -version 但还是没有运气。
是否有任何方法覆盖符号和/或以某种“兼容性”模式运行Java来解决这个问题?
还是我错过了一些很明显的东西?
谢谢
编辑:,如Andrew所建议的,这是libjvm.so的ldd的完整输出:
root@server # ldd -rv /usr/jdk/instances/jdk1.6.0/jre/lib/sparc/server/libjvm.so
find object=libc.so.1; required by /usr/lib/secure/s9_preload.so.1
libc.so.1 => /usr/lib/libc.so.1
find object=libdl.so.1; required by /usr/lib/libc.so.1
libdl.so.1 => /usr/lib/libdl.so.1
find version=libdl.so.1
libdl.so.1 (SUNW_1.4) => /usr/lib/libdl.so.1
libdl.so.1 (SUNWprivate_1.1) => /usr/lib/libdl.so.1
object=/usr/lib/libc.so.1; filter for /usr/platform/$PLATFORM/lib/libc_psr.so.1
find object=/usr/platform/SUNW,Sun-Blade-T6320/lib/libc_psr.so.1; required by /usr/lib/libc.so.1
/usr/platform/SUNW,Sun-Blade-T6320/lib/libc_psr.so.1
object=/usr/lib/libdl.so.1; filter for /usr/lib/ld.so.1..。
root@server # ldd -ss /usr/jdk/instances/jdk1.6.0/jre/lib/sparc/server/libjvm.so
find object=libc.so.1; required by /usr/lib/secure/s9_preload.so.1
search path=/usr/openwin/lib:/usr/local/lib:/usr/local/ssl/lib (LD_LIBRARY_PATH)
trying path=/usr/openwin/lib/libc.so.1
trying path=/usr/local/lib/libc.so.1
trying path=/usr/local/ssl/lib/libc.so.1
search path=/usr/lib (default)
trying path=/usr/lib/libc.so.1
libc.so.1 => /usr/lib/libc.so.1
find object=libdl.so.1; required by /usr/lib/libc.so.1
search path=/usr/openwin/lib:/usr/local/lib:/usr/local/ssl/lib (LD_LIBRARY_PATH)
trying path=/usr/openwin/lib/libdl.so.1
trying path=/usr/local/lib/libdl.so.1
trying path=/usr/local/ssl/lib/libdl.so.1
search path=/usr/lib (default)
trying path=/usr/lib/libdl.so.1
libdl.so.1 => /usr/lib/libdl.so.1
object=/usr/lib/libc.so.1; filter for /usr/platform/$PLATFORM/lib/libc_psr.so.1
find object=/usr/platform/SUNW,Sun-Blade-T6320/lib/libc_psr.so.1; required by /usr/lib/libc.so.1
/usr/platform/SUNW,Sun-Blade-T6320/lib/libc_psr.so.1
object=/usr/lib/libdl.so.1; filter for /usr/lib/ld.so.1发布于 2016-10-26 14:11:37
好了解决了。不过这挺奇怪的。
正如Andrew在评论中所建议的,我仔细研究了
root@server # truss -f -a -e -l -f -rall -wall -o truss_jdk_1.6.0_45.txt /usr/bin/java -version并确认包含符号__fmodf的数学库在运行时由libjvm.so调用,在系统的默认位置中找到它之前在几个地方查找它:
24757/1: stat("/usr/jdk/instances/jdk1.6.0/jre/lib/sparc/server/libm.so.1", 0xFFBFE910) Err#2 ENOENT
24757/1: stat("/usr/jdk/instances/jdk1.6.0/jre/lib/sparc/libm.so.1", 0xFFBFE910) Err#2 ENOENT
24757/1: stat("/usr/jdk/instances/jdk1.6.0/jre/../lib/sparc/libm.so.1", 0xFFBFE910) Err#2 ENOENT
24757/1: stat("/usr/openwin/lib/libm.so.1", 0xFFBFE910) Err#2 ENOENT
24757/1: stat("/usr/local/lib/libm.so.1", 0xFFBFE910) Err#2 ENOENT
24757/1: stat("/usr/local/ssl/lib/libm.so.1", 0xFFBFE910) Err#2 ENOENT
24757/1: stat("/usr/lib/libm.so.1", 0xFFBFE910) = 0
24757/1: resolvepath("/usr/lib/libm.so.1", "/usr/lib/libm.so.1", 1023) = 18
24757/1: open("/usr/lib/libm.so.1", O_RDONLY) = 3文件/usr/lib/libm.so.1实际上存在于系统中,但我在此之前也注意到,其他版本的相同数学库安装在其他地方:
/.SUNWnative/lib/libm.so.1
/.SUNWnative/lib/libm.so.2因此,我试图通过将它们软链接到/usr/jdk/instances/jdk1.6.0/jre/lib/sparc/server/中来向Java提供这些信息。
当我链接到/.SUNWnative/lib/libm.so.1时,没有什么改变,但后来我出于绝望尝试了最肮脏的伎俩:
root@server # ln -s /.SUNWnative/lib/libm.so.2 /usr/jdk/instances/jdk1.6.0/jre/lib/sparc/server/libm.so.1令人惊讶的是,这件事起了作用。现在,Java6UPDATE 45在我的Solaris 9上顺利运行。
因此,libjvm.so显式地查找libm.so.1 (不仅仅是libm.so,它通常是指向实际库的默认版本的符号链接),但是实际上需要libm.so.2才能工作。
非常感谢安德鲁的提示!
https://stackoverflow.com/questions/40259436
复制相似问题