[Java] Caused by: java.lang.UnsatisfiedLinkError
자바 유료화와 관련하여 OracleJdk → OpenJDK로 변경하여
테스트 작업을 하는 도중 UnsatisfiedLinkError 에러와 함께 ClassNotFoundException까지 발생하였다.
- java.lang.UnsatisfiedLinkError: no xdsp_jni in java.library.path
- java.lang.NoClassDefFoundError: Could not initialize class com.softforum.xdbe.XdspNative
- java.lang.ClassNotFoundException 등등
2. 원인
- Library 경로 오류 또는 해당 Library가 해당 경로에 없는 경우 발생하는 오류 였다.
- 다음과 같은 종류의 오류가 발생하는 경우가 나와 같은 경우일 것 이다.
- java.lang.UnsatisfiedLinkError: no {LIBRARY 이름} in java.library.path
(org.springframework.web.util.NestedServletException: Handler processing failed; nested exception is java.lang.UnsatisfiedLinkError: no xdsp_jni in java.library.path)
3. 해결
- 우리 싸이트 같은 경우 순정 JDK를 사용한 것이 아니었다.
순정 JDK + 별도의 dll 파일은 추가하여 사용한 JDK였기 때문에 이를 모르고 JDK를 교체하였기 때문에 오류가 발생하였다.
[ JDK폴더\bin\ ] 하위 경로에 이전에 사용하고 있던 별도의 dll 파일들을 추가하여 해당 오류를 해결 하였다.
※ 혹시 Library경로가 잘못된 경우 다음과 같은 방법으로 확인 할 수도 있다.
(결론은 어떤 Libarary 경로에 오류에서 확인된 Libarary가 있는지 확인 해 주면 된다.)
1) 이클립스에서 Run -> Run Configurations -> Arguments 에 들어가서 VM arguments에 다음과 같이 옵션을 준다.
-Djava.library.path=dll파일이 위치한 경로
2) 또는 자바 프로그램을 실행할 때 -D 옵션으로 지정한다.
java -Djava.library.path=/home/taehyo/jni_test HelloJNI
3) jvm의 lib 폴더에 해당 jar 복사하여 붙여넣기
(weblogic 등 자체 jvm을 사용하는 경우 해당 jvm이 참조하는 lib 폴더에 복사)
4) Web-inf/lib 폴더에 jar 복사하여 붙여넣기
※ 결정적인 참고가 된 참고내용
- 스택오버 플로우에 다음과 같이 나와 있다.
In order for System.loadLibrary() to work, the library (on Windows, a DLL) must be in a directory somewhere on your PATH or on a path listed in the java.library.
path system property (so you can launch Java like java -Djava.library.path=/path/to/dir).
Additionally, for loadLibrary(), you specify the base name of the library, without the .dll at the end.
So, for /path/to/something.dll, you would just use System.loadLibrary("something").
You also need to look at the exact UnsatisfiedLinkError that you are getting. If it says something like:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no foo in java.library.path
then it can't find the foo library (foo.dll) in your PATH or java.library.path. If it says something like:
Exception in thread "main" java.lang.UnsatisfiedLinkError: com.example.program.ClassName.foo()V
then something is wrong with the library itself in the sense that Java is not able to map a native Java function in your application to its actual native counterpart.
To start with, I would put some logging around your System.loadLibrary() call to see if that executes properly.
If it throws an exception or is not in a code path that is actually executed, then you will always get the latter type of UnsatisfiedLinkError explained above.
As a sidenote, most people put their loadLibrary() calls into a static initializer block in the class with the native methods, to ensure that it is always executed exactly once:
class Foo {
static {
System.loadLibrary('foo');
}
public Foo() {
}
}