네이티브 메서드란 C나 C++같은 네이티브 프로그래밍 언어로 작성한 메서드를 말한다. 즉, Java 소스코드에서 C/C++로 작성한 코드를 호출할 때 사용한다.
public class HelloWorldJNI {
static {
System.loadLibrary("native");
}
public static void main(String[] args) {
new HelloWorldJNI().sayHello();
}
//native method with no body
public native void sayHello();
}
위와 같이 메서드를 선언하고 javac -h . HelloWorldJNI.java
로 실행하면 아래와 같은 파일이 자동생성된다.
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
#ifndef _Included_HelloWorldJNI
#define _Included_HelloWorldJNI
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT void JNICALL Java_HelloWorldJNI_sayHello
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
그리고 C++파일을 작성한다.
#include<iostream>
#include<jni.h>
#include "HelloWorldJNI.h"
void sayHello(){
std::cout << "Hello from C++ !!" << std::endl;
}
JNIEXPORT void JNICALL Java_HelloWorldJNI_sayHello
(JNIEnv* env, jobject thisObject) {
sayHello();
}
그다음,
g++ -c -I”%JAVA_HOME%\include” -I”%JAVA_HOME%\include\win32" HelloWorldJNI.cpp
로 실행하고 g++ -shared -o native.dll HelloWorldJNI.o
를 통해 object file로 부터 dll file을 생성한다.
마지막으로 java HelloWorldJNI
을 통해 java파일을 실행한다. 자세한 내용은 Guide to JNI를 참고하면 된다.
자바가 성숙해가며 (OS 같은)하부 플랫폼의 기능들을 점차 흡수 => 네이티브 메서드 사용의 필요성 하락
예로 Java 9에서 새로 process API를 추가 -> OS 프로세스에 접근가능
private static void infoOfCurrentProcess() {
ProcessHandle processHandle = ProcessHandle.current();
ProcessHandle.Info processInfo = processHandle.info();
log.info("PID: " + processHandle.pid());
log.info("Arguments: " + processInfo.arguments());
log.info("Command: " + processInfo.command());
log.info("Instant: " + processInfo.startInstant());
log.info("Total CPU duration: " + processInfo.totalCpuDuration());
log.info("User: " + processInfo.user());
}
16:31:24.784 [main] INFO c.b.j.process.ProcessAPIEnhancements - PID: 22640
16:31:24.790 [main] INFO c.b.j.process.ProcessAPIEnhancements - Arguments: Optional[[Ljava.lang.String;@2a17b7b6]
16:31:24.791 [main] INFO c.b.j.process.ProcessAPIEnhancements - Command: Optional[/Library/Java/JavaVirtualMachines/jdk-13.0.1.jdk/Contents/Home/bin/java]
16:31:24.795 [main] INFO c.b.j.process.ProcessAPIEnhancements - Instant: Optional[2021-08-31T14:31:23.870Z]
16:31:24.795 [main] INFO c.b.j.process.ProcessAPIEnhancements - Total CPU duration: Optional[PT0.818115S]
16:31:24.796 [main] INFO c.b.j.process.ProcessAPIEnhancements - User: Optional[username]
ex) 레거시 데이터를 사용하는 레거시 라이브러리
하지만, 성능을 개선할 목적으로 네이티브 메서드를 사용하는 것은 거의 권장하지 않는다. JVM은 엄청난 속도로 발전해와 지금의 자바는 다른 플랫폼에 견줄만한 성능을 보인다.
ex) 자바1.1 시절 BigInteger는 C로 작성한 고성능 라이브러리에 의지했으나, 3때 순수 자바로 다시 구현되어 튜닝해 더 네이티브 구현보다도 더 빨라졌다.
하지만 네이티브 라이브러리 쪽은 GNU 다중 정밀 연산 라이브러리를 필두로 개선 작업이 계속 되었으므로 정말로 고성능의 다중 정밀 연산이 필요하다면, 고려해도 좋다.
이펙티브 자바 3/E
Guide to JNI
Java 9 Process API Improvements