java jni开发_Java JNI开发实践记录
当使用到JNI的时候,基本可以肯定Java的平台移植性注定减弱,接下来记录一次使用Java JNI开发的经历。
关于Java JNI的相关资料参见:
下面是使用JNI常见三种场景:
1.在Java应用中标准Java类库不支持平台相关的特性
2.已经存在用其它语言写好的类库,希望通过Java JNI类访问
3.需要使用低级语言(如汇编)来实现时效性要求很高的一小部分代码
这次使用JNI属于第2中场景,由于加解密库使用C来实现的,而在Java应用中使用到其加密后的密文数据,所以解密部分需要此库。
在1和3这两种场景下使用JNI做法相对容易一些,通常先定义好本地方法,然后通过javah生成头文件,接着用其它语言(如C)来实现相应的功能,而2中场景则需要做一些简单的适配,因为类库已经存在,而在Java中定义好的本地方法并不能直接对应类库的具体实现,所以得通过调用已存在的类库中的方法来实现本地方法。
在开始之前有一个坑先看看:
本地编译好的动态库头信息:
[ enc]$ readelf -a libfdsi.so
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian *******
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Shared object file)
Machine: Advanced Micro Devices X86-64
提供方静态库信息:
ELF Header:
Magic: 7f 45 4c 46 02 02 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, big endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (Relocatable file)
Machine: PowerPC64
通过对比应该很清楚了,数据存储模式不同。这里需要明确的是环境一致性很重要。
接下来来从头到尾实现一个Java调用C的一个解密方法。
1.定义Java的本地方法(DataDecryt.java)
package com.cto;
public class DataDecrypt{
native public static String decrypt(String data);
}
2.通过javah命令生成头文件(dd.h)
./javah -classpath . -jni -o dd.h com.cto.DataDecrypt
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class com_cto_DataDecrypt */
#ifndef _Included_com_cto_DataDecrypt
#define _Included_com_cto_DataDecrypt
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_cto_DataDecrypt
* Method: decrypt
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_cto_DataDecrypt_decrypt
(JNIEnv *, jclass, jstring);
#ifdef __cplusplus
}
#endif
#endif
3.定义使用静态库中的方法的头文件(dec.h)
#ifndef __DEC__
#define _DEC__
#ifdef __cplusplus
extern "C"{
#endif
int ts_comm_dec(const char* in , int inlen, char* out, int* outlen);
#ifdef __cplusplus
}
#endif
#endif
ts_comm_dec方法即为已经实现了的解密方法。
4.创建实现dd.h头文件方法的cto.c文件,cto.c中将调用ts_common_dec方法
#include
#include
#include "dec.h"
#include "dd.h"
//about JNI http://doc.oracle.com/javase/1.5.0/docs/guide/jni/spec/functions.html
JNIEXPORT jstring JNICALL Java_com_cto_DataDecrypt_decrypt
(JNIEnv *env, jclass jc, jstring data){
char out_str[48];
const char *enc_str = (*env)->GetStringUTFChars(env, data, 0);
const jsize enc_len = (*env)->GetStringUTFLength(env, data);
int out_len = sizeof(out_str);
ts_comm_dec(enc_str, enc_len, out_str, &out_len);
jstring plain_text = (*env)->NewStringUTF(env, out_str);
(*env)->ReleaseStringUTFChars(env, data, enc_str);
return plain_text;
}
5.编写测试用例(TestDataDecrypt.java)
这里加载的类库cto即为libcto.so。关于动态库静态库命名规则可百度之。
package com.cto;
import com.cto.DataDecrypt;
public class TestDataDecrypt{
static {
System.loadLibrary("cto");
}
public static void main(String [] args){
String plainText= DataDecrypt.decrypt(args[0]);
System.out.println(plainText);
System.out.println("解密之后的长度是:"+plainText.length());
}
}
6.编译动态库
gcc cto.c -shared -fPIC -lstdc++ -I~/soft/jdk1.6.0_45/include -I~/soft/jdk1.6.0_45/include/linux -I~/native/enc libtsbase.a -o libcto.so
7.运行测试
./java -cp . -Djava.library.path=. com.cto.TestDataDecrypt Qt96BsMOKGjZ0oiqqhRqcA==
13********1
解密之后的长度是:11
解密后的结果和预期一致。
8.需要注意的事项
命令:javac java javah是同一版本,有时候可能系统中有多个版本的JDK
权限:从其它地方复制的文件,需要确认读写执行权限
其它:即便按照文中方法来,同样会遇到各种各样的问题,需要多多查看和发现
java jni开发_Java JNI开发实践记录相关推荐
- java web试题_Java web开发经典面试题汇总(内附答案详解)
原标题:Java web开发经典面试题汇总(内附答案详解) 1.说出Servlet 的生命周期,并说出Servlet 和CGI 的区别? 答:Web 容器加载Servlet 并将其实例化后,Servl ...
- java 日志设计_Java日志设计实践(3) - 开发篇
1.选择恰当的日志级别 2.输出明确的提示文字和充分的现场信息 3.输出内容一行搞定,不要换行 4.其他 1.选择恰当的日志级别 选择日志级别时需要遵循一些通用规范,不可随意定义 log4j的日志级别 ...
- java项目流程_Java项目开发全流程实践
文章导读 [项目遵循需求分析.程序设计.编码.测试.运行标准开发过程, 从分析项目问题入手,提出解决方案,应用对象建模工具UML设计系统,依据设计文档进行编码.] 问题描述:实现一个简单的四则运算器. ...
- java 托盘开发_java托盘开发界面记录
设置对话框为圆角: //首先选择设置 JFrame.setDefaultLookAndFeelDecorated(true); JDialog.setDefaultLookAndFeelDecorat ...
- java自动化开发_Java自动化开发指南
一.背景 在Java web开发中,虽然Spring boot已经帮助我们简化了很多工作,但项目中庞杂的业务仍然需要自己去编写较多的 entity,vo,Mapper,Service, Control ...
- java 记事本 新建_java记事本开发
今天我想要分享的是一个用java写的一个记事本程序.我知道现在市面上有各种各样的记事本了,但是我发现有的写的功能不够完善,或者是代码层次结构不够清晰,有的甚至看了之后云里雾里的,有的还不乏了非常明显的 ...
- web开发的java语言步骤_java web开发入门一(servlet和jsp)基于eclispe
servlet 用java语言开发动态资源网站的技术,在doGet方法中拼接显示html,在doPost方法中提交数据.类似于.net的ashx技术. servlet生成的class文件存放在tomc ...
- java系统教程_Java 教程(开发环境配置+基础语法)
Java 开发环境配置 在本章节中我们将为大家介绍如何搭建Java开发环境. window系统安装java 下载JDK 首先我们需要下载java开发工具包JDK,下载地址:http://www.ora ...
- java电话计费系统_java 连接数据库开发的电话计费管理系统
[实例简介] 这是java连接数据库 sql 2000 开发的电话计费管理系统 里面运用的还是比较方便的虽然有一点小问题 [实例截图] [核心代码] 电话计费系统 └── 电话计费系统 ├── all ...
最新文章
- 通过ping命令测试主机与虚拟机之间是否连通
- 网易云信携手小天才Z6手表,让安全“看得见”
- c语言做贪吃蛇vs2015,熬书几个月,终于编出简易的贪吃蛇了,VS2013
- 自适应 幻灯片代码 app_低成本0基础开发app之开发首页幻灯片接口
- Spark(Core)
- 产品经理应该看什么书?
- CAD随机圆形颗粒插件
- 计算机视觉和模式识别领域企业论坛,第三届中国模式识别与计算机视觉大会(PRCV 2020)圆满举办...
- C# 打开CMD窗口并执行CMD 指令
- netware php_Linux中NetWare客户端简易安装说明(转)
- 【SpringBoot整合NoSql】-----ElasticSearch的安装与操作篇
- K.dot和K.batch_dot
- 大国的崛起:第二集:小国大业 荷兰
- 序列回帖与multi-mapped reads的处理
- 身份证男女识别---非线性问题01
- 《神经网络与深度学习》—学习笔记
- 1号店详情页(共5页)
- 计算机程序 申请专利,计算机程序能申请专利吗
- Audio的framecount、framesize、sampleRate计算关系
- git bash里ln -s
热门文章
- 什么时候需要使用cqrs_在CQRS读取模型中使用Hibernate进行快速开发
- jcache_随机JCache内容:多个提供程序和JMX Bean
- 终端查看命令有哪些功能命令_从命令式功能到纯粹功能式功能,再返回:Monads与范围内的延续...
- junit junit_使用junit做其他事情
- 硒测试中所需的功能和示例
- 使用Hibernate和Spring构建Java Web应用程序
- mockito java_使用Mockito在Java中进行模拟入门
- java pojo使用_在POJO中使用ThreadLocal进行Java嵌套事务
- 谓词::不适合Java
- jvm 性能_JVM性能魔术