2016-10-26 11 views
2

Solaris 9 (Solaris 10 전역의 브랜드 영역)에서 Java 응용 프로그램을 실행하고 있습니다.Solaris 9의 Java 1.6.0_45가 재배치 오류를 반환합니다. "symbol __fmodf : 참조 된 기호를 찾을 수 없습니다."

[email protected] # 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 

...

나는 응용 프로그램이 JDK 1.6.0_45 위에 달 동안 실행하는 데 사용 (로그)에서 확실히 알
[email protected] # isainfo -v 
64-bit sparcv9 applications 
32-bit sparc applications 

:

[email protected] # 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은 오류를 반환하지만 다른 버전은 여전히 ​​정상적으로 실행됩니다.

[email protected] # 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 호환으로 인증하므로 어떤 일이 발생하는지 실제로 파악할 수 없습니다. 나는 이틀 동안이 일에 매달 렸고 가능한 모든 해결 방법을 시도했지만 운이 없었습니다.

모든 필요한 시스템 라이브러리가 해결됩니다

[email protected] # 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 라이브러리의 한 메소드입니다. 솔라리스 9 링크가 기본적으로 libm.so.1에 libm.so 때문에, 나는 또한 여전히

[email protected] # LD_PRELOAD=/.SUNWnative/lib/libm.so.2 java -version 

하지만 행운과 함께 수학 라이브러리를 대체했습니다.

심볼을 덮어 쓰거나 Java를 어떤 종류의 "호환성"모드로 실행하여 문제를 해결할 수있는 방법이 있습니까?

아니면 매우 분명한 것을 놓치고 있습니까?

감사

편집 : 앤드류 헨레에 의해 제안,이 libjvm.so에 대한 LDD의 전체 출력 :

[email protected] # 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 
...

[email protected] # 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 
+0

'/ usr/bin/java'에'ldd' 출력을 게시했습니다. 그 출력은'libjvm.so'를 포함하지 않지만, 에러 메시지는'/ usr/jdk/instances/jdk1.6.0/jre/lib/sparc/server/libjvm.so'입니다. 공유 객체에 대한'ldd -rv' 결과는 무엇입니까? ('-r'을 추가하여 실제 심볼 검색을 강제 실행하십시오. 문제는 https://docs.oracle.com/cd/E23823_01/html/816-5165/ldd-1.html을 참조하십시오. –

+0

안녕하세요 앤드류, 귀하의 회신에 감사드립니다. 이미 저도 시도해 보았고 나에게 맞았습니다 ... 나는 그 질문을 편집하고 여러분이 제안한 결과를 덧붙였다. – MariusPontmercy

+0

그건'libm.so'를 전혀 보여주지 않습니다. JVM 코드는 다른 링커 옵션/환경 변수를 사용하는 라이브러리에서 런타임 링크 일 가능성이 큽니다. 'truss -f -a -e -l -o/path/to/output/file java -version'을 시도해보십시오. 그러면 JVM을 시작하는 데 필요한 모든 공유 객체를로드하고 런타임에 연결하는 모든 시스템 호출을 보여주는 많은 양의 출력이 생성됩니다. 그 데이터의 어딘가에서'libm.so '에 대한 필요성이 어디에서 왔는지에 대한 단서가 있어야합니다. 이 수정 사항은 JVM의 업그레이드 여야합니다 - 1.6.0_45는 고풍이며 재부팅 후에 작동을 멈 춥니 다. 패치/업데이트? –

답변

1

확인, 해결되었습니다. 하지만 이것은 아주 이상합니다.코멘트에 앤드류 헨레에 의해 제안

, 나는

[email protected] # 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/으로 그들을 소프트 연결하여, 그와 함께 자바를 공급하기 위해 노력했다. 내가 /.SUNWnative/lib/libm.so.1 아무것도 연결하지

변경,하지만 나는 절망의 밖으로 더러운 트릭을 시도 :

[email protected] # ln -s /.SUNWnative/lib/libm.so.2 /usr/jdk/instances/jdk1.6.0/jre/lib/sparc/server/libm.so.1 

을 그리고 이것은 놀랍게도 트릭을했다. 이제 45이 실행 부드럽게 내 Solaris에서 자바 6 업데이트가 9

그래서, libjvm.so 명시 적으로 libm.so.1을 찾습니다 (단지 libm.so, 그 실제 라이브러리의 기본 버전에 대한 심볼릭 링크 일반적으로)하지만 실제로 요구 libm.so.2에 작품 ...

힌트를 위해 Andrew에게 감사드립니다!