developer tip

JNI 프로젝트에서 UnsatisfiedLinkError (종속 라이브러리를 찾을 수 없음)를 수정하는 방법

copycodes 2020. 10. 17. 10:40
반응형

JNI 프로젝트에서 UnsatisfiedLinkError (종속 라이브러리를 찾을 수 없음)를 수정하는 방법


JNI를 사용하는 Java 프로젝트에서 일하고 있습니다. JNI는 내가 직접 작성한 사용자 지정 라이브러리 (mylib.dll)를 호출하며 타사 라이브러리 인 libsndfile-1.dll에 의존합니다.

내 프로그램을 실행할 때 충돌합니다.

java.lang.UnsatisfiedLinkError:  C:\...path...\mylib.dll: Can't find dependent libraries.

이 사이트 (및 기타)를 검색했으며 여러 가지 수정을 시도했습니다.

  1. 나는 의존성 워커를 운영했다. DW는 libsndfile, MPR.DLL 및 SHLWAPI.DLL에 필요한 두 라이브러리에 "미해결 가져 오기"가 있다는 몇 가지 경고를 제공했지만 DW FAQ 에서는 이러한 경고를 무시해도 안전하다고 말했습니다.

  2. 여기에 제안 된대로 mylib.dll에서 메서드 이름을 수정했습니다 . 메서드 이름이 컴파일러에 의해 엉망이되었지만 링커 플래그를 추가했고 dll 메서드 이름이 이제 jni 헤더 파일의 이름과 정확히 일치합니다.

  3. 이러한 DLL을 모두 호출하는 .jar과 동일한 디렉터리에있는 동일한 디렉터리에 저장하여 올바른 경로에 있는지 확인합니다.

주사위가 없습니다.

무슨 일이 일어나고 있는지 아는 사람이 있습니까?

MacBook pro (Parallels을 통해)에서 Visual Studio 2010으로 개발을하고 있습니다. Toshiba 랩톱에서 Windows XP로 테스트하고 있습니다.


클래스 경로와 공유 라이브러리 검색 경로가 서로 거의 관련이 없다고 확신합니다. The JNI Book 에 따르면 Windows에서 java.library.path시스템 속성을 사용하지 않는 경우 DLL은 현재 작업 디렉터리 또는 Windows PATH환경 변수에 나열된 디렉터리에 있어야 합니다.


최신 정보:

Oracle이 웹 사이트에서 PDF를 제거한 것 같습니다. 위의 링크를 업데이트하여 University of Texas-Arlington에 거주하는 PDF의 인스턴스를 가리 키도록했습니다.

또한 JNI 사양 의 Oracle HTML 버전을 읽을 수도 있습니다 . 그것은 Java 웹 사이트의 Java 8 섹션에 있으므로 잠시 동안 사용할 수 있기를 바랍니다.


업데이트 2 :

적어도 Java 8 (이전 버전을 확인하지 않음)에서는 다음을 수행 할 수 있습니다.

java -XshowSettings:properties -version

공유 라이브러리 검색 경로를 찾으십시오. java.library.path해당 출력 에서 속성 값을 찾습니다 .


위의 모든 방법을 시도한 후에도 여전히 오류가 있습니다. 이상한 점은 Windows 7 컴퓨터에서는 작동하지만 Windows XP에서는 작동하지 않는다는 것입니다. 그런 다음 종속성 워커를 사용하고 Windows XP에는 dll 요구 사항으로 VC ++ 런타임이 없다는 것을 알았습니다. 여기에 VC ++ 런타임 패키지를 설치 하면 매력처럼 작동합니다. 나를 방해하는 것은 직관적으로 JNI 종속 dll이있는 동안 종속 라이브러리를 찾을 수 없다는 것을 계속 말하지만 마침내 JNI 종속 dll에는 다른 종속 dl이 필요하다는 것이 밝혀졌습니다. 이게 도움이 되길 바란다.


JNI 라이브러리를로드해야합니다.

System.loadLibrary 는 JVM 경로 (JDK bin 경로)에서 DLL을로드합니다.

경로가있는 명시 적 파일을로드하려면 System.load ()를 사용하십시오.

참고 항목 : Java에서 System.load ()와 System.loadLibrary의 차이점


