Java调用linux shell命令的时候,是通过Process来实现的,Process会新起一个进程,并且把主进程的内存信息拷贝一份到新的进程中,对于小的程序这种方式没问题,但如果项目足够大,就会导致系统内存不够程序退出的情况发生。
为了解决这个问题,有一个比较好的方案是JNI,这个时候并不需要重新起一个Process,也就不会存在备份内存的问题,下面是一个例子.
1.编写java类JNIHelper.java
package com.pracbiz;
public class JNIHelper
{
static
{
System.loadLibrary("JNI");
}
public native String exec(String input);
private static JNIHelper instance;
private JNIHelper()
{
}
public static JNIHelper getInstance()
{
synchronized(JNIHelper.class)
{
if(instance == null)
{
instance = new JNIHelper();
}
}
return instance;
}
public static void main(String[] args)
{
getInstance().exec("pwd");
}
}
2.通过jdk自带的javah命令生成c头文件com_pracbiz_JNIHelper.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_pracbiz_JNIHelper */
#ifndef _Included_com_pracbiz_JNIHelper
#define _Included_com_pracbiz_JNIHelper
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_pracbiz_JNIHelper
* Method: exec
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_pracbiz_JNIHelper_exec
(JNIEnv *, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endif
3.编写c++文件,实现头文件中的方法com_pracbiz_JNIHelper.cpp
#include "com_pracbiz_JNIHelper.h"
#include <string.h>
#include <errno.h>
#include <iostream>
#include <cstdlib>
#include <string>
#include <iomanip>
using namespace std;
JNIEXPORT jstring JNICALL Java_com_pracbiz_JNIHelper_exec
(JNIEnv *env, jobject obj, jstring input)
{
std::string result;
std::string cmd;
FILE *fstream=NULL;
char buff[1024]="";
char const *str = (char *)env->GetStringUTFChars(input, NULL);
char const *ext = " 2>&1";
cmd.append(str);
cmd.append(ext);
memset(buff,0,sizeof(buff));
if(NULL==(fstream=popen(cmd.c_str(),"r")))
{
fprintf(stderr,"execute command failed: %s",strerror(errno));
env->ReleaseStringUTFChars(input, str);
return env->NewStringUTF("-1");
}
env->ReleaseStringUTFChars(input, str);
while (NULL!=fgets(buff, sizeof(buff), fstream))
{
result.append(buff);
}
if (fstream != NULL)
{
pclose(fstream);
}
return env->NewStringUTF(result.c_str());
}
int main()
{
return 0;
};
4.生成对应的jni可执行文件,注意命名格式,linux结尾为.so, mac os结尾为.jnilib
linux:
gcc -Wall -fPIC -I./ -I/opt/jdk1.6.0_32/include -I/opt/jdk1.6.0_32/include/linux -shared -o libJNI.so com_pracbiz_JNIHelper.cpp -lstdc++
mac os:
gcc -Wall -fPIC -I./ -I/System/Library/Frameworks/JavaVM.framework/Versions/A/Headers -shared -o libJNI.jnilib com_pracbiz_JNIHelper.cpp -lstdc++
-l是编译时的路径参数,编译JNI文件需要两个java提供的库文件,jni.h和jni_md.h,对于linux, jni.h在opt/jdk1.6.0_32/include, jni_md.h存在/opt/jdk1.6.0_32/include/linux, 对于mac os来说,这两个文件都在 /System/Library/Frameworks/JavaVM.framework/Versions/A/Headers目录下,不同的linux发行版以及不同的jdk版本可能位置会有所不同,这个在编译之前自己去确认下两个文件的路径。
5.文件生成好以后需要放到java.library.path,这样jvm才能加载到,那这个目录是什么呢,通过System.getProperty("java.library.path")方法就可以得到.
或者可以通过-Djava.library.path指定也行,下面会讲到。
6.应用很简单,写个TestJni.java,我是写在com.pracbiz.b2bportal.base.action包下面的.
system.out.println(JNIHelper.getInstance().exec("ls -la"));
以linux平台为例,如果so文件没有放到java.library.lib下,则运行时通过-Djava.library.path指定.so文件的路径
java -Djava.library.path=/home/oyl-admin/b2bportal/EC-Portal/branches/fp-phase2-client/web/WEB-INF/classes com.pracbiz.b2bportal.base.action.TestJni
如果已经放到java.library.lib下,则直接运行
java com.pracbiz.b2bportal.base.action.TestJni
分享到:
相关推荐
代码用来演示第一个jni实例!对初学者很实用!
jni实例 已Eclipse测试可用,让你清楚的了解jni调用的流程.
linux JNI实例及其JNI编程模板
JNI实例,jni的基本使用,包括回调,传递map集合,处理复杂对象等等的使用
Android JNI实例01
简单jni实例调用第三方.so库
简单的jni实例学习,对初学者很好的实例
首先需要下载安装ndk,他负责创建so库同你的android代码打包成apk文件。高版本的ndk自带打包工具,所以不需要再安装cygwin了,详情见博客
是一个jni实例,包括返回一个字符串,返回一个对象
JNI 实例, 可以作为模板供初学者学习. 纯C版本, 用Cgwin下的Makefile编译而成. 有利于初学者。
JNI 实例, 可以作为模板供初学者学习, 例子很详细, 源代码很详细,给初学者的帮助. 采用VC++ 6.0作为编译器. 还提供cygwin下的纯C版本的编译,对初学者的帮助会更大
Android JNI 实例,包括动态注册JNI ,静态注册JNI
Android JNI 实例,实例很简单,就一个Hello World
第一次用java的jni调用c++的dll程序,运行挺好的,内部还有很多说明,有兴趣的可以看看哟!!!
看到关于JNI方面的知识,先来分享一下吧!
Mstar平台JNI实例 个人资料备份 验证通过
JNI操作实例代码 1.java项目代码 2.C++ 项目代码,创建DLL文件类型项目 文档下载路径: http://download.csdn.net/detail/zhoupeng_love/9562563
androidJNI初始入门基础案例 androidJNI操作指南
本文档根据网上的学习资料和本人的亲身实践,详细讲解了在windows系统平台下如何配置ndk的过程。 1、安装cygwin 2、下载ndk 3、ndk和cygwin的配置 4、下载安装eclipse插件cdt ...6、运行实例hello-jni