Mine sisu juurde

Java Native Interface

Allikas: Vikipeedia

Java Native Interface (JNI)ontarkvararaamistik,mis võimaldabJava virtuaalmasinas(JVM) jooksvalJavaprogrammil kutsuda väljaoperatsioonisüsteemija riistvaraspetsiifilisi rakendusi ningteeke,mis on kirjutatud teistesprogrammeerimiskeeltes,näiteksC,C++jaAssembler.[1]

JNI võimaldabprogrammeerijallahendada olukorda, kus tarkvara kirjutamine täielikult Javas ei ole võimalik, näiteks kui Java standardteek ei toeta platvormispetsiifilist funktsionaalsust või teeki. Samuti aitab JNI taaskasutada varem mõnes muus programmeerimiskeeles kirjutatud teeki. JNI annab programmeerijale ligipääsu süsteemi madalatasemelistele ressurssidele, näiteksmälujaI/O operatsioonidele,mis teevad programmi kirjutamise keerulisemaks, aga samas ka paindlikumaks.[2]

Üldiselt soovitatakse JNI kasutamist võimalikult palju vältida, kuna välistemasinkoodikskompileeritud teekide kasutamisega muutub rakendusplatvormistsõltuvaks. Selle probleemi lahendamiseks tuleb iga platvormi jaoks kompileerida eraldi teek ning siis lasta Java koodil käivitamise ajal tuvastada kasutaja operatsioonisüsteem ja selle põhjal laadida õige teek.[1]

Selleks, et defineerida süsteemispetsiifilist (inglnative) funktsiooni, tuleb definitsioonis kasutada võtmesõnanative.See annab Javakompilaatorileteada, et funktsioon on implementeeritud eraldiseisvas.so/.dll/.dylib (sõltuvalt operatsioonisüsteemist) failis, mitte ei ole osa Javas kirjutatud koodist.[1]

publicclassJniTest{

privatestaticnativeintsquare(intx);

publicstaticvoidmain(String[]args){
System.loadLibrary("jniTest");
System.out.println(square(20));
}
}

Nüüd sisestamekäsurealjavac -h. JniTest.java,mis genereerib automaatselt selle klassi põhjal meile järgneva päise faili nimegaJniTest.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include<jni.h>
/* Header for class JniTest */

#ifndef _Included_JniTest
#define _Included_JniTest
#ifdef __cplusplus
extern"C"{
#endif
/*
* Class: JniTest
* Method: square
* Signature: (I)I
*/
JNIEXPORTjintJNICALLJava_JniTest_square
(JNIEnv*,jclass,jint);

#ifdef __cplusplus
}
#endif
#endif

Implementatsiooni kirjutame failiJniTest.cpp,mis võiks välja näha umbes nii:

#include"JniTest.h"

JNIEXPORTjintJNICALLJava_JniTest_square(JNIEnv*env,jclassthisOpj,jintx){
returnx*x;
}

Järgmiseks sammuks on C-keeles kirjutatud koodi kompileerimineWindowsilkäsugag++ -c -I%JAVA_HOME%\include -I%JAVA_HOME%\include\win32 JniTest.cpp -o JniTest.o.Viimaseks sammuks on kompileerimisel tekkinud objektifaili linkimine Windowsil käsugag++ -shared -o jniTest.dll JniTest.o -Wl,--add-stdcall-alias.Selle tulemusel tekib jniTest.dll fail, mis laaditakse Java programmis funktsioonigaSystem.loadLibrary( "jniTest" ).Programmi käivitamiseks tuleb määrata JVM parameeterjava.library.path,mille väärtuseks peab määrama DLL-faili asukoha.[1]

Tabel näitab seoseid Java (JNI) ja C keele tüüpide vahel.[3]

C tüüp Java tüüp Kirjeldus
unsigned char jboolean 8 bitti, märgita
signed char jbyte 8 bitti, märgiga
unsigned short jchar 16 bitti, märgita
short jshort 16 bitti, märgiga
long jint 32 bitti, märgiga

long long
__int64

jlong 64 bitti, märgiga
float jfloat 32 bitti
double jdouble 64 bitti
void void N/A

JNI võib tekitada märkimisväärset jõudluse kadu teatud tingimustel[4]:

  • meetodite ja klassimuutujate korduv küsimine – kuna tüübid programmi töö käigus ei muutu, siis on need võimalik pärast esmakordset küsimist salvestada;
  • massiiviüksikute elementide muutmisel sellest täieliku koopia tegemine – JNI pakub ka võimalust küsida ainult vaja minevat osa massiivist;
  • meetodile objekti andmine parameetriks tähendab seda, et riistvaraspetsiifiline kood peab iga objektimuutuja eraldi JVM käest küsima – parem on anda kõik muutujad meetodile eraldi argumentidena kui ühe objektina;
  • kuna JNI meetodi väljakutse võib võtta kuni 5 korda kauem aega kui tavalise meetodi väljakutse, siis on vajalik rakendus disainida nii, et iga JNI väljakutsega tehakse ära võimalikult suur hulk tööd.
  1. 1,01,11,21,3"Guide to JNI (Java Native Interface)".Vaadatud 30.11.2018.
  2. "Oracle javadoc".Vaadatud 30.11.2018.
  3. "Java Fundamentals Tutorial: Java Native Interface (JNI)".Vaadatud 30.11.2018.
  4. "Best practices for using the Java Native Interface".Vaadatud 30.11.2018.