elasticsearch之Java调用本地代码
虽然Java虚拟机为开发人员屏蔽了底层的实现细节,使得开发人员不用考虑底层操作系统的差异性。不过在某些应用程序中,还是免不了要直接与底层操作系统上的原生代码进行交互。今天我们就来看一下Java对本地调用提供的支持。
一、为什么要进行本地调用
1.基于性能的考虑
Java语言从其运行速度上来说,在大多数方面是慢于底层操作系统上原生的C和C++等语言的。这主要是由于Java虚拟机这个中间层次的存在。如果完全用Java语言实现的性能无法达到程序的预期要求,可以选择把部分重要且耗时的代码用C或C++来实现。
2.基于某些特殊的需求
Java平台提供的标准类库的功能很强大,包括了在开发中可能遇到的大部分功能。但是仍然有一些功能无法用标准API来实现,主要是一些与底层硬件平台直接交互的功能。Java虚拟机没有把这一部分功能暴露给运行在其上的程序。如果需要这方面的功能,那么只能使用原生代码来进行开发。
3.与已有的使用原生代码编写的程序之间进行集成。
如果Java程序需要与底层操作系统上由C和C++语言开发的程序进行交互,那么可以进行本地调用。
我们平时的开发更多的情况是后边两种情况;在elasticsearch中基本上是属于第二种情况。
二、使用JNI实现本地调用
针对以上提到的各种情况,Java提供了JNI(Java Native Interface)和JNA(Java Native Access)两种方式,其中JNI的一个重要使用场景是提高程序的性能。当对程序中关键部分的性能要求比较高的时候,可以使用C和C++代码来实现。
我们先来看下怎么使用JNI来进行本地调用。
首先我们需要有一个Java类来声明本地方法,并负责加载本地代码库。本地方法与Java接口中的方法或抽象类中的抽象方法一样,只包含方法声明,没有相关的实现。程序中的其他部分可以用正常的方法调用本地方法,比如参数传递和返回值使用等都与正常的方法相同。当虚拟机在执行本地方法时,会尝试在已经加载的本地代码库中查找本地方法的对应实现。在查找到对应的实现方法之后,虚拟机会负责进行参数传递、实际方法调用和返回值传递等工作。
public class HelloNative {
static{
System.loadLibrary("greetLib");
}
public static native void greeting();
}
下一步要编写实现本地方法的C/C++代码。Java提供的命令行工具根据Java源代码生成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
三、elasticsearch使用JNA实现本地调用
通过上边对JNI的简单了解,我们更多的时候碰到的情况是,在编写Java程序之前,就已经有了可以使用的本地代码库。这个本地代码库可能是程序的一部分,也可能是底层操作系统自带的。这些本地代码库的特点是在实现的时候并没有考虑与Java虚拟机的集成,因此也没有使用与JNI相关的内容。在使用这样的本地代码库时,我们就需要一个中间的本地代码库作为桥梁。这个本地代码库作为Java程序中本地方法的实现,负责实际调用时的参数类型转换和返回值传递等工作。这个过程是十分的繁琐的,Java提供了JNA来支持这种情况。
我们知道elasticsearch启动的时候需要检测当前用户是否是root用户,这个检测是直接调用的底层操作系统的代码,我们来看下elasticsearch是怎样使用JNA实现的。
首先elasticsearch提供了Natives类,作为调用本地方法的入口,并负责检测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的definitelyRunningAsRoot中,如果是非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使用JNAKernel32Library来封装对windows的Kernel32的调用,使用 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之Java调用本地代码的更多相关文章
- Android使用JNI(从java调用本地函数)
当编写一个混合有本地C代码和Java的应用程序时,需要使用Java本地接口(JNI)作为连接桥梁.JNI作为一个软件层和API,允许使用本地代码调用Java对象的方法,同时也允许在Java方法中调用本 ...
- [JNI] Java 调用 C++ dll
首先介绍一下JNI吧! JNI 是Java提供的一个用于调用本地接口的接口层,位于Java代码 和 本地代码之间的一层:主要功能是 数据类型的转换,还有就是通过这一层来调用本地代码! 下面就说说Jav ...
- java调用dll-JNA
介绍 给大家介绍一个最新的访问本机代码的 Java 框架 —JNA . JNA(Java Native Access) 框架是一个开源的 Java 框架,是 SUN 公司主导开发的,建立在经典的 JN ...
- JAVA调用c/c++代码
JNI是Java Native Interface的缩写,中文为JAVA本地调用.使用JNI可以很方便的用我们的Java程序调用C/C++程序.很多时候,某些功能用Java无法实现,比如说涉及到底层驱 ...
- ElasticSearch5在Ubuntu系统下的安装和Java调用
ElasticSearch是开源搜索平台的新成员,实时数据分析的神器.可以理解为作为搜索的数据库,可以提供搜索功能.对比关系型数据库,具有以下的相似关系: 关系型数据库 数据库 表 行 列 Elast ...
- java调用Linux执行Python爬虫,并将数据存储到elasticsearch--(环境脚本搭建)
java调用Linux执行Python爬虫,并将数据存储到elasticsearch中 一.以下博客代码使用的开发工具及环境如下: 1.idea: 2.jdk:1.8 3.elasticsearch: ...
- Java调用DLL有多种方式,常用的方式有JNative、JNA、JNI等。
JNative方式调用dll JNative是一种能够使Java语言使调用DLL的一种技术,对JNI进行了封装,可能有些读者会有这样一个问题,JNative对JNI进行了封装,并且是一种跨语言的使用D ...
- native关键字(本地方法)、 java调用so动态链接库
Java native关键字 一. 什么是Native Method 简单地讲,一个Native Method就是一个java调用非java代码的接口.一个Native Method是这样一个ja ...
- [JNA系列]Java调用Delphi编写的Dll之JNA使用
介绍 给大家介绍一个最新的访问本机代码的 Java 框架 —JNA . JNA(Java Native Access) 框架是一个开源的 Java 框架,是 SUN 公司主导开发的,建立在经典的 JN ...
随机推荐
- react new features 2020
react new features 2020 https://insights.stackoverflow.com/survey/2019#technology-_-web-frameworks h ...
- PAA房产智慧社区:解决社区管理服务的痛点难点
社区,是社交与生活的舞台,更是家的延伸.社区之所有能够有所创新发展,得益于借助数字化和智能化.智能化给社区带来的便利体现在社区门禁可以人脸识别:AI的摄像头可以自动捕获异常的现象,便于社区管理员第一时 ...
- Datahero Inc利用区块链溯源,造福各行各业
近些年来,随着区块链技术的不断崛起以及快速发展,越多越多的人提出将区块链技术引入到溯源系统当中,溯源也成为了区块链技术的重要应用场景之一. 目前,Datahero inc已建设一整套的溯源平台系统,基 ...
- 蓝桥杯——试题 算法训练 Yaroslav and Algorithm
试题 算法训练 Yaroslav and Algorithm 资源限制 时间限制:100ms 内存限制:128.0MB 问题描述 (这道题的数据和SPJ已完工,尽情来虐吧!) Yaroslav喜欢算法 ...
- 学习笔记-python基础
一. 1.python按装 1.1 官网 https://www.python.org 1.2 点 downloads下的 windows下载64位python3.7.3版本 Download Win ...
- 微信小程序:解决小程序中有些格式如webpiPhone手机暂不支持的问题
问题:小程序中有些格式是iPhone手机暂不支持的,如goods_introduce中的webp格式,在小程序的模拟器中是可以正常显示webp格式的,但是一旦你做真机调试,很可能某些iPhone手机是 ...
- SpringBoot2.x中的AOP机制总结(附带demo)
寄语:刚开始学aop的时候是大三吧,老师讲的不好,我也没学好,导致现在才有个较为清晰的认知,那个时候只知道有aop, 根部不明白aop的作用,时至今日,任然觉得aop难以咀嚼,奈何平时不用面试要用,特 ...
- 小白养成记——JavaWeb之文件的上传
文件的上传推荐使用commons的fileupload组件来完成.该组件还依赖于io包,因此需要用到两个jar包: commons-fileupload-X.X.jar commons-io-X.X. ...
- NodeJs 入门到放弃 — 常用模块及网络爬虫(二)
码文不易啊,转载请带上本文链接呀,感谢感谢 https://www.cnblogs.com/echoyya/p/14473101.html 目录 码文不易啊,转载请带上本文链接呀,感谢感谢 https ...
- 快速电路仿真器(FastSPICE)中的高性能矩阵向量运算实现
今年10-11月份参加了EDA2020(第二届)集成电路EDA设计精英挑战赛,通过了初赛,并参加了总决赛,最后拿了一个三等奖,虽然成绩不是很好,但是想把自己做的分享一下,我所做的题目是概伦电子出的F题 ...