Load Library Exception : No package_jni in java.library.path
들어가면서
- 지난 번 포스트에서 알아본 DRM 관련 연동을 하면서 발생한 자그마한 Exception과 해결 방법에 대해 다뤄 보고자 합니다.
- 또한 DLL, JNI, JAR의 개념에 대해서도 정리를 해보고자 합니다.
-
⚠️ Situation
- 현재 시스템에서 기본 DRM SoftCamp를 사용하고 있으며 최근 특정 서비스에 Fasoo DRM 연동을 추가로 진행하면서 발생한 이슈입니다
Exception : load library Exception : no pkg_jni in java.library.path com.fasoo.fcwpkg.packager.FassoPackagerJNI.N_DestroyObject(J)V
- ⚠️ 핵심 : System.loadLibrary(“pkg_jni”)를 호출 -> java.library.path에서 pkg_jni.dll을 찾을 수 없음 -> UnsatisfiedLinkError 발생
- 현재 시스템에서 기본 DRM SoftCamp를 사용하고 있으며 최근 특정 서비스에 Fasoo DRM 연동을 추가로 진행하면서 발생한 이슈입니다
-
💡 Solution
-
VM option에 java.library.path를 설정
- Eclipse 기준 -> Run > Run Configuration > Arguments > VM Arguments
-Djava.library.path=”해당 library가 존재하는 directory”
- Tomcat(Window) 기준 : JVM 실행 옵션을 직접 설정 -> /bin/setenv.bat
set “JAVA_OPTS=%JAVA_OPTS% -Djava.library.path=해당 library가 존재하는 directory”
- Eclipse 기준 -> Run > Run Configuration > Arguments > VM Arguments
- 해당 경로에 pkg_jni.dll이 존재하게 하면 해결완료
-
-
🔁 Process
- Application 실행 -> JVM(Java Virtual Machine) 기동
-
JVM은 classpath 설정을 바탕으로 필요한 .class 또는 .jar 파일을 ClassLoader를 통해 로딩(jar안에 포함된 Java class들도 로딩)
- 로딩된 Java class 내부에서 JNI(Java Native Interface)를 통해 C/C++로 구현된 native 메소드를 호출
System.loadLibrary("pkg_jni");
- OS에 pkg_jni.dll을 로딩하라고 요청
- JVM은 내부적으로 java.library.path에 설정된 Directory를 통해 pkg_jni.dll를 찾습니다
- java.library.path가 설정되어 있지 않으면 운영체제의 PATH 환경 변수에서 탐색
- pkg_jni.dll을 발견하면 JVM은 해당 DLL을 메모리에 로딩
- 해당 dll이 의존하고 있는 다른 dll이 있을 경우 그 의존 dll들까지 함께 찾고 로딩
- 만약 의존 dll을 찾지 못하면 UnsatisfiedLinkError : Can’t find dependent libraries Exception 발생
- pkg_jni.dll이 성공적으로 로딩되면 JVM은 해당 dll 내부의 C/C++ 구현 함수들을 Java 메서드에 바인딩
- Java 코드에서 native method가 호출되면 JVM은 JNI Bridge를 통해 C/C++ method를 호출
- Java -> C코드로 제어권이 넘어가며 메모르/리소스를 공유하고 처리 결과를 Java로 반환
-
✅Conclusion
- 개발도 중요하겠지만 어플리케이션이 돌아가는 과정과 관련된 기본적인 개념에 대해서 한 번씩 정리하는 과정을 통해서 다음에 비슷한 jar와 dll 관련된 이슈가 생기더라도 빠르게 대처할 수 있을 것 같습니다.