2010-07-26 6 views
1

나는 CMOS로부터 시스템에 관한 정보를 얻기 위해 네이티브 함수를 호출하는 클래스를 가지고있다. 클래스는 기본 함수를 포함하는 라이브러리를로드하는 정적 초기화 블록을 가지고 있으며, 보인다 :System.load를 두 번 호출하지 않으려면 어떻게해야합니까?

내 테스트에 따르면, 방법은 미세 내가 처음 사용할 때 작동
package lib.sysid; 

public class SysId 
{ 
    private static native int getSysIdNative(); 
    private static final String SYS_ID_PATH = "libsysid.so"; 

    static 
    { 
     System.load(SYS_ID_PATH); 
    } 

    public static int getSysIdFromCMOS() 
    { 
     int returnValue = getSysIdNative(); 
    } 
} 

을,하지만 난 호출하는 경우 나중에 다시 방법은 정적 초기화 블록은 UnsatisfiedLinkError를 일으키는 원인이 실행 :

java.lang.UnsatisfiedLinkError: Native Library libsysid.so already loaded in another classloader 

가 어떻게 이미 실행 된 경우 System.load() 방법을 실행에서 정적 초기화 블록을 피할 수있다?

또는 라이브러리를 이미로드 한 상태에서 "언로드"하여 System.load() 메서드를 다시 호출하기 전에 시도해 볼 방법이 있습니까?

EDIT : 이상하게도 내가 System.load() 호출을 try-catch 블록으로 둘러싸면 여전히 UnsatisfiedLinkError가 발생하지만 실제로는 getSysIdNative()에 대한 호출에서 발생합니다. 내가 보는 오류는 다음과 같습니다.

lib.sysid.SysId.getSysIdNative()I 

"I"가 나타나는 것은 무엇입니까? 이 코드에 디버거를 연결하여 메시지가 채워지는 곳을 확인하려고했지만 지금까지 성공하지 못했습니다.

답변

2

짐작하지만, 단일 JVM이 클래스를로드하고 정적 초기화 프로그램을 두 번 실행하는 유일한 방법은 다른 클래스 로더를로드하는 것입니다. 따라서 여기에 관련된 두 번째 클래스 로더가있을 수 있습니다. 이것은 두 번째로 다른 클래스 로더가 적용될 때 적용됩니다.

"실제"운영 체제에서 java -verbose:class은이를 확인하기위한 로더 메시지를 제공합니다. 어떻게 임베디드 시스템에서 이것을 검증 할 것인지는 잘 모르겠습니다. 인쇄하려면 getSysId()을 (?) 수정하거나 SysId.class.getClassLoader()에 대한 참조를 덤프 할 수 있습니다.

0

@Carl이 옳다고 생각합니다. 정적 이니셜 라이저가 JVM에서 두 번 실행될 수있는 유일한 방법은 클래스가 여러 클래스 로더에로드되는 경우입니다.

lib.sysid.SysId.getSysIdNative()I What the heck is that "I" that shows up?

쉽습니다. I은 클래스 파일 형식으로 정의 된 시그니처 유형의 내부 표현을 기반으로합니다. 특히 I은 프리미티브 int 유형을 의미합니다. Class.getName() 등을 참조하십시오. 이것은 메소드의 리턴 유형과 일치합니다.

(이 원시 유형 이름이 가끔씩 응용 프로그램 공간에 나타나기는하지만 혼란 스럽습니다.) 또 다른 경우는 을 Object에서 메소드 구현을 상속받은 클래스에서 호출 할 때입니다. 클래스.)

+0

정확히 내가 보는 문제입니다. 시스템에 몇 가지 논리가 있는데, 위의 파일을 포함하여 시스템과 관련된 모든 라이브러리 파일을 "다시로드"하지만 처음에는 파일을로드하는 것과 다른 클래스 로더를 통해이 작업을 수행합니다. – troyal

관련 문제