|
Spec-Zone .ru
спецификации, руководства, описания, API
|
API ВызоваГлава 5API Вызова позволяет поставщикам программного обеспечения загружать Java VM в произвольное собственное приложение. Поставщики могут поставить поддерживающие Java приложения, не имея необходимость соединять с Java исходный код VM. Эта глава начинается с краткого обзора API Вызова. Это сопровождается ссылочными страницами для всех API-функций Вызова. Чтобы улучшить возможность встраивания Java VM, API Вызова расширяется в JDK 1.1.2 несколькими незначительными способами. Краткий обзорСледующий пример кода иллюстрирует, как использовать функции в API Вызова. В этом примере код C++ создает Java VM и вызывает статический метод, вызванный
#include <jni.h> /* where everything is defined */
...
JavaVM *jvm; /* denotes a Java VM */
JNIEnv *env; /* pointer to native method interface */
JDK1_1InitArgs vm_args; /* JDK 1.1 VM initialization arguments */
vm_args.version = 0x00010001; /* New in 1.1.2: VM version */
/* Get the default initialization arguments and set the class
* path */
JNI_GetDefaultJavaVMInitArgs(&vm_args);
vm_args.classpath = ...;
/* load and initialize a Java VM, return a JNI interface
* pointer in env */
JNI_CreateJavaVM(&jvm, &env, &vm_args);
/* invoke the Main.test method using the JNI */
jclass cls = env->FindClass("Main");
jmethodID mid = env->GetStaticMethodID(cls, "test", "(I)V");
env->CallStaticVoidMethod(cls, mid, 100);
/* We are done. */
jvm->DestroyJavaVM();
Этот пример использует три функции в API. API Вызова позволяет собственному приложению использовать указатель на интерфейс JNI для доступа функции VM. Проект подобен JRI Netscape, Встраивающему Интерфейс. Создание VM Присоединение к VMУказатель на интерфейс JNI ( У присоединенного потока должно быть достаточное стековое пространство, чтобы выполнить reaonable объем работы. Выделение стекового пространства на поток работает специфичный для системы. Например, используя pthreads, размер стека может быть определен в Разгрузка VMОсновной поток не может отсоединить себя от VM. Вместо этого это должно вызвать VM ожидает, пока основной поток не является единственным пользовательским потоком прежде, чем это фактически разгрузится. Пользовательские потоки включают и потоки Java и присоединили собственные потоки. Это ограничение существует, потому что поток Java или присоединил собственный поток, может содержать системные ресурсы, такие как блокировки, окна, и так далее. Структуры инициализацииРазличный Java реализация VM, вероятно, потребует различных параметров инициализации. Трудно придумать стандартную структуру инициализации, подходящую для всего настоящего и будущего Java VMs. Как компромисс, мы резервируем первое поле (версия), чтобы идентифицировать контент структуры инициализации. Собственные приложения, встраивающие JDK 1.1.2, должны установить поле версии в 0x00010001. Реализации VM поощряются использовать ту же самую структуру инициализации в качестве JDK, хотя другие реализации могут хотеть игнорировать некоторые из параметров инициализации, поддерживаемых JDK. Номера версий 0x80000000 к 0xFFFFFFFF резервируются, и не должны быть распознаны никакой реализацией VM. Следующий код показывает структуру, используемую, чтобы инициализировать Java VM в JDK 1.1.2.
typedef struct JDK1_1InitArgs {
/* The first two fields were reserved in JDK 1.1, and
formally introduced in JDK 1.1.2. */
/* Java VM version */
jint version;
/* System properties. */
char **properties;
/* whether to check the Java source files are newer than
* compiled class files. */
jint checkSource;
/* maximum native stack size of Java-created threads. */
jint nativeStackSize;
/* maximum Java stack size. */
jint javaStackSize;
/* initial heap size. */
jint minHeapSize;
/* maximum heap size. */
jint maxHeapSize;
/* controls whether Java byte code should be verified:
* 0 -- none, 1 -- remotely loaded code, 2 -- all code. */
jint verifyMode;
/* the local directory path for class loading. */
const char *classpath;
/* a hook for a function that redirects all VM messages. */
jint (*vfprintf)(FILE *fp, const char *format,
va_list args);
/* a VM exit hook. */
void (*exit)(jint code);
/* a VM abort hook. */
void (*abort)();
/* whether to enable class GC. */
jint enableClassGC;
/* whether GC messages will appear. */
jint enableVerboseGC;
/* whether asynchronous GC is allowed. */
jint disableAsyncGC;
/* Three reserved fields. */
jint reserved0;
jint reserved1;
jint reserved2;
} JDK1_1InitArgs;
В JDK 1.1.2, структура инициализации обеспечивает рычаги так, чтобы собственное приложение могло перенаправить сообщения VM и получить управление, когда VM завершается. Структуру ниже передают как параметр, когда собственный поток присоединяет к Java VM в JDK 1.1.2. В действительности никакие параметры не требуются для собственного потока присоединить к JDK 1.1.2.
typedef struct JDK1_1AttachArgs {
/*
* JDK 1.1 does not need any arguments to attach a
* native thread. The padding is here to satisfy the C
* compiler which does not permit empty structures.
*/
void *__padding;
} JDK1_1AttachArgs;
Библиотека и управление ВерсиейВ JDK 1.1, как только собственная библиотека загружается, это видимо от всех загрузчиков класса. Поэтому два класса в различных загрузчиках класса могут соединиться с тем же самым собственным методом. Это приводит к двум проблемам:
В Java 2 SDK каждый загрузчик класса управляет своим собственным набором собственных библиотек. Тот же самый JNI собственная библиотека не может быть загружен больше чем в один загрузчик класса. Выполнение так причины
Чтобы облегчить управление управлением версиями и управление ресурсами, библиотеки JNI в Java, 2 Платформы могут дополнительно экспортировать следующие две функции: JNI_OnLoad
JNI_OnLoad когда собственная библиотека загружается (например, через System.loadLibrary). JNI_OnLoad должен возвратить версию JNI, необходимую собственной библиотеке. Чтобы использовать любую из новых функций JNI, собственная библиотека должна экспортировать a РЕДАКТИРОВАНИЕ:Экспортируемый от собственных библиотек, которые содержат собственную реализацию метода. НАЧИНАЯ С SDK/JRE 1.4:Чтобы использовать функции JNI, представленные в выпуске 1.2 J2SE, в дополнение к тем, которые были доступны в JDK 1.1, собственная библиотека должна экспортировать a Чтобы использовать функции JNI, представленные в выпуске 1.4 J2SE, в дополнение к тем, которые были доступны в выпуске 1.2, собственная библиотека должна экспортировать a Если собственная библиотека не экспортирует a JNI_OnUnload
JNI_OnUnload когда загрузчик класса, содержащий собственную библиотеку, собирается "мусор". Эта функция может использоваться, чтобы выполнить операции уборки. Поскольку эта функция вызывается в неизвестном контексте (такой как от финализатора), программист должен быть консервативным при использовании Java службы VM, и рефрен от произвольных обратных вызовов Java. Отметьте это РЕДАКТИРОВАНИЕ:Экспортируемый от собственных библиотек, которые содержат собственную реализацию метода.API-функции вызова
typedef const struct JNIInvokeInterface *JavaVM;
const struct JNIInvokeInterface ... = {
NULL,
NULL,
NULL,
DestroyJavaVM,
AttachCurrentThread,
DetachCurrentThread,
GetEnv,
AttachCurrentThreadAsDaemon
};
Отметьте что три API-функции Вызова, JNI_GetDefaultJavaVMInitArgs
Возвращает конфигурацию по умолчанию для Java VM. Прежде, чем вызвать эту функцию, собственный код must1 установил vm_args-> поле версии к версии JNI, которую это ожидает, что VM будет поддерживать. В JDK 1.1.2, vm_args-> версия должна быть установлена в 0x00010001. После этой функции возвраты vm_args-> версия будет установлена в фактическую версию JNI, которую поддерживает VM. РЕДАКТИРОВАНИЕ:Экспортируемый от собственной библиотеки, которая реализует виртуальную машину Java. ПАРАМЕТРЫ:
ВОЗВРАТЫ:Возвраты “0”, если требуемая версия поддерживается; возвращает отрицательное число, если требуемая версия не поддерживается. JNI_GetCreatedJavaVMs
Возвраты весь Java VMs, которые были созданы. Указатели на VMs пишутся в буфере vmBuf в порядке, они создаются. В большинстве bufLen числа записей будет записан. Общее количество создаваемого VMs возвращается в *nVMs. JDK 1.1.2 не поддерживает создание больше чем одного VM в единственном процессе. РЕДАКТИРОВАНИЕ:Экспортируемый от собственной библиотеки, которая реализует виртуальную машину Java. ПАРАМЕТРЫ:
ВОЗВРАТЫ:Возвраты “0” на успехе; возвращает отрицательное число при отказе. JNI_CreateJavaVM
Загрузки и инициализируют Java VM. Текущий поток становится основным потоком. Наборы JDK 1.1 не поддерживает создание больше чем одного VM в единственном процессе. Поле версии в vm_args must2 быть установленным в 0x00010001. В JDK 1.1, втором параметре В Java 2 SDK мы представляем стандартную структуру инициализации VM. Обратная совместимость сохраняется. Если параметр инициализации VM указывает на a
typedef struct JavaVMInitArgs {
jint version;
jint nOptions;
JavaVMOption *options;
jboolean ignoreUnrecognized;
} JavaVMInitArgs;
typedef struct JavaVMOption {
char *optionString;
void *extraInfo;
} JavaVMOption;
Размер массива обозначается nOptions полем в
Кроме того, каждая реализация VM может поддерживать свой собственный набор нестандартных строк опции. Нестандартные имена опции должны начаться" Вот пример кода, который создает Java VM в Java 2 SDK: JavaVMInitArgs vm_args; JavaVMOption options[4]; options[0].optionString = "-Djava.compiler=NONE"; /* disable JIT */ options[1].optionString = "-Djava.class.path=c:\myclasses"; /* user classes */ options[2].optionString = "-Djava.library.path=c:\mylibs"; /* set native library path */ options[3].optionString = "-verbose:jni"; /* print JNI-related messages */ vm_args.version = JNI_VERSION_1_2; vm_args.options = options; vm_args.nOptions = 4; vm_args.ignoreUnrecognized = TRUE; /* Note that in the Java 2 SDK, there is no longer any need to call * JNI_GetDefaultJavaVMInitArgs. */ res = JNI_CreateJavaVM(&vm, (void **)&env, &vm_args); if (res < 0) ... Java 2 SDK все еще поддерживает РЕДАКТИРОВАНИЕ:Экспортируемый от собственной библиотеки, которая реализует виртуальную машину Java. ПАРАМЕТРЫ:
ВОЗВРАТЫ:Возвраты “0” на успехе; возвращает отрицательное число при отказе. DestroyJavaVM
Разгружает Java VM и исправляет его ресурсы. Только основной поток может разгрузить VM. Система ожидает, пока основной поток только не остается пользовательским потоком прежде, чем это уничтожит VM. Поддержка РЕДАКТИРОВАНИЕ:Индекс 3 в таблице функции интерфейса JavaVM. ПАРАМЕТРЫ:
ВОЗВРАТЫ:Возвраты “0” на успехе; возвращает отрицательное число при отказе. JDK 1.1.2 не поддерживает разгрузку VM. AttachCurrentThread
Присоединяет текущий поток к Java VM. Возвращает указатель на интерфейс JNI в Попытка присоединить поток, который уже присоединяется, нет. Собственный поток не может быть присоединен одновременно к двум Java VMs. Когда поток присоединен к VM, загрузчик класса контекста является программой начальной загрузки. РЕДАКТИРОВАНИЕ:Индекс 4 в таблице функции интерфейса JavaVM. ПАРАМЕТРЫ:
В JDK 1.1, втором параметре В Java 2 SDK Вы передаете
typedef struct JavaVMAttachArgs {
jint version; /* must be JNI_VERSION_1_2 */
char *name; /* the name of the thread, or NULL */
jobject group; /* global ref of a ThreadGroup object, or NULL */
} JavaVMAttachArgs
ВОЗВРАТЫ:Возвраты “0” на успехе; возвращает отрицательное число при отказе. AttachCurrentThreadAsDaemonjint AttachCurrentThreadAsDaemon(JavaVM* vm, void** penv, void* args); Та же самая семантика как AttachCurrentThread, но недавно создаваемый экземпляр java.lang.Thread является демоном. Если поток был уже присоединен или через AttachCurrentThread или через AttachCurrentThreadAsDaemon, эта подпрограмма просто устанавливает значение, на которое указывает penv к JNIEnv текущего потока. В этом случае ни AttachCurrentThread, ни эта подпрограмма не имеют эффекта на состояние демона потока. РЕДАКТИРОВАНИЕ:Индекс 7 в таблице функции интерфейса JavaVM.
vm: экземпляр виртуальной машины, к которому будет присоединен текущий поток. penv: указатель на расположение, в которое будет помещен указатель на интерфейс JNIEnv для текущего потока. args: указатель на структуру JavaVMAttachArgs.
Возвраты обнуляют на успехе; иначе, возвращает отрицательное число.
Ни один. С ТЕХ ПОР:SDK/JRE 1.4 DetachCurrentThread
Отсоединяет текущий поток от Java VM. Выпускаются все мониторы Java, сохраненные этим потоком. Уведомляются все потоки Java, ожидающие этого потока, чтобы умереть. В JDK 1.1, основной поток не может быть отсоединен от VM. Это должно вызвать В Java 2 SDK основной поток может быть отсоединен от VM. Основной поток, который является потоком, который создал Java VM, не может быть отсоединен от VM. Вместо этого основной поток должен вызвать РЕДАКТИРОВАНИЕ:Индекс 5 в таблице функции интерфейса JavaVM. ПАРАМЕТРЫ:
ВОЗВРАТЫ:Возвраты “0” на успехе; возвращает отрицательное число при отказе. GetEnv
РЕДАКТИРОВАНИЕ:Индекс 6 в таблице функции интерфейса JavaVM. ВОЗВРАТЫ:Если текущий поток не присоединен к VM, наборам ПАРАМЕТРЫ:
1. JDK 1.1 не требовал, чтобы собственный код установил поле версии. Для обратной совместимости JDK 1.1.2 предполагает, что требуемая версия является 0x00010001, если поле версии не устанавливается. Будущие версии JDK потребуют, чтобы поле версии было установлено в соответствующее значение. 2. См. сноску 1.
|