2013-07-21 1 views
7

Java Web Start를 사용하여 일부 타사 네이티브 라이브러리에 종속 된 Java 응용 프로그램을 시작합니다. 그런 다음 이러한 기본 라이브러리는 LoadLibrary/dlopen을 사용하여 종속성으로 다른 기본 라이브러리 (commonLib)를로드합니다.Java Web Start - 다른 네이티브 종속성을 사용하여 네이티브 종속성로드

Web Start를 사용하지 않는 경우 기본 라이브러리가 같은 디렉토리에있을 때 모든 것이 예상대로 작동합니다.

시작하지만, 내가 한 네이티브 라이브러리 jar 파일에 포장 및 JNLP 파일에서 참조 할 필요

웹 :

<!-- Windows OS --> 
    <resources os="Windows"> 
     <nativelib href="native/native-windows.jar" /> 
    </resource> 

    <!-- Linux OS --> 
    <resources os="Linux"> 
     <nativelib href="native/native-linux.jar" /> 
    </resources> 

    <!-- Mac OSX --> 
    <resources os="Mac OS X"> 
     <nativelib href="native/native-osx.jar"/> 
    </resources> 

네이티브 라이브러리 잘로드하지만 그들은 자신의 의존성을로드에 실패를 commonLib - 파일이 현재 라이브러리 검색 경로가 아닌 일부 jar/cache 폴더에 있기 때문에 C++ LoadLibrary/dlopen 호출이 실패합니다.

System.loadLibrary("commonLib"); 
System.loadLibrary("myNativeLib"); 

그러나이 방법은 OS X에서 작동하지 않습니다 :

는 Windows에서 나는 JNI 라이브러리를로드과 같이하기 전에 자바에 미리 로딩 commonLib하여이 문제를 해결할 수 있었다 - 원시 코드에서 dlopen이 실패합니다. dlopen은 이미로드 된 라이브러리를 다시로드하려고 시도하지 않을 정도로 현명하지 못합니다.

Java Web Start의 다른 네이티브 라이브러리에 의존하는 네이티브 라이브러리를 압축하고로드하는 플랫폼 간 플랫폼이 있습니까?

+0

항아리에는 관련된 모든 원주민이 포함되어 있습니까? –

+0

예, 두 번 확인했습니다. –

답변

1

(못생긴) 해결 방법을 찾을 수있었습니다.

String tmpDir = System.getProperty("java.io.tmpdir"); 
if (!tmpDir.endsWith("/") && !tmpDir.endsWith("\\")) 
    tmpDir += "/"; 
String resource = "commonDir.dll"; // Adjust accordingly to current OS, omitted for brevity 
InputStream is = loader.getResourceAsStream(resource); 
if (is == null) { 
    // Handle error - resource not found 
    return; 
} 
try { 
    FileOutputStream os = new FileOutputStream(tmpDir + resource); 
    byte[] buffer = new byte[1024*1024]; 
    int len = is.read(buffer); 
    while (len != -1) { 
     os.write(buffer, 0, len); 
     len = is.read(buffer); 
    } 
    os.close(); 
    is.close(); 
    System.out.println("Extracted " + resource + " to " + tmpDir); 
} catch(IOException ex) { 
    // Handle the exception - cannot write to temp directory 
    System.out.println("Could not extract resource " + resource + " to " + tmpDir + ": " + ex.getMessage()); 
} 
:

... 
<resources os="Windows"> 
    <jar href="native/deps-windows.jar" /> 
</resources> 
<resources os="Linux"> 
    <jar href="native/deps-linux.jar" /> 
</resources> 
<resources os="Mac OS X"> 
    <jar href="native/deps-osx.jar" /> 
</resources> 
... 

2 단계는 임시 디렉토리에 자바를 사용하여 이러한 리소스를 추출하는 것입니다 비결은 단순한 자원 항아리에 종속 라이브러리 (commonLib)을 포장하고 jnlp 파일에 추가하는 것입니다

3 단계는 원시 JNI 라이브러리에 추출 된 종속성에 대한 전체 경로를 알리거나 현재 디렉토리를 임시 디렉토리 에 임시로 설정하고 JNI 라이브러리를로드 한 다음 다시 설정합니다. 이것은 자체적으로 문제입니다. Java에서는 현재 작업 디렉토리를 변경하기가 어렵습니다. [1] 비록 C에서 그렇게하는 또 다른 작은 유틸리티 JNI 라이브러리를 생성하여이를 해결할 수 있습니다.