자바 가 elasticsearch 로 컬 코드 를 호출 하 는 방법

자바 가상 머 신 은 개발 자 들 에 게 바 텀 의 실현 디 테 일 을 차단 하여 개발 자 들 이 바 텀 운영 체제 의 차이 점 을 고려 하지 않 아 도 된다.그러나 일부 응용 프로그램 에 서 는 바 텀 운영 체제 의 네 이 티 브 코드 와 직접 상호작용 을 하 는 것 을 피 할 수 없다.오늘 우 리 는 자바 가 로 컬 호출 에 제공 하 는 지원 을 살 펴 보 자.
1.왜 로 컬 호출 을 해 야 합 니까?
1.성능 에 기초 한 고려
자바 언어 는 운영 속도 에서 볼 때 대부분 바 텀 운영 체제 에서 원생 인 C 와 C++등 언어 보다 느리다.이것 은 주로 자바 가상 컴퓨터 라 는 중간 차원 의 존재 때문이다.자바 언어 로 이 루어 진 성능 이 프로그램의 기대 에 미 치지 못 하면 일부 중요 하고 시간 이 걸 리 는 코드 를 C 나 C++로 선택 할 수 있 습 니 다.
2.특정한 특수 한 수 요 를 바탕 으로
자바 플랫폼 이 제공 하 는 표준 라 이브 러 리 의 기능 은 매우 강하 고 개발 과정 에서 만 날 수 있 는 대부분의 기능 을 포함한다.그러나 아직도 일부 기능 은 표준 API 로 실현 되 지 못 하고 주로 바 텀 하드웨어 플랫폼 과 직접 상호작용 하 는 기능 이다.자바 가상 머 신 은 이 기능 을 실행 중인 프로그램 에 노출 시 키 지 않 았 다.이 기능 이 필요 하 다 면,네 이 티 브 코드 로 만 개발 할 수 있다.
3.기 존의 네 이 티 브 코드 로 작 성 된 프로그램 과 통합 합 니 다.
자바 프로그램 이 바 텀 운영 체제 에서 C 와 C+언어 로 개 발 된 프로그램 과 상호작용 을 해 야 한다 면 로 컬 호출 이 가능 합 니 다.
우리 가 평소에 개발 하 는 더 많은 상황 은 뒤의 두 가지 상황 이다.elasticsearch 에 서 는 기본적으로 두 번 째 상황 에 속한다.
2.JNI 를 사용 하여 로 컬 호출 실현
위 에서 언급 한 여러 가지 상황 에 대해 자 바 는 JNI(Java Native Interface)와 JNA(Java Native Access)두 가지 방식 을 제 공 했 는데 그 중에서 JNI 의 중요 한 사용 장면 중 하 나 는 프로그램의 성능 을 향상 시 키 는 것 이다.프로그램의 핵심 부분의 성능 에 대한 요구 가 비교적 높 을 때 C 와 C++코드 를 사용 하여 실현 할 수 있다.
JNI 를 어떻게 사용 하여 로 컬 호출 을 하 는 지 알 아 보 겠 습 니 다.
우선 로 컬 방법 을 설명 하고 로 컬 코드 라 이브 러 리 를 불 러 오 는 자바 클래스 가 필요 합 니 다.로 컬 방법 은 자바 인터페이스 에서 의 방법 이나 추상 류 에서 의 추상 적 인 방법 과 마찬가지 로 방법 성명 만 포함 하고 관련 된 실현 이 없다.프로그램의 다른 부분 은 정상 적 인 방법 으로 로 컬 방법 을 호출 할 수 있다.예 를 들 어 매개 변수 전달 과 반환 값 사용 등 은 모두 정상 적 인 방법 과 같다.가상 컴퓨터 가 로 컬 방법 을 실행 할 때 로 컬 코드 라 이브 러 리 에서 로 컬 방법의 대응 을 찾 으 려 고 시도 합 니 다.대응 하 는 실현 방법 을 찾 은 후에 가상 기 회 는 매개 변수 전달,실제 방법 호출 과 반환 값 전달 등 업 무 를 담당한다.

public class HelloNative {
    static{
        System.loadLibrary("greetLib");
    }

    public static native  void greeting();
}
다음 단 계 는 로 컬 방법 을 실현 하 는 C/C+코드 를 작성 해 야 합 니 다.자바 가 제공 하 는 명령 행 도 구 는 자바 소스 코드 에 따라 C/C+코드 에 필요 한 헤더 파일 을 생 성 합 니 다.로 컬 방법 에 대해 서 는 헤더 파일 에 대응 하 는 방법 설명 이 포함 되 어 있 습 니 다.

F:\source\JNI\src>javac -h .\ .\HelloNative.java
아래 에서 자동 으로 생 성 된 헤더 파일 을 통 해 우 리 는 이곳 에 많은 암시 적 약속 이 있 음 을 알 수 있 습 니 다.우 리 는 이 성명 에 따라 실현 하면 됩 니 다.구체 적 인 규칙 은 오늘 의 중점 이 아니 라 상세 하 게 설명 하지 않 습 니 다.

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

