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. C/C++ 작성
#include <jni.h> #include <stdio.h> #include "HelloWorld.h" JNIEXPORT void JNICALL Java_HelloWorld_print(JNIEnv *env, jobject obj) { printf("Hello World!!\n"); }
6번에서 생성된 헤더 파일을 보면 C/C++에서 작성해야 할 함수의 원형이 정의되어있다. 거기에 맞춰 함수를 작성한다. 인자로 넘어오는 JNIEnv와 jobject에 대해선 여기서 언급하지 않는다.
8. gcc HelloWorld.c -o lib/libHelloWorld.so -shared -I /usr/java/include -I /usr/java/include/linux
작성된 C/C++을 컴파일한다. 주의할 점은 '-I ' 소문자 '엘'이 아니라 대문자 '아이'다. 또한 생성할 오브젝트 파일의 이름 앞에 'lib'를 붙여야한다. (플렛폼마다 다를 수 있음)
9. java HelloWorld
System.loadLibrary(이름) 는 LD_LIBRARY_PATH에서 이름.so 를 찾는 듯 하다. 따라서 LD_LIBRARY_PATH 가 잘못 정의되어있거나 so파일 이름이 명시된 이름과 다르면 실행시 예외가 발생한다.
주의사항 한가지 더!!
패키지 정보가 변동되어선 안된다. 예를들어 새로운 JAVA 프로그램에서 JNI 연동을 할 경우 만약 그 프로그램이 package common; 을 선언하고 그 안에서 System.loadLibrary("HelloWorld") 를 호출했다면 그 자체의 호출엔 문제가 없으나 라이브러리 함수를 호출하는 시점에서 런타임 에러가 날 것이다.
참고 사이트: http://java.sun.com/docs/books/tutorial/native1.1/index.html
'Software > JAVA' 카테고리의 다른 글
(이전글 2006년) Java Technology Forums - Error message in JNI (0) | 2013.12.05 |
---|---|
(이전글 2006년) jni 사용예 (0) | 2013.12.05 |
(이전글 2009년) - 리눅스 환경에서 JAVA를 이용한 USB이용에 대한 문의드립니다. (0) | 2013.12.04 |
Java Technology Forums - Changin JButton Icons via action performed (0) | 2012.03.02 |
JBUTTON 내부의 텍스트를 회전 하기 위한 방법 (0) | 2012.03.02 |