라이브러리 경로가 올바른지 확인하십시오. 물론 다음 코드를 사용하여 라이브러리 경로 경로를 확인할 수 있습니다.System.out.println(System.getProperty("java.library.path"));

Java 애플리케이션을 시작할 때 java.library.path를 지정할 수 있습니다 .

java -Djava.library.path=path ...

64 비트 JRE로 32 비트 버전의 dll을로드하면이 문제가 발생할 수 있습니다. 제 경우였습니다.


설치 XP 시스템에서와 동일한 문제가 있었나요 javacvopencv이클립스와 함께. 다음 파일이 누락 된 것으로 나타났습니다.

  • msvcp100.dll
  • msvcr100.dll

이것들이 설치되면 프로젝트가 컴파일되고 정상적으로 실행되었습니다.


  • 짧은 대답 : "종속 라이브러리를 찾을 수 없음"오류의 경우 $ PATH를 확인하십시오 (아래 글 머리 기호 # 3에 해당).
  • 긴 대답 :
    1. 순수 자바 세계 : jvm은 "Classpath"를 사용하여 클래스 파일을 찾습니다.
    2. JNI 세계 (자바 / 네이티브 경계) : jvm은 "java.library.path"(기본값은 $ PATH)를 사용하여 dll을 찾습니다.
    3. 순수 네이티브 세계 : 네이티브 코드는 $ PATH를 사용하여 다른 dll을로드합니다.

킵 세이프의 몇몇 친구들이 저와 같은 일을 겪은 멋진 기사를 찾았습니다. 그것은 나를 위해 일했기 때문에 희망적으로 당신을 도울 것입니다! 관심이 있다면 읽어 보거나 ( 안드로이드에서 네이티브 라이브러리로드의 위험성 )

compile 'com.getkeepsafe.relinker:relinker:1.2.3'

교체

System.loadLibrary("myLibrary");

ReLinker.loadLibrary(context, "mylibrary");

나는 똑같은 문제가 있었는데 마침내 해결되었습니다.

I put all the dependent DLLs into the same folder where mylib.dll was stored and make sure the JAVA Compiler could find it (if there is no mylib.dll in the compilation path, there would be an error reporting this during compiling). The important thing you need to notice is you must make sure all the dependent libs are of the same version with mylib.dll, for example if your mylib.dll is release version then you should also put the release version of all its dependent libs there.

Hope this could help others who have encountered the same problem.


I had the same issue, and I tried everything what is posted here to fix it but none worked for me. In my case I'm using Cygwin to compile the dll. It seems that JVM tries to find the JRE DLLs in the virtual Cygwin path. I added the the Cygwin's virtual directory path to JRE's DLLs and it works now. I did something like:

SET PATH="/cygdrive/c/Program Files/Java/jdk1.8.0_45";%PATH%


In my situation, I was trying to run a java web service in Tomcat 7 via a connector in Eclipse. The app ran well when I deployed the war file to an instance of Tomcat 7 on my laptop. The app requires a jdbc type 2 driver for "IBM DB2 9.5". For some odd reason the connector in Eclispe could not see or use the paths in the IBM DB2 environment variables, to reach the dll files installed on my laptop as the jcc client. The error message either stated that it failed to find the db2jcct2 dll file or it failed to find the dependent libraries for that dll file. Ultimately, I deleted the connector and rebuilt it. Then it worked properly. I'm adding this solution here as documentation, because I failed to find this specific solution anywhere else.


Creating static library worked for me, compiling using g++ -static. It bundles the dependent libraries along with the build.


installing Microsoft Visual C++ 2010 SP1 Redistributable Fixed it


  1. Go to http://tess4j.sourceforge.net/usage.html and click on Visual C++ Redistributable for VS2012
  2. Download it and run VSU_4\vcredist_x64.exe or VSU_4\vcredist_x84.exe depending upon your system configuration
  3. Put your dll files inside the lib folder, along with your other libraries (eg \lib\win32-x86\your dll files).

참고URL : https://stackoverflow.com/questions/6092200/how-to-fix-an-unsatisfiedlinkerror-cant-find-dependent-libraries-in-a-jni-pro

반응형