Разработка native методов в программах на Java
Native-метод — это метод Java-программы, реализация которого написана на C/C++. Это может понадобиться, например, для доступа к определенным функциям операционной системы, сторонним библиотекам на C/C++ из Java. Множество методов из Java API, взаимодействующих с операционной системой реализовано именно таким образом. Конечно же, стандартная библиотека предоставляет много возможностей, и библиотеки других производителей не отстают, однако разработчикам прикладных программ нужна возможность взаимодействия через native-методы. Не стоит, однако, забывать, что если вы реализуете функциональность с помощью native-методов, вам может протребоваться собрать C/C++ библиотеку для нескольких операционных систем. Не забывайте об основном принципе Java — WORA: Write Once, Run Anywhere.
Давайте рассмотрим пример реализации native-метода. Интерфейс с такими методами называется Java Native Interface (JNI). Предположим, что нужно написать метод, отображающий информацию о текущем состоянии JVM — стеки всех нитей, состояние памяти, и т.д. Точнее, сама JVM умеет выводить такую информацию и вы можете увидеть ее нажав Ctrl-\ на Unix системах или Ctrl-Break на Windows системах. А мы создадим метод, заставляющий JVM это сделать без вмешательства пользователя.
Пишем часть на Java.
JavaDump.java:
public class JavaDump {
static {
System.loadLibrary("JavaDump");
}
/**
* Send SIGQUIT to java process and Ctrl-Break on Windows.
* This will usually cause JVM to dump information about
* current state.
*
* @return true if it was successful
*
*/
public static native boolean javaDump();
public static void main(String[] args) {
javaDump();
}
}
Метод, который будет реализован на C объявляется native. В статическом инициализаторе загружается библиотека, которая будет содержать ревлизацию этого метода. Для unix-систем это будет libJavaDump.so, для Windows - JavaDump.dll.
Компилируем этот класс javac:
> javac JavaDump.java
Используем javah для получения заголовочного файла с объявлением функции javaDump:
> javah JavaDumpПолучается файл JavaDump.h:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class JavaDump */
#ifndef _Included_JavaDump
#define _Included_JavaDump
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: JavaDump
* Method: javaDump
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_JavaDump_javaDump
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
Пишем реализацию этого метода. На Unix-системах будем использовать сигнал SIGQUIT, а на Windows — функцию GenerateConsoleCtrlEvent.
JavaDump.c:
#include "jni.h"
#ifdef _WIN32
#include <windows.h>
#else /* _WIN32 */
#include <unistd.h>
#include <signal.h>
#endif /* _WIN32 */
JNIEXPORT jboolean JNICALL Java_JavaDump_javaDump
(JNIEnv *env, jclass clazz) {
#ifdef _WIN32
int dw;
LPVOID lpMsgBuf;
if (!GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, 0)) {
dw = GetLastError();
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL,
dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0,
NULL);
printf("%s\n", lpMsgBuf);
LocalFree(lpMsgBuf);
return JNI_FALSE;
}
return JNI_TRUE;
#else /* if not _WIN32 */
kill(getpid(), SIGQUIT);
return JNI_TRUE;
#endif /* _WIN32 */
}
Теперь нужно собрать библиотеку для каждой архитектуры. Для каждой архитектуры будем собирать в отдельный каталог. Пусть JDK установлена в /opt/sun-jdk-1.6.0 или C:\Program Files\Java\jdk1.6.0.
Для Linux на архитектуре Intel:
> mkdir linux-i586
> gcc -I/opt/sun-jdk-1.6.0/include -I/opt/sun-jdk-1.6.0/include/linux -shared -fPIC
JavaDump.c -o linux-i586/libJavaDump.so
Для Solaris на архитектуре SPARC:
> mkdir solaris-sparc
> cc -G -KPIC -I/usr/java/include -I/usr/java/include/solaris
JavaDump.c -o solaris-sparc/libJavaDump.so
Для Windows на Intel архитектуре:
> mkdir windows-i586
> cl /LD /MD
/I"C:\Program Files\Java\jdk1.6.0\include"
/I"C:\Program Files\Java\jdk1.6.0\include\win32"
JavaDump.c
/Fewindows-i586/JavaDump.dll
Запускаем:
На Linux-Intel:
> LD_LIBRARY_PATH=linux-i586 java JavaDump
На Solaris-SPARC:
> LD_LIBRARY_PATH=solaris-sparc java javaDump
На Windows:
> set PATH=window-i586;%PATH%
> java JavaDump
Работает.
Но нам пришлось делать одни и те же действия для каждой архитектуры. Все-таки на Java писать проще. Тем более, что большинство получаемой информации доступно и через JVM Monitoring and Management API.
Все, что здесь описано - это, конечно, один из самых простых случаев. Есть много нюансов, о которых можно прочитать по ссылкам:
Удачи Вам!
Н.Х.
опубликовал vmrobot ( апр 11 2006, 07:22:06 PM MSD ) Permalink Комментарии [0]
