JNIインスタンス
Javaがlinux shellコマンドを呼び出すときは、Processによって実現されます.Processは新しいプロセスを開始し、メインプロセスのメモリ情報を新しいプロセスにコピーします.小さなプログラムでは問題ありませんが、プロジェクトが十分大きいと、システムのメモリがプログラム終了に足りない場合があります.
この問題を解決するために、JNIの方が良い案がありますが、この場合はProcessを再開する必要はありません.バックアップメモリの問題もありません.以下は例です.
1.JavaクラスJNIHelper.javaの作成
2.jdkが持参したjavahコマンドによりcヘッダファイルcom_を生成するpracbiz_JNIHelper.h
3.c++ファイルを作成し、ヘッダファイルの方法com_を実現するpracbiz_JNIHelper.cpp
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ファイルをコンパイルするには2つのjavaが提供するライブラリファイル、jni.hとjni_が必要です.md.h、linuxの場合、jni.hはopt/jdk 1.6.0_32/include, jni_md.h存在/opt/jdk 1.6.0_32/include/linux、mac osの場合、両方のファイルは/system/Library/frameworks/JavaVM.framework/Versions/A/Headersディレクトリの下で、異なるlinuxリリース版と異なるjdkバージョンの場所が異なる可能性があります.これは、コンパイル前に自分で次の2つのファイルのパスを確認します.
5.ファイルが生成されたらjava.library.pathを置く必要があります.これによりjvmがロードできるようになります.このディレクトリは何ですか.System.getProperty(「java.library.path」)メソッドで得ることができます.
または-Djava.library.pathで指定してもいいです.以下に説明します.
6.アプリケーションは簡単です.TestJni.javaと書きます.com.pracbiz.b 2 bportal.base.actionパッケージの下に書きます.
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の方が良い案がありますが、この場合は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ファイルをコンパイルするには2つのjavaが提供するライブラリファイル、jni.hとjni_が必要です.md.h、linuxの場合、jni.hはopt/jdk 1.6.0_32/include, jni_md.h存在/opt/jdk 1.6.0_32/include/linux、mac osの場合、両方のファイルは/system/Library/frameworks/JavaVM.framework/Versions/A/Headersディレクトリの下で、異なるlinuxリリース版と異なるjdkバージョンの場所が異なる可能性があります.これは、コンパイル前に自分で次の2つのファイルのパスを確認します.
5.ファイルが生成されたらjava.library.pathを置く必要があります.これによりjvmがロードできるようになります.このディレクトリは何ですか.System.getProperty(「java.library.path」)メソッドで得ることができます.
または-Djava.library.pathで指定してもいいです.以下に説明します.
6.アプリケーションは簡単です.TestJni.javaと書きます.com.pracbiz.b 2 bportal.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