#ifndef _Included_HelloNative
#define _Included_HelloNative
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     HelloNative
 * Method:    greeting
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_HelloNative_greeting
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif
3.elasticsearch 는 JNA 를 사용 하여 로 컬 호출 을 실현 합 니 다.
위 에서 JNI 에 대한 간단 한 이 해 를 통 해 자바 프로그램 을 만 들 기 전에 사용 할 수 있 는 로 컬 코드 라 이브 러 리 가 있 는 경우 가 더 많 습 니 다.이 로 컬 코드 라 이브 러 리 는 프로그램의 일부분 일 수도 있 고 바 텀 운영 체제 가 자체 적 으로 가지 고 있 을 수도 있다.이러한 로 컬 코드 라 이브 러 리 의 특징 은 구현 할 때 자바 가상 머 신과 의 통합 을 고려 하지 않 았 기 때문에 JNI 와 관련 된 내용 도 사용 하지 않 았 다 는 것 이다.이러한 로 컬 코드 라 이브 러 리 를 사용 할 때,우 리 는 중간 에 있 는 로 컬 코드 라 이브 러 리 를 교량 으로 해 야 한다.이 로 컬 코드 라 이브 러 리 는 자바 프로그램 에서 로 컬 방법의 실현 으로 실제 호출 시의 매개 변수 유형 변환 과 반환 값 전달 등 을 책임 집 니 다.이 과정 은 매우 번 거 로 웠 고 자바 가 JNA 를 제공 해 이런 상황 을 지원 했다.
elasticsearch 가 시 작 될 때 현재 사용자 가 루트 사용자 인지 확인 해 야 한 다 는 것 을 알 고 있 습 니 다.이 검 사 는 직접 호출 된 바 텀 운영 체제 의 코드 입 니 다.elasticsearch 가 JNA 를 어떻게 사용 하 는 지 살 펴 보 겠 습 니 다.
우선 elasticsearch 는 로 컬 방법 을 호출 하 는 입구 로 네 이 티 브 류 를 제공 하고 JNA 의 가용성 을 측정 합 니 다.

 static {
        boolean v = false;
        try {
            // load one of the main JNA classes to see if the classes are available. this does not ensure that all native
            // libraries are available, only the ones necessary by JNA to function
            Class.forName("com.sun.jna.Native");
            v = true;
        } catch (ClassNotFoundException e) {
            logger.warn("JNA not found. native methods will be disabled.", e);
        } catch (UnsatisfiedLinkError e) {
            logger.warn("unable to load JNA native support library, native methods will be disabled.", e);
        }
        JNA_AVAILABLE = v;
    }
JNA 가 사용 가능 한 지 확인 하고 JNANatives 의 맞 춤 법 을 호출 합 니 다.

static boolean definitelyRunningAsRoot() {
        if (!JNA_AVAILABLE) {
            logger.warn("cannot check if running as root because JNA is not available");
            return false;
        }
        return JNANatives.definitelyRunningAsRoot();
    }
JNANatives 의 definitely Running AsRoot 에서 비 windows 시스템 이 라면 호출 합 니 다.
JNACLibrary.geteuid

/** Returns true if user is root, false if not, or if we don't know */
    static boolean definitelyRunningAsRoot() {
        if (Constants.WINDOWS) {
            return false; // don't know
        }
        try {
            return JNACLibrary.geteuid() == 0;
        } catch (UnsatisfiedLinkError e) {
            // this will have already been logged by Kernel32Library, no need to repeat it
            return false;
        }
    }
elasticsearch 는 JNAKernel 32 Library 를 사용 하여 windows 의 Kernel 32 호출 을 패키지 하고 JNACLibrary 를 사용 하여 비 windows 시스템 의 libc 호출 을 패키지 합 니 다.

 static {
        try {
            Native.register("c");
        } catch (UnsatisfiedLinkError e) {
            logger.warn("unable to link C library. native methods (mlockall) will be disabled.", e);
        }
    }

    static native int mlockall(int flags);

    static native int geteuid();
총화
JNI 는 로 컬 호출 을 사용 하여 성능 에 대한 요구 가 높 은 장면 을 해결 하 는 데 더욱 적합 하 며,우리 스스로 C 나 C++를 사용 하여 처리 논 리 를 실현 해 야 합 니 다.기 존의 로 컬 라 이브 러 리 를 호출 하 는 방법 이나 운영 체제 에 대해 서 는 JNA 를 사용 하 는 것 이 편리 하 다.
자바 가 elasticsearch 로 컬 코드 를 호출 하 는 것 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 자바 호출 elasticsearch 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 바 랍 니 다!

좋은 웹페이지 즐겨찾기