본문 바로가기
자바,스프링 - Java,Spring Framework

java jni란?, jni 사용하기, windows에서 jni사용하기, 윈도jni

by devscb 2024. 11. 10.
반응형

java jni란?

jni는 Java Native Interface 입니다.
Java에서 native 코드로 작성된 라이브러리를 연계해줄 수 있는 기술입니다.
예를 들어, C나 C++같은 다른 코드로 작성된 라이브러리와 연계해주는 기술이라고 정의할 수 있습니다.

Java는 기본적으로 JVM위에서 실행되기에 특정운영체제에 종속적이지 않는데요,
모든 운영체제의 기능을 JVM에 담을 수 없기에 특정 OS의 기능을 실행하지 못하는 경우가 존재할 수 있습니다.
이처럼 Java로 구현하기 힘든 기능에 대해 Native Code (예를 들어 C나 C++로 작성된 dll이나 so파일)를 사용할 수 있도록 하게 해주는 기능입니다.
java코드에서는 native 키워드를 사용할 수 있으며, java 기본 라이브러리에서도 사용하고 있습니다.
예를 들어 아래와 같이 java.lang 에서도 사용하고 있는것을 확인할 수 있습니다.
https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/lang/ProcessHandleImpl.java

 

해당 java 클래스의 다른 메소드는 중괄호({})로 메소드의 body가 작성이 되어 있지만,
native 메소드를 보면 따로 body가 작성이 되어있지 않는것을 확인할 수 있습니다.
abstract 메소드나 java interface의 미구현 메소드가 아님에도 body가 없는 이유가
바로 native 키워드를 사용한 jni기술이 사용되었기 때문입니다.
이 메소드의 body는 외부 파일에 작성이 되어 있고, native function은 외부파일의 function 을 호출하는 것입니다.

이를 그림으로 표현하면 아래와 같이 표현할 수 있습니다.

 

java jni 를 사용하기 위한 개요

jni를 사용하기 위한 방식을 소개하려고 하는데요,
아래와 같은 최종 구조로 예제를 소개해드리려고 합니다.

 

@startuml

node "HelloWorldJNI.class" as A {
node "native void sayHello()" as CC
}

node "JNITest.dll" as B {
node "sayHello()" as DD
}
CC -> DD

@enduml

jni를 사용하기 위한 방식은 아래와 같이 진행하면됩니다.
A. java 코드 작성
B. native 코드를 작성하기 위한 header 파일 생성
C. c파일 작성후 빌드
D. java 코드 빌드후 실행

각 스텝별 상세 설명은 아래에 설명합니다.

A. java 코드 작성

HelloWorldJNI.java 파일을 만들어줍니다.
파일 내용은 아래와 같이 native function이 들어간 코드를 작성해주고,
loadLibrary 메소드로 외부 라이브러리를 로드해줍니다.

public class HelloWorldJNI {

    static {
        System.loadLibrary("native");
    }

    public static void main(String[] args) {
        (new HelloWorldJNI()).sayHello();
    }

    private native void sayHello();
}

B. native 코드를 작성하기 위한 header 파일 생성

HelloWorldJNI.java 파일을 작성한 뒤, 커맨드창에 아래와 같이 입력해줍니다.

javac -h . HelloWorldJNI.java

그러면 아래와 같이 .h와 .class 파일 두개가 생긴것을 확인할 수 있습니다.

HelloWorldJNI.h
HelloWorldJNI.class

C. c파일 작성후 빌드

앞서 만든 HelloWorldJNI.h 파일 내용을 보면 아래와 같습니다.

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloWorldJNI */

#ifndef _Included_HelloWorldJNI
#define _Included_HelloWorldJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     HelloWorldJNI
 * Method:    sayHello
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_HelloWorldJNI_sayHello
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

이 중 Java_HelloWorldJNI_sayHello에 대해 함수 내용을 작성해보겠습니다.
HelloWorldJNI.c 파일을 만들고, 아래와 같이 작성합니다.

 #include <stdio.h>
 #include "HelloWorldJNI.h"

JNIEXPORT void JNICALL Java_HelloWorldJNI_sayHello
(JNIEnv *env, jclass obj)
 {
     printf("Hello World!\n");
     return;
 }

그리고 아래와 같은 명령어로 공유 라이브러리 파일을 컴파일합니다. (리눅스의 경우)

gcc -I${JAVA_HOME}/include -shared HelloWorldJNI.c -o HelloWorldJNI.so

windows의 경우, 보통 visual studio 를 많이 쓰실텐데요,
developer command prompt for vs 또는 개발자 명령 프롬프트를 여시고,
아래와 같은 명령어로 빌드하면됩니다.
이 때, 64비트용(x64)으로 열어주셔야 나중에 java에서 호출 할 수 있습니다.
(32비트용으로 하실거면 java도 32비트용으로 빌드해주셔야 합니다. )

cl.exe /LD /EHsc /I "%JAVA_HOME%\include" /I "%JAVA_HOME%\include\win32" HelloWorldJNI.c

 

만일 아래와 같은 에러 발생시, JAVA_HOME이 환경변수로 등록되어있는지 확인해주세요.

fatal error C1083: 포함 파일을 열 수 없습니다. 'jni.h': No such file or directory

만일 developer command prompt for vs를 못 찾으실 경우 커맨드창으로 들어가신 후, 아래와 같은 명령어로 실행하시면 됩니다.

{visual studio 설치 경로}\VC\Auxiliary\Build\vcvars64.bat 
{visual studio 설치 경로}\VC\Tools\MSVC\14.40.33807\bin\Hostx64\x64\cl /LD /EHsc /I "%JAVA_HOME%\include" /I "%JAVA_HOME%\include\win32" HelloWorldJNI.c

그러면 아래와 같이 HelloWorldJNI.dll 파일이 생성된 것을 확인할 수 있습니다.

D. java 코드 빌드후 실행

앞서 컴바일된 HelloWorldJNI.dll 파일이나 HelloWorldJNI.so파일을 java코드가 있는 곳으로 옮깁니다.
HelloWorldJNI.java 에서 이름이 native인 라이브러리를 불러온다고 했으므로,
아래와 같이 파일명을 바꿔줍니다.

HelloWorldJNI.dll -> native.dll
HelloWorldJNI.so -> native.so 

아래와 같이 컴파일 한 후,

javac HelloWorldJNI.java

아래와 같이 실행을 해주면, 공유 라이브러리를 사용하여 프로그램이 실행된 것을 확인할 수 있습니다.

java  HelloWorldJNI -Djava.library.path="."

총평

최근 JNI를 사용할 일이 있었는데, 어떻게 만들어지는지 궁금해서 찾아보게 되었습니다.
먼 옛날 리눅스에서는 사용해본적이 있었던거 같은데,
윈도에서 jni 를 사용하는 방법은 이번 기회에 처음 해보게 되었습니다.
가장 힘들었던것은 visual studio 사용하지 않고 c 파일을 컴파일하는 것이였습니다.
확실히 윈도에서 c언어 개발하려면 visual studio 를 써야 편한거 같네요.
많은 개발자들이 리눅스에서 개발을 많이 하셔서 그런지 윈도는 관련 자료찾기가 어려웠었는데,
이번 포스팅이 다른 분께도 도움이 되었으면 좋겠습니다.

728x90
반응형

댓글