JNI 와 java.library.path

발생일: 2010.01.05

문제:
시스템에서 Fasoo DRM 이라는 암호화 모듈을 사용하고 있다.
내부적으로는 문서 다운로드 요청이 들어왔을 때, 암호화 처리를 한 후 돌려주는 방식으로 사용하고 있는데,
얼마 전 서버를 옮긴 이후부터 클래스 패스를 찾을 수 없다는 메세지가 나온다.

javax.servlet.ServletException: no fasoopackager in java.library.path

서버는 JEUS 를 쓰는데, 업체에서 제공해준 jar 파일을
각 라이브러리 폴더(WEB-INF/lib, JEUS_HOME/lib/application 등)로 옮겨보며 테스트 해보아도 해결되지 않는다.

뭐가 문제일까...?


해결책:

javax.servlet.ServletException: no fasoopackager in java.library.path

이 메세지가 의미하는 것은 일반 자바 라이브러리의 클래스 패스를 찾지 못하겠다는 것이 아니라,
 "JVM 이 'fassopackager' 라는 네이티브 라이브러리를 찾을 수 없다" 는 것이다.
즉, 네이티브 어플리케이션을 실행하기 위한 라이브러리를 찾지 못한다는 얘기다.

위 암호화 모듈이 암호화 작업을 수행할 때, 모든 작업을 자바 라이브러리에서 수행하는 게 아니었던 것이다.
확인해보니 해당 라이브러리에서 암호화를 수행하기 위해 fasoopackager.dll 이라는 파일을 이용하고 있었다.

위와 같이, Java 에서 외부 프로그램에 접근하기 API를 JNI (Java Native Interface) 라고 한다.
해당 플랫폼에서만 실행 가능한 네이티브 코드(native code)에 접근하기 위해 만들어진 응용 프로프로그램 인터페이스로,
주로 자바만으로는 구현할 수 없거나, 다른 언어로 쓰여진 어플리케이션을 접근하려고 하는 경우에 쓰인다.
동작 환경이 해당 플랫폼에 제한된다는 단점이 있다.

JNI 를 사용하기 위해서는 사용하고자 하는 네이티브 라이브러리를 JVM 이 읽어올 수 있게 설정해줘야 한다.
native libary path 가 정상적으러 설정되어 있지 않아서 실행하고자 하는 파일을 찾을 수 없을 때,
보통 아래와 같은 예외가 발생한다.

java.lang.UnsatisfiedLinkError: no 파일명 in library path

native library path 를 설정해주는 방법은 운영체제마다 다른데,
Solaris 시스템 (Unix) 의 경우, LD_LIBRARY_PATH 에 해당 라이브러리의 경로를 설정해주면 된다.

윈도우 환경에서는 PATH 환경 변수에 해당 라이브러리 경로를 추가해주거나,
아래와 같이 자바 실행 옵션에 추가해주면 된다.(SDK 1.2 부터)

java -Djava.library.path=라이브러리 경로 클래스명


위 문제점이 발생한 환경에서는 사정 상 서버의 환경 변수를 추가할 수는 없었다.
다행히 제우스 실행 배치 파일을 확인해보니,
제우스 서버를 올릴 때 java.libarary.path 로 제우스 시스템 라이브러리(JEUS_HOME/lib/system) 폴더를 참조하고 있었다.

여기서는 해당 dll 파일을 제우스 시스템 라이브러리 폴더로 복사해주는 방법으로 해결했다~~


# 참고:

What is java.library.path?
문제 해결의 실마리를 얻은 JavaRanch 의 포럼
JNI 에 대한 위키백과 정보 (영문)

JNI 에 대한 SUN 의 튜토리얼.(영문)
HTML 버전으로 읽어보니 간편하고 좋다.
Introduction and Tutorial 부분만 읽어봤는데, 유래부터 예제까지 쉽게 잘 설명해뒀다.

카테고리

분류 전체보기 (710)
About me. (6)
Daylogs (675)
영어공부 (0)
My works - 추억 (29)
비공개 (0)