시소당
JAVA라는 언어가 플렛폼 독립적임을 추구함으로써 생기는 커다란 장점 뒤에는 특정 플렛폼에 종속적인 기능을 수행하지 못한다는 관점에 따라선 커다란 단점이 있다. 이를 해결하기 위한 해결책이 JNI - Java Native Interface 이다. JNI 는 JAVA로부터 C/C++을 호출할 수 있도록 해준다.
JAVA가 JVM을 통해 해석되어 실행되는 메커니즘 때문에 잃는 속도를 JNI로 충당할 수 있다고 말하는 사람도 있다. 그러나 적어도 내 주관적인 의견으로는 단지 속도 문제가 거슬려서 JNI를 이용하는 것은 부적절한 행동이라 생각한다.
그렇다면 왜 나는 JNI를 서술하고 있는가? JNI의 주된 용도는 레거시 시스템과의 연동과 플렛폼 종속적인 기능의 사용에 있다. 리눅스가 설치된 컴퓨터에 모터가 달려있고 이것을 제어하기 위한 드라이버가 C API만 제공한다면 JAVA를 이용하는 개발자는 JNI가 필수적이다. 지금 말한 이것이 내가 JNI를 서술하고 있는 이유이다.
리눅스에서의 JNI 사용 튜토리얼
1. mkdir JNI/lib
2. cd JNI
3. export LD_LIBRARY_PATH=`pwd`/lib
LD_LIBRARY_PATH가 설정되어있지 않으면 컴파일된 JAVA 클래스의 실행시 native 호출 대상을 찾을 수 없어서 System.loadLibrary() 에서 예외가 발생한다.
4. java 클래스 작성
public class HelloWorld {
static {
System.loadLibrary("HelloWorld");
}
public native void printHelloWorld();
public static void main(String[] args) {
new HelloWorld().print();
}
}
System.loadLibrary() 를 통해 JNI로 연동할 so 파일명을 서술한다. static 블럭으로 설정해야한다. C/C++로 구현한 함수의 호출은 native 키워드를 사용해 정의한다.
5. java 클래스 컴파일 (저 상태로 컴파일에 전혀 문제가 없다)
6. javah -jni HelloWorld
C/C++ 을 위한 헤더 파일을 생성한다. javah 뒤에 컴파일된 클래스가 와야하므로 컴파일이 먼저고 헤더 생성이 다음이다.
7. 6에서 생성한 헤더를 구현: C/C++ 코드 작성
#include <JNI.H>
#include <STDIO.H>
#include "HelloWorld.h"
JNIEXPORT void JNICALL Java_HelloWorld_print(JNIEnv *env, jobject obj) {
printf("Hello World!!");
}
6번에서 생성된 헤더 파일을 보면 C/C++에서 작성해야 할 함수의 원형이 정의되어있다. 거기에 맞춰 함수를 작성한다. 인자로 넘어오는 JNIEnv와 jobject에 대해선 여기서 언급하지 않는다.
8. 7에서 생성한 코드 컴파일: gcc HelloWorld.c -o lib/libHelloWorld.so -shared -I /usr/java/include -I /usr/java/include/linux
작성된 C/C++을 컴파일한다. 주의할 점은 '-I ' 소문자 '엘'이 아니라 대문자 '아이'다. 또한 생성할 오브젝트 파일의 이름 앞에 'lib'를 붙여야한다. (플렛폼마다 다를 수 있음)
9. java 클래스 실행: java HelloWorld
System.loadLibrary(이름) 는 LD_LIBRARY_PATH에서 이름.so 를 찾는 듯 하다. 따라서 LD_LIBRARY_PATH 가 잘못 정의되어있거나 so파일 이름이 명시된 이름과 다르면 실행시 예외가 발생한다.
주의사항!!
자 바의 패키지 정보가 변동되어선 안된다. 예를들어 새로운 JAVA 프로그램에서 JNI 연동을 할 경우 만약 그 프로그램이 package common; 을 선언하고 그 안에서 System.loadLibrary("HelloWorld") 를 호출했다면 그 자체의 호출엔 문제가 없으나 라이브러리 함수를 호출하는 시점에서 런타임 에러가 날 것이다. 이 경우 5번부터 다시 작업해야한다.
참고 사이트: http://java.sun.com/docs/books/tutorial/native1.1/index.html
출처 : http://java-project.tistory.com/2