Professional Documents
Culture Documents
Beograd, 2010
Sadrzaj
Rezime ................................................................................................................................................ 4
Uvod .................................................................................................................................................... 5
1. Integrativno programiranje java/C++ ................................................................................................ 6
1.1. Runtime.Exec............................................................................................................................ 7
1.2. JNI-JAVA NATIVE Interface ...................................................................................................... 9
1.2.1 Primjena JNI ........................................................................................................................ 9
1.2.2. Problemi ............................................................................................................................. 9
1.2.3. Način na koji funkcioniše JNI .............................................................................................. 9
1.2.4. Mapiranja native i Java tipova podataka ........................................................................... 10
1.2.4. Ostale primjene ................................................................................................................ 10
1.3 KNI-K Native Interface ............................................................................................................. 11
1.4. CNI-Compiled Native Interface ................................................................................................ 12
1.4.1. Java kao podskup C++ ..................................................................................................... 12
1.4.2. GCJ kompajler .................................................................................................................. 12
1.4.3. CNI framework.................................................................................................................. 12
1.5. SWIG-Simplified Wrapper and Interface Generator ................................................................. 13
1.5.1. Swig i Java ....................................................................................................................... 13
1.6. JNA-Java Native Access ......................................................................................................... 14
2. Primjer upotrebe JNI, kreiranjem projekta u Eclipse-u i Visual Studiju ........................................... 15
2.1. Ukratko o primjeru ................................................................................................................... 15
2.2. Java projekat........................................................................................................................... 17
2.2.1. Kreiranje projekta i Bean klase ......................................................................................... 17
2.2.2. Kreiranje JniExample ........................................................................................................ 19
2.2.3. Kreiranje Main klase ......................................................................................................... 21
2.3. C++ projekat (dll) .................................................................................................................... 23
2.3.1. Pozivanje javah i javap preko External Tools iz Eclipse-a ................................................. 23
2.3.2. Uključivanje generisanog header fajla u projekat .............................................................. 24
2.3.3. Implementacija klase JniExampleLibrary.cpp.................................................................... 26
2.4. Testiranje poziva izmeĎu Java projekta i C++ dll-a.................................................................. 34
2.4.1. Kompajliranje DLL-a ......................................................................................................... 34
2.4.2. Konfigurisanje putanje do dll-a u Eclipse-u ....................................................................... 34
2|Strana
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
3|Strana
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
REZIME
Java okruženje i jezik je siguran i efikasan način za razvoj aplikacija. Pa ipak, ponekad je za
aplikaciju potrebna odreĎena funkcionalnost, koju Java, zbog svoje težnje da bude
multiplatfomska, nije moguce postići, ili bar ne upotrebom same Jave.
Primjer za to su:
integracija sa postojećim bibliotekama direktno vezanim za funkcionalnosti nekog
operativnog sistema, ili hardvera
integracija sa kodom koji je najčešće napisan u C/C++, za postizanje većih performansi, ili
bolje iskorištenje sistema
Zbog toga je razvijen standard, JNI-Java Native Interface. O njemu će biti riječi u prvom dijelu
rada, načinu na koji funkcioniše, mapiranjima izmedju C/C++ i Java tipova podataka, kao i
problemima koji nastaju upotrebom ovog API-ja.
Sem JNI, biće predstavljeni i
KNI-K Native Inteface, namjenjen ureĎajima sa ograničenim hardverskim mogućnostima,
koji predstavlja podskup JNI,
CNI-Compiled Native Interface, gdje se Java posmatra kao podskup C++,
SWIG- Simplified Wrapper and Interface generator, interfejs kompajler koji povezuje
programe napisane u C i C++, sa skriptnim jezicima (Lua, Perl, Python, Ruby, Tcl) ali i
drugim, kao što je Java
JNA- Java native access, koji omogućava Java programima lak i brz pristup native
bibliotekama, bez upotrebe JNI interfejsa.
Ponekad je potrebno samo pokrenuti neki utility program, ili drugi u okviru Java programa. Tada je
moguće koristiti Runtime.exec komandu pa će i ona biti predstavljena.
U drugom dijelu rada, biće predstavljen primjer upotrebe JNI kroz JniExample Java projekat, i C++
projekat JniExampleLibrary, odnosno pozivanje Java metoda iz C++ biblioteke, i obrnuto,
pozivanje C++ metoda iz Java projekta. Okruženja korištena za izradu ova dva projekta su
Eclipse i Visual Studio 2010.
Sem izrade, naglasak je i na debug-u projekata, a posebna pažnja posvećena je i problemima koji
mogu nastati upotrebom ovog API-ja, tj. pucanja Java virtuelne mašine izazvanim loše
napisanim C++ kodom.
Uz ovaj rad priloženi su:
JniExample, Java projekat, uraĎen u Eclipse-u Helios (JniExample.rar)
JniExampleLibrary, C++ Win 32 projekat, uraĎen u Visual Studiju 2010
(JniExampleLibrary.rar)
4|Strana
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
UVOD
Često se javlja potreba da iz Java virtuelne mašine treba da pristupimo nekoj native1 metodi, npr.
grafičkim funkcijama niskog nivoa, pristupu fajlovima, funkcijama mreže, i drugim rutinama, koje
zavise od operativnog sistema u kome su implementirane, ili čak niže, na nivou harvera.
Ovakve metode su napisane u native kodu, koji se kompajliranjem prevodi na mašinski jezik
razumljiv hardveru. Način na koji će ove metode biti dostupne JVM može da varira, zavisno i od
načina na koji je sama JVM implementirana. Sa ciljem da se minimizuje rad potreban za
portabilnost ovakvog koda, uspostavljen je standard JNI (Java Native Interfaces).
Namjena JNI standarda je da:
posluži kao standardizovan interfejs ka virtualnoj mašini, tako da će iste native metode
jednako raditi pod različitim mašinama
obezbjedi na nivou Jave univerzalni API za dinamičko učitavanje biblioteka napisanih u
native kodu i pozivanju njihovih metoda
Naravno, ovo nije jedini način da se iz Java programa pozivaju native metode, napisane u native
programima, i zavisno od tipa interakcije izmedju njih, na raspolaganju je još nekoliko API-ja.
MeĎutim, sem pozitivnih strana ovakve interakcije, ne treba zaboraviti da:
loše napisan native kod može da obori čitavu JVM
zbog univerzalnosti implementacije API-ja, gubi se na brzini izvršavanja, kao i korišćenja
veće količine memorijskih resursa
dinamičko učitavanje i pozivanje native metoda iz Java programa može stvoriti sigurnosne
probleme, obzirom na nedostatak Java 2 security modela
Cilj integracije je iskorišćenje mogućnosti oba programska jezika, zavisno od potreba napisanog
Java programa, uz voĎenje računa o problemima koji mogu nastati pri ovakvoj implementaciji.
1
Native- metoda napisana u programu koji radi direktno sa hardverom, ili sa operativnim sistemom, na
niskom nivou.
5|Strana
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
6|Strana
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
1.1. RUNTIME.EXEC
Runtime.exec je jednostavan interfejs, ka platformski zavisnim utility programima i aplikacijama. U
najprostijoj formi, primejer poziva Unix ls komande bi bio:
Process p = Runtime.getRuntime().exec("/bin/ls");
Za razliku od fork metode C-a, ne dozvoljava nam da direktno kontrolišemo okruženje. Novi proces
vrši redirekciju STDIN, STDOUT, STDERROR, pa rezultat poziva ne dobijamo na ekranu.
Umjesto toga, moramo koristiti getInputStream(), getOutputStream() i
getErrorStream()metode procesa, da bismo komunicirali sa pozvanim programom.
U listingu je dat primjer poziva komande ls:
Import java.io.*;
class execInput {
public static void main(String Argv[]) {
try {
String ls_str;
try {
while ((ls_str = br_in.readLine()) != null) {
System.out.println(ls_str);
}
} catch (IOException e) {
System.exit(0);
}
} catch (IOException e1) {
System.err.println(e1);
System.exit(1);
}
System.exit(0);
}
}
Od verzije JDK 1.1 PATH varijabla je poznata, ali je i pored toga dobra praksa proslijeĎivati punu
putanju do programa koga pokrećemo.
Shell ugradjene komande operativnog sistema neće raditi u svim slučajevima, bar ne na
jednostavan način koa što smo navikli. Npr. za poziv DOS dir komande, poziv bi bio
command \c dir
Ukoliko želimo da proslijedimo više parametara za redom, umjesto pisanja komande u stringu i
proslijeĎivanja exec metodi, potrebno je napraviti komandu kao niz stringova, i takav niz predati
za argument.
Postoje četiri overloaded exec metode klase Proces, redom:
7|Strana
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
Trošak upotrebe ove komande je što gubimo na portabilnosti napisanog Java softvera, dok je sa
druge strane najjednostavniji način da koristimo, i pokrećemo alate i utility-je operativnog
sistema, ali i druge programe. Česta primjena kod Java programera je upotreba ove komande
za pozivanje eksterno napisanih Help stranica (.chm i sl.) za aplikacije iz kojih se pokreću.
8|Strana
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
1.2.2. PROBLEMI
Postoji niz problema sa kojima se suočavamo, upotrebom JNI, kao npr.:
greške u upotrebi JNI mogu destabilizovati čitavu JVM, a koje je ponekad teško otkriti ili
debug-ovati
samo aplikacije i potpisani apleti mogu koristiti JNI
aplikacija gubi na portabilnosti upotrebom JNI, moguće rješenje je da napišemo posebnu
implementaciju za svaku platormu, a onda da koristimo AbstractFactory pattern, zavisno od
platfome
JNI ne obezbjeĎuje Garbage Collector, za resurse koji nisu u direktnoj vezi sa JVM, znači
moramo voditi računa o svim objektima instanciranim u okviru native metoda, i njihovom
uništavanju
provjera grešaka je obaveza pri ovakvoj implementaciji, obzirom da ove greške mogu
oboriti čitavu JVM
koristi se modifikovani UTF-8, u metodama JNI poput NewStringUTF i sl.
9|Strana
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
suštini, bilo što što Java kod može da uradi, može da se uradi i preko JNIEnv, ali na dosta
komplikovaniji način.
Primjer upotrebe je instanciranje objekata, kreiranje stringova, i sl., o čemu ce biti riječi u drugom
dijelu izlaganja. Kod napisan u C++ koji koristi JNI je nešto čistiji u odnosu na C, jer je C++
objektno orjentisan jezik, poput Jave.
Ukoliko se radi o nizu koristi se notacija [ ispred potpisa tipa, npr. za niz cjelih brojeva, pišemo [I.
Tabela 1. Mapirani tipovi
Native tip Java Tip Opis “Signature”
tipa
Ovi tipovi takoĎe podrazumjevaju implicitnu konverziju meĎusobno ekvivalentnih Java/native tipova
npr. jint nije potrebno konvertovati u int da bi se koristio kao int. Ovo ne važi uvijek, npr. za
stringove, upotreba jstring na mjestu char * dovešće do pucanja JVM. Izuzetak od pravila
su i nizovi, gdje je potrebno koristiti posebne konstrukcije, kao što ce biti navedeno u primjeru
kasnije.
10 | S t r a n a
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
11 | S t r a n a
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
2
JIT-Just-in-ime compilation, metod za povećanje performansi pokrenutog programa, poznat i kao
dynamic translation.
12 | S t r a n a
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
3
RAD-Rapid Application Development
13 | S t r a n a
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
14 | S t r a n a
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
U primjeru se koriste dvije Java klase Bean i JniExample. JniExample učitava native biblioteku (
JniExampleLibrary.dll5) i otvara Java klasi metode koje su implementirane u dll-u. Bean se
koristi da se prikaže kako se razmjenjuju podaci putem JNI.
Prvo ćemo koristiti javah.exe da generišemo header fajl koji deklariše native metode u dll-u, kao
što smo definisali u JniExample.java. Komanda koju je potrebno pokrenuti je:
javap -s rs.edu.fit.se411.jni.JniExample
4
Native program-Napisan za hardver, ili za operativni sistem, na niskom nivou, kompajliranjem prevodi se u
mašinski kod.
5
Dll-Dynamic-link Library, je Microsoft implementacija za koncept djeljene biblioteke, u MS Windows
operativnim sistemima, i OS/2. Moguće ekstenzije su DLL, OCX-ActiveX kontrole, koje pamtimo još iz
vremena Visual Basic 6 i njihove registracije, i DRV (sistemski drajveri).
15 | S t r a n a
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
Za debug biblioteke, i Java programa istovremeno, u okviru Visual Studija treba poći na Debug,
potom Attach to Process, pronaći javaw.exe i odabrati Attach komandu.
Kao i kod bilo kod native koda, potrebno je obratiti posebnu pažnju na moguća curenja memorije
(jer nemamo Garbage Collector da to uradi za nas). Ipak, u slučaju JNI, JVM obavlja većinu
posla za nas. Bilo koja instanca proslijedjena ili vraćena od strane dll-a, biće počisćena od
strane JVM. Potrebno je da oslobodimo bafer, samo ako je alociran objekat van JVM.
Na kraju, prikazaćemo i kako da dovedemo do pucanja JVM, što će biti iznenaĎujuće lako. Ukoliko
imamo namjeru da u nasoj web aplikaciji koristimo i native kod, treba da budemo svjesni da
problem loše napisanog i nesigurnog koda u native biblioteci može oboriti čitav server. Zbog
toga bi bilo dobro da se native biblioteka pokreće na posebnom web serveru.
16 | S t r a n a
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
17 | S t r a n a
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
package rs.edu.fit.se411.jni;
//public members
public String dataString;
public byte[] dataByteArray;
public Bean() {}
@Override
public String toString(){
String ret = "string = " + dataString;
18 | S t r a n a
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
return ret;
}
}
package rs.edu.fit.se411.jni;
static {
System.loadLibrary("JniExampleLibrary");
}
// native methods
19 | S t r a n a
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
/**
* this method calls printSomething
*/
public native void callJavaMethod();
/**
* this method creates an instance of Bean and returns it
*/
public native Bean createAndReturnBean();
/**
* this method takes an instance of Bean as parameter and changes the
value of its members
*/
public native void modifyBean(Bean bean);
/**
* this method will the JVM when invoked
*/
public native void crashTheJvm();
20 | S t r a n a
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
bean.setDataString("hello");
6
Entry Point-polazna tačka aplikacije
21 | S t r a n a
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
U njoj ćemo pozivati public metode iz JniExample, redom, kao u listingu ispod.
package rs.edu.fit.se411.jni;
/**
* @param args
*/
public static void main(String[] args) {
System.out.println("Starting JavaMain...");
Za potrebe testiranja poziv runExample4 ce biti zakomentarisan, i testiran poziv dll-a sa prve tri
metode, pa potom testiran i sa odkomentarisanim pozivom ove metode, za test pucanja JVM.
22 | S t r a n a
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
U Source Files logičkom folderu dll projekta kreiraćemo cpp klasu JniExampleLibrary.
23 | S t r a n a
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
Pošto popunimo novi program podacima kao na slici, prvo idemo na Apply, pa Run. Ukoliko je sve
u redu, u folderu C++ projekta će se naći novi header fajl, rs_edu_fit_se411_jni_JniExample.h.
#ifndef _Included_rs_edu_fit_se411_jni_JniExample
#define _Included_rs_edu_fit_se411_jni_JniExample
#ifdef __cplusplus
extern "C" {
24 | S t r a n a
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
#endif
/*
* Class: rs_edu_fit_se411_jni_JniExample
* Method: callJavaMethod
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_rs_edu_fit_se411_jni_JniExample_callJavaMethod
(JNIEnv *, jobject);
/*
* Class: rs_edu_fit_se411_jni_JniExample
* Method: createAndReturnBean
* Signature: ()Lrs/edu/fit/se411/jni/Bean;
*/
JNIEXPORT jobject JNICALL Java_rs_edu_fit_se411_jni_JniExample_createAndReturnBean
(JNIEnv *, jobject);
/*
* Class: rs_edu_fit_se411_jni_JniExample
* Method: modifyBean
* Signature: (Lrs/edu/fit/se411/jni/Bean;)V
*/
JNIEXPORT void JNICALL Java_rs_edu_fit_se411_jni_JniExample_modifyBean
(JNIEnv *, jobject, jobject);
/*
* Class: rs_edu_fit_se411_jni_JniExample
* Method: crashTheJvm
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_rs_edu_fit_se411_jni_JniExample_crashTheJvm
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
25 | S t r a n a
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
Zbog toga označimo projekat u Visual Studiju, potom desni klik mišem na Properties, pa C/C++,
General u stablu, i na učitanoj stranici primjetimo prvi red Additional Include Directories. Idemo
na <Edit..>, i dodamo sledeće dvije putanje:
C:\Program Files\Java\jdk1.6.0_18\include
C:\Program Files\Java\jdk1.6.0_18\include\win32
26 | S t r a n a
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
Na sličan način kao što smo dodali javah, dodajmo i program javap.
Potom idemo na Apply i Run. Isti rezultat možemo dobiti i iz konzole (moramo voditi računa da je
postavljen JAVA_HOME, ili pokrenuti iz bin foldera JDK-a komandu).
27 | S t r a n a
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
Vidimo da su za void native metode siganture ()V, dok je za metodu koja vraća Bean taj potpis
drugačiji, tj. ()Lrs/edu/fit/se411/jni/Bean;
2.3.3.2. CallJavaMethod()
U ovoj metodi će se pozvati Java metoda printSomething (iz klase JniExample). Objasnićemo
red po red ovog listinga.
Metod JniEnv instance GetObjectClass nam vraća handler na klasu JniExample.GetMethodID
nam vraća handler na metod printSomething, čiji je signature ()V. Na kraju
CallVoidMethod rezultuje pozivanjem Java metoda klase JniExample, koje dobija ovaj metod
kao parametre.
env->CallVoidMethod(obj, mid);
}
env->CallVoidMethod(obj, mid);
}
2.3.3.3. CreatAndReturnBean()
Ovaj metod je zadužen za kreiranje i vraćanje Bean Java instance.
Prvo nalazimo klasu Bean. Za nju, potrebno je kreirati instancu, tj. pokrenuti konstruktor. U JNI, to
radimo preko <init>, odnosno sa GetMethodID(beanClass, "<init>", "()V") nalazimo
konstruktor, i u sledećoj liniji pozivamo sa NewObject.
28 | S t r a n a
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
Potom kreiramo UTF string, u JNI to radimo preko NewStringUTF. Sada je potrebno Bean instanci
setovati podatak član dataString preko settera setDataString, pa nalazimo handler na
setDataString, čiji je signature (Ljava/lang/String;)V.
Kako je seter void tipa, zovemo CallVodMethod i proslijeĎujemo string seteru. Povratna
vrijednost u JNI je jobject i to je instancirani Bean sa setovanim stringom.
return bean;
}
2.3.3.3. ModifyBean()
U ovom primjeru ćemo uzeti postojeći Bean, kao parametar, vec instanciran u okviru neke Java
klase, i u C++ kodu izmjeniti njegove podatke članove. U Java klasi ćemo za testiranje prije
izmjene, i poslije, koristi pomoćni metod toString, da bi smo vidjeli razliku u podacima prije i
poslije dejstva ove metode.
Prvo nalazimo klasu, za parametar tipa jobject. Potom nalazimo handler na setDataString,
kreiramo novi string, i pozivamo void metod sa stringom kao parametrom, slično prethodnom
primjeru.
Dalje ćemo izmjeniti još jedan podatak član, koji je JNI tipa jbyteArray, odnosno polje Bean-a
dataByteArray. Najprije deklarišemo newByteArray tipa jbyteArray, dimenzije pet bajtova,
pa instanciramo niz od pet jbyte-ova, a potom ovaj niz upisujemo u deklarisani newByteArray.
Nakon sto pronaĎemo handler za ovaj seter setDataByteArray, pozivamo ponovo void metod
za njega, sa newByteArray kao parametrom.
7
Bean je na ovaj nacin razmjenjen (shared ) izmedju Java programa i native dll-a.
7
Shared object-djeljenje objekta izmedju dva programa, jednog napisanog u Javi i drugog u C++.
29 | S t r a n a
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
2.3.3.4. CrashTheJVM()
CrashTheJVM metoda pokušava da kreira double niz, koji je veći od dimenzije steka, što će
dovesti do stack overflow-a. Ovo može da izazove velike probleme u produkciji, kao za primjer
web servera, i obori JVM.
Testiranjem Main metode JniExample Java projekta, dobijamo u konzoli Eclipse-a sledece,
odnosno potvrdu da je došlo do rušenja JVM, ukoliko poziv metod jniExample.runExample4()
nije pod komentarima kao što smo naveli ranije.
30 | S t r a n a
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
Starting JavaMain...
starting runExample1...
Thanks for watching this video
starting runExample2...
returned= string = this bean has been created in
Java_rs_edu_fit_se411_jni_JniExample_createAndReturnBean / byteArray =
starting runExample3...
before: string = hello / byteArray = 1 2 3
after: string = world / byteArray = 5 4 3 2 1
starting runExample4...
An unrecoverable stack overflow has occurred.
#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_STACK_OVERFLOW (0xc00000fd) at pc=0x0fb11d97, pid=5700, tid=4832
#
# JRE version: 6.0_18-b07
# Java VM: Java HotSpot(TM) Client VM (16.0-b13 mixed mode, sharing windows-x86
# Problematic frame:
# C [JniExampleLibrary.dll+0x11d97]
#
# An error report file with more information is saved as:
# E:\Dev\Java\workspace\SE411\JniExample\hs_err_pid5700.log
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#include "rs_edu_fit_se411_jni_JniExample.h"
#include <cstring>
31 | S t r a n a
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
env->CallVoidMethod(obj, mid);
}
return bean;
}
32 | S t r a n a
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
33 | S t r a n a
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
8
Visual Studio Solution-Termin za kontejner za jedan ili više projekata u Visual Studiju, koji predstavljaju
jednu logičku cjelinu.
34 | S t r a n a
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
odnosno, pozivaju se prva tri metoda iz dll-a, dok je četvrti nepozvan, koji treba da izazove pucanje
JVM-a, jer je zakomentarisan metod koji u svom tijelu poziva ovaj metod dll-a.
35 | S t r a n a
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
36 | S t r a n a
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
Sem breakpointa, potrebno je i povezati projekat sa procesom javaw.exe, kao na slici 12, preko
Debug->Attach To Process.. , odabrati javaw.exe iz liste i sa Attach potvrditi.
i obzirom da izazivamo pucanje JVM, Eclipse nas izbacuje, iz debug-a, kao na slici 14.
37 | S t r a n a
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
3.ZAKLJUČAK
Java okruženje i jezik je siguran i efikasan način za razvoj aplikacija. Pa ipak, ponekad je za
aplikaciju potrebna odreĎena funkcionalnost, koju Java, zbog svoje težnje da bude
multiplatfomska, nije moguće postići, ili bar ne upotrebom isključivo Java koda.
Zbog toga se kao logično rješenje nameće potreba za integracijom Jave i programa koji koriste
mogućnosti hardvera za koga su napisane, ili operativnog sistema. C/C++ je primjer takvog
jezika, koji se prevodi u mašinski kod.
Sledeći razlog integracije ova dva jezika je što želimo da komuniciramo sa već napisanim
softverom, kakav je moguće napisati i upotrebom Jave, ali ne želimo kod pisati iznova,
pogotovu ako se radi o velikim sistemima, jer bi to zahtjevalo velike resurse, ali i vrijeme koga
najčešće nemamo.
Zavisno od zahtjevane funkcionalnosti Java koda, pa i od izbora samog programera, ovu
integraciju je moguće postići na više načina, tj. upotrebom različitih API-ja, nekomercijalnih, i
komercijalnih. Ovakva integracija, uz niz prednosti, i obezbjeĎivanja funkcionalnosti, koje inače
ne bi bile moguće samo upotrebom Jave, donosi i niz problema. Jedan od njih je što loše
napisan C++ kod može dovesti do pucanja Java virtuelne masine, što je posebno opasno kod
izvršavanja ovakvog koda na web serverima.
Nijedan od predstavljenih načina integracije nije savršen, ali uz niz problema o kojima moramo
voditi računa (kao što je nepostojanje Garbage Collector-a u okviru C++, zbog čega moramo
eksplicitno uništavati objekte, ili gubitka na portabilnosti ovakvog koda) donosi i niz prednosti i
obezbjeĎuje funkcionalnosti koji upotrebom samo Jave i Javinih biblioteka ne bi bile moguće.
38 | S t r a n a
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
U ovom radu su predstavljeni različiti pristupi integraciji Java i C/C++ koda. Dat je kratak pregled
najčešće korišćenih API-ja, kao i preporuke koji odabrati u konkretnoj situaciji. Nijedan od njih
nije savršen, i ima svoje nedostatke, o kojima posebno treba voditi računa.
Situacija se na ovom polju, usavršavanjem Jave, odnosno JVM, stalno mijenja, i bajt kod po brzini
dostiže sličan napisan u jezicima koji se prevode u mašinski kod. Tako jedan od aspekata ove
integracije gubi na značaju.
Pisano je o načinu na koji funkcioniše JNI, mapiranjima izmedju C/C++ i Java tipova podataka, kao
i problemima koji nastaju upotrebom ovog API-ja. Dalje je moguće detaljnije pisati o:
održavanju Java reference JNIEnv u C/C++ kodu
primitivnom tipovima, nizovima, stringovima, i njihovoj upotrebi
kreiranju i uništavanju objekata
raspodjeli memorije
interfejsima
izuzecima
i drugim temama, vezanim za ovaj kompleksni, robustni API.
I drugi API-ji su predstavljeni na način da čitalac ima tek uvid o njima. Za njihovo bolje
razumjevanje, potrebno je detaljnije istražiti njihovu namjenu, polja primjene, probleme u
upotrebi. Kao polaznu tačku, čitalac može koristi literaturu korištenu u ovom radu.
39 | S t r a n a
[SE411-INTEGRATIVNO PROGRAMIRANJE U DVA PROGRAMSKA JEZIKA C++/JAVA]
December 16, 2010
5. LITERATURA
http://www.ensta.fr/~diam/java/online/io/javazine.html
http://www.javaworld.com/jw-12-2000/jw-1229-traps.html?page=1
http://stackoverflow.com/questions/782827/jni-vs-runtime-exec
http://gcc.gnu.org/onlinedocs/gcj/Basic-concepts.html#Basic-concepts
http://en.wikipedia.org/wiki/Java_Native_Interface
http://www.ibm.com/developerworks/java/library/j-jni/index.html
http://download.oracle.com/javase/1.4.2/docs/guide/jni/spec/jniTOC.html
http://www.drdobbs.com/184401335
http://gcc.gnu.org/java/papers/native++.html
http://codebazaar.blogspot.com/2010/08/package-codebazaar.html
http://download.oracle.com/javase/1.4.2/docs/guide/awt/1.3/AWT_Native_Interface.html
http://java.sun.com/javame/reference/docs/kni/html/02-Goals.html
http://en.wikipedia.org/wiki/GNU_Classpath
http://en.wikipedia.org/wiki/Compiled_Native_Interface
http://en.wikipedia.org/wiki/SWIG
http://www.swig.org/
http://www.swig.org/Doc1.3/Java.html
http://en.wikipedia.org/wiki/Java_Native_Access
http://stackoverflow.com/questions/3720563/access-c-shared-library-from-java-jni-jna-cni-or-swig
40 | S t r a n a