Fejlett Webes Technolgik II Bilicki Vilmos 2002 09
Fejlett Webes Technológiák II. Bilicki Vilmos 2002. 09. 30
A mai előadás tartalma: l CLDC • Célok, Követelmények • Architektúra, biztonság • Eltérés a J 2 SE-től • Eltérés a JVM-től • CLDC könyvtárak
Célok, Követelmények, Hatókör l Cél: • Szabványos, minimális erőforrás igényű Java • • • környezet Horizontális specifikáció Olyan alap létrehozása melyre vertikális specifikációk (profilok) épülhetnek Az alkalmazások biztonságos, dinamikus telepítése
Célok, Követelmények, Hatókör l Követelmények: • Hardver: • 128 k. B nem illékony memória • 32 k. B illékony memória (Java környezet, objektumemória) • 16 vagy 32 bites processzor • Szoftver: • Minimális operációs rendszer vagy kernel • Legalább egy időszelet a KVM számára (nincs megkötés a többszálúságra, …)
Célok, Követelmények, Hatókör l Hatókör: • Java nyelv és a VM lehetőségei • Alap Java osztályok (java. lang. *, java. util. *) • Input/Output • Hálózatkezelés • Biztonság • Nemzetközi alkalmazhatóság
Architektúra és Biztonság l l l KVM CLDC API Profilok, saját API-k
Architektúra és Biztonság l l KVM (Kilo Virtual Machine) • • • A lehető legkisebb még ”teljes” Java virtuális gép 40 – 80 k. B 16 – 32 bites CISC, RISC processzorok (jelenleg több mint 25 környezetben) Alkalmazás menedzsment: • • Gyakran nincs fájlrendszer (Letöltés, Betöltés) Rendelkezésre áll valamilyen tároló rendszer (általában C nyelven) • Alkalmazások listázása • Alkalmazás kiválasztása és futtatása • Alkalmazások törlése
Architektúra és Biztonság l Biztonság • • Alacsony szintű - virtuális gép biztonság • Java osztályfájl ellenőrző (illegális memória terület, Java objektum memórián kívüli írás) Alkalmazás szintű biztonság • J 2 SE A külső eszközök elérése security manager • Homokozó modell: • • • Java osztályfájlok ellenőrzése (alacsony szintű) Korlátozott számú Java API Alkalmazások letöltése, menedzselése gépközeli nyelven van megoldva Csak a VM API-k használhatóak (nincs natív kód hívás) Nem írhatóak felül a rendszer osztályok Egyszerre több alkalmazás is futtatható
Osztály fájl ellenőrzés l l Előellenőrzés (Off-device verification) • • Szerveren, fejlesztői gépen történik Olyan adatokat fűz hozzá (stack map) a bájtkódhoz melyeket a második lépcső gyorsan, hatékonyan felhasználhat (10%-al nagyobb kód) Futásidejű ellenőrzés (In-device verification) • Végignézi az utasításokat a stack map segítségével szigorú típus ellenőrzést végrehajtva
Osztály fájl formátum l Java Archive JAR formátum (30 -50% tömörítés) • Tartalmaznia kell a Stack-Map bejegyzéseket • Néhány Java bájtkódot nem tartalmazhat • Az osztályfájlokon kívül tartalmazhat • erőforrásokat is (png fájlok) (Class. get. Resource. As. Stream(String name)) Minden osztály definíció tartalmazza a saját szimbólumtábláját (metódus, kivételek, …)
Osztályfájl betöltés l l J 2 SE Classpath J 2 ME Implementáció függő Nem írhatóak felül az alaposztályok Az alkalmazás programozó nem szólhat bele a betöltési sorrendbe
Eltérés a Java specifikációtól l l l Nincs lebegőpont támogatás (a készülékek többségében nincs ilyen) Nincs finalize() metódus támogatás (nem írhatunk saját metódusokat melyeket a gc végrehajt mielőtt az objektumot megszüntetné) Nincsenek gyenge referenciák (gyenge referencia - az objektum akkor is törölhető ha nincs van rá hivatkozás) Nincs JNI A felhasználó nem definiálhat saját osztály betöltőket Hibakezelési szűkítések: • A készülékek viselkedése hiba esetén sokfajta lehet, ezért a hibaosztályok egy része nincs megvalósítva (Error – nincs visszatérés) Nincs Daemon thread, Thread group
CLDC osztályok l Célok: l Típusok: • Az alapvető könyvtárak megvalósítása • Kapcsolat lehetősége ! • java. * • javax. *
A J 2 SE-ből származó osztályok l l l l Rendszer osztályok (java. lang. *) Adattípus osztályok (java. lang. *) Gyűjtemény osztályok (java. util. *) Input/Output osztályok (java. io. *) Naptár, idő osztályok (java. util. *) Egyéb hasznos osztályok (java. util. *) Hibakezelő osztályok (java. lang. *)
Rendszer osztályok l Rendszer osztályok (alapvetőek a java nyelv számára): • • • java. lang. Object java. lang. Class java. lang. Runtime java. lang. System java. lang. Thread java. lang. Runnable (interfész) java. lang. String. Buffer java. lang. Throwable
Rendszer osztályok l java. lang. Object • • • ősosztály (ha egy osztálynak nincs őse akkor ez az osztály lesz az) minden osztály a tömböket is ideértve megvalósítják a metódusait fontosabb metódusai: • get. Class(Object obj) • notify() • notify. All() • wait(), wait(long timeout, int nanos)
Rendszer osztályok l java. lang. Thread (Szál) • • • Egyszerű szekvenciális parancssor a programon belül. Könnyűsúlyú folyamat: • • megosztva használja a kód és az adat szekciót csökken a ”context-switch” végrehajtási idő Segítségével egyszerre több feladatot végezhetünk: • • képernyő frissítés hálózat kezelés …
Thread osztály l l a Thread osztály egy általános szálat valósít meg mely nem csinál semmit a run metódus üres a run metódus felülírásával tudunk feladatot specifikálni két módon tudunk szálat megvalósító osztályt definiálni: • • a Thread osztályból származtatva és felülírva a run metódust megvalósítva a Runnable interfészt
A run metódus felülírása public class Simple. Thread extends Thread { public Simple. Thread(String str) { super(str); } public void run() { for (int i = 0; i < 10; i++) { System. out. println(i + " " + get. Name()); try { sleep((long)(Math. random() * 1000)); } catch (Interrupted. Exception e) {} } System. out. println("DONE! " + get. Name()); } }
Futtatás public class Two. Threads. Demo { public static void main (String[] args) { new Simple. Thread("Jamaica"). start(); new Simple. Thread("Fiji"). start(); } } 0 0 1 1 2 2 3 3 4 4 5 Jamaica Fiji Jamaica Fiji 6 Fiji 7 Fiji 5 Jamaica 8 Fiji 6 Jamaica 9 Fiji 7 Jamaica DONE! Fiji 8 Jamaica 9 Jamaica DONE! Jamaica
A Runnable interfész megvalósítása public class Simple. Thread implements Runnable { Thread Simple. Thread; public Simple. Thread(String str) { Simple. Thread = new Thread(this, str); } public void start() {Simple. Thread. start(); } public void run() { for (int i = 0; i < 10; i++) { System. out. println(i + " " + my. Thread. get. Name()); try { my. Thread. sleep((long)(Math. random() * 1000)); } catch (Interrupted. Exception e) {} } System. out. println("DONE! " + my. Thread. get. Name()); }}
Mikor melyik módot válasszuk ? l l Amennyiben osztályunknak származnia kell valahonnan akkor az interfész a megoldás (MIDlet esetén) Egyébként tetszőleges
A szál életciklusa sleep új done sleeping suspend blokkolt resume start futtatható wait notify halott run metódus kilép stop
Állapotok I. l l új szál • • amikor a new operátorral létrehozzuk még nem fut ekkor a new állapotban van • a megfelelő erőforrások lefoglalását, a szál adminisztrálását, a szál futását a start metódus segítségével tudjuk elindítani a new állapotból. ebben az állapotban a szál nem feltétlenül fog futni. Az operációs rendszer feladata a megfelelő futási idő biztosítása számára. a szálak közötti váltás operációs rendszer függő (pl. : solaris esetén green threads, windows esetén mindegyik szálnak egy időszelet) runnable • •
Állapotok II. l blokkolt szálak a következő módokon kerülhetnek ebbe az állapotba: • • • l a sleep() metódus eredményeként (ekkor adott ideig lesz itt) egy olyan művelet végrehajtása esetén mely input/output műveletekkel blokkolt és addig nem tér vissza míg ezek be nem fejeződtek a wait() metódus meghívására (másik szálnak meg kell hívnia a notify vagy notify. All metódust) amikor olyan objektumhoz próbál hozzáférni amely zárolt a suspend() metódus meghívására (ez már elavult) a resmue() metódussal lehet visszahozni. futtatható állapotba csak úgy kerülhetnek vissza ha a blokkolást előidéző eseménynek megfelelő esemény következik be
Állapotok III. l halott szálak • a run metódus kilép • hirtelen meghal mert egy kezeletlen kivétel • • miatt megszűnik a run metódus a stop metódus elavult ezért ne használjuk az is. Alive metódus segítségével nézhetjük meg, hogy él-e még.
A run metódus kezelése I. l a feladat befejezése után kilép: public void run() { for (int i = 0; i < 10; i++) { System. out. println(i + " " + get. Name()); try { sleep((long)(Math. random() * 1000)); } catch (Interrupted. Exception e) {} } System. out. println("DONE! " + get. Name()); } }
A run metódus kezelése II. Figyeli, hogy ki kell-e lépnie: public void run() { Thread my. Thread = Thread. current. Thread(); while (clock. Thread == my. Thread) { repaint(); try { Thread. sleep(1000); } catch (Interrupted. Exception e){} } } public void stop() { clock. Thread = null; } l
Prioritás l l a szálak versenyeznek a CPU használatáért nagyobb prioritású szálak előnyben vannak a kisebb prioritású szálakkal szemben a kisebb prioritású szálak csak akkor jutnak CPU időhöz, ha a nagyobb prioritású szálak már nem tartanak igényt a CPU-ra az egyenlő prioritású szálak kezelése operációs rendszer függő • • l win 9 x, Win. NT… az egyenlő prioritású szálak felváltva kapnak CPU időt (időosztás) solaris az egyenlő prioritású szálak csak között csak a feladat befejezése után történik váltás (probléma az önző szálak kezelése) a set. Priority() metódussal lehet beállítani egy szál prioritását (MAX_PRIOROTY=10, MIN_PRIORITY=1)
public class Simple. Thread implements Runnable { Thread Simple. Thread; public Simple. Thread(String str) { Simple. Thread = new Thread(this, str); } public void start() { Simple. Thread. start(); } public void set. Priority(int i) { Simple. Thread. set. Priority(i); } public void run() { Thread my. Thread = Thread. current. Thread(); for (int i = 0; i < 10; i++) { for (int c = 0; c < 1000000; c++); System. out. println(i + " " + Simple. Thread. get. Name()); } System. out. println("DONE! " + Simple. Thread. get. Name()); } } Példa:
Egyforma prioritás public class Three. Threads. Test { public static void main (String[] args) { Simple. Thread t; Simple. Thread t 1; t = new Simple. Thread("Jamaica"); t. set. Priority(1); t 1 = new Simple. Thread("Kolumbia"); t 1. set. Priority(1); t 1. start(); t. start(); } } 0 Kolumbia 1 Kolumbia 2 Kolumbia 0 Jamaica 1 Jamaica 2 Jamaica 3 Jamaica 4 Jamaica 3 Kolumbia 4 Kolumbia 5 Kolumbia 6 Kolumbia 5 Jamaica 6 Jamaica 7 Jamaica 8 Jamaica 9 Jamaica 7 Kolumbia 8 Kolumbia 9 Kolumbia DONE! Jamaica
Különböző prioritás public class Three. Threads. Test { public static void main (String[] args) { Simple. Thread t; Simple. Thread t 1; t = new Simple. Thread("Jamaica"); t. set. Priority(10); t 1 = new Simple. Thread("Kolumbia"); t 1. set. Priority(1); t 1. start(); t. start(); } } 0 Jamaica 1 Jamaica 2 Jamaica 3 Jamaica 4 Jamaica 5 Jamaica 6 Jamaica 7 Jamaica 8 Jamaica 9 Jamaica DONE! Jamaica 0 Kolumbia 1 Kolumbia 2 Kolumbia 3 Kolumbia 4 Kolumbia 5 Kolumbia 6 Kolumbia 7 Kolumbia 8 Kolumbia 9 Kolumbia DONE! Kolumbia
Megjegyzés l l l olyan szálakat kell írnunk melyek nem önzőek az operációs rendszerek különbözőek, ha platform független programot akarunk írni akkor nekünk kell gondoskodnunk a megfelelő időosztásról a yield() metódus segítségével tudjuk egy szál futását felfüggeszteni és a CPU-t átadni egy legalább ilyen prioritású szálnak nem minden operációs rendszer rendelkezik 10 prioritási szinttel (pl winnt 7) a szálak prioritásukat a létrehozó száltól öröklik
Szálak szinkronizálása l l Egyes feladatokat nem lehet megoldani egymástól független szálakkal (pl. : közös erőforrás használata módosítása) Hibás működéshez vezethet amennyiben nem gondoskodunk zárolásról a közös erőforrás használatakor pl. : két vagy több szál bankbetétek között végez tranzakciókat. A művelet bármikor megszakadhat (windows) és nem konzekvens állapot maradhat, amit egy másik szál felhasználhat. a problémát az adatmódosító metódus megszakíthatósága okozza
Zárolás l l l synchronized a zárolt objektumhoz csak egy szál férhet hozzá ha egy szál használ egy zárolt objektumot és meghív egy másik szálat akkor a másik szál hozzáférhet az objektumhoz minden objektumnak van egy zárolás számlálója egy szál egyszerre több objektumot is zárolhat a szál ütemező periodikusan aktiválja a szálakat, azok melyek egy zárolt objektumra várakoznak a következő soron kívüli futási jogot kapnak.
wait, notify. All l előfordulhat olyan eset amikor egy szál a másik akciójára vár ilyenkor mivel a közös objektumot zárolt függvényeken keresztül lehet elérni ez végtelen ciklushoz vezetne wait – ha egy szál meghívja a wait() metódust akkor az objektum felszabadul és a szál blokkolva lesz amíg az adott objektumnál egy másik szál meg nem a hívja a notify, notify. All metódust érdemes a notify. All metódust használni mivel a másik a blokkolt szálak közül csak egyet szabadít fel azt is véltelenszerűen
Példa: l l Tároló objektum: Tarolo Adat forrás: Producer Adat nyelő: Consumer main: PTest
public class Tarolo { private int contents; private boolean available = false; public synchronized int get() { while (available == false) { try { wait(); } catch (Interrupted. Exception e) { } } System. out. println("Olvasgatok"); available = false; notify. All(); return contents; } public synchronized void put(int value) { while (available == true) { try { wait(); } catch (Interrupted. Exception e) { } } System. out. println("Irogatok"); contents = value; available = true; notify. All(); } } Tarolo. java
public class Producer extends Thread { private Tarolo tarolo; private int number; public Producer(Tarolo c, int number) { tarolo = c; this. number = number; } public void run() { for (int i = 0; i < 10; i++) { tarolo. put(i); System. out. println("Producer #" + this. number + " beirtam: " + i); try { sleep((int)(Math. random() * 100)); } catch (Interrupted. Exception e) { } }
public class Consumer extends Thread { private Tarolo tarolo; private int number; public Consumer(Tarolo c, int number) { tarolo = c; this. number = number; } public void run() { int value = 0; for (int i = 0; i < 10; i++) { value = tarolo. get(); System. out. println("Consumer #" + this. number + " kiolvastam: " + value); } } }
Main public class PTest { public static void main(String[] args) { Tarolo c = new Tarolo(); Producer p 1 = new Producer(c, 1); Consumer c 1 = new Consumer(c, 1); c 1. start(); p 1. start(); } }
Eredmény H: >java PTest Irogatok Olvasgatok Consumer #1 kiolvastam: 0 Producer #1 beirtam: 0 …. Irogatok Olvasgatok Producer #1 beirtam: 8 Consumer #1 kiolvastam: 8 Irogatok Producer #1 beirtam: 9 Olvasgatok Consumer #1 kiolvastam: 9
Újrafoglalás public class Reentrant { public synchronized void a() { b(); System. out. println("here I am, in a()"); } public synchronized void b() { System. out. println("here I am, in b()"); } }
String. Buffer l l Segítségével karakterlácokat tudunk manipulálni Használata: • String x = new String. Buffer(). append("a"). append(4). append("c"). to. String()
Throwable l l Minden hiba osztály őse Használata: try { int a[] = new int[2]; a[4]; } catch (Array. Index. Out. Of. Bounds. Exception e) { System. out. println("exception: " + e. get. Message()); e. print. Stack. Trace(); }
Adat típus osztályok l Adat típus osztályok: • java. lang. Boolean • java. lang. Byte • java. lang. Short • java. lang. Integer • java. lang. Short • java. lang. Character
Gyűjtemény osztályok l Gyűjtemény osztályok • java. util. Vector • java. util. Stack • java. util. Hashtable • java. util. Enumeration
Vector l l Olyan tömböt valósít meg amely objektumokat tartalmazhat és növelhető a kapacitása Használata: Vector vector. Name = new Vector(); Vector vector. Name = new Vector(5); int vector. Size = vector. Name. size(); int object. First. Found. At = vector. Name. index. Of(object. To. Search. For); Object object. Name = vector. Name. element. At(int. To. Get. Element. At); vector. Name. add(object. To. Add); vector. Name. remove(int. Offset. To. Remove. Element);
Stack l l l A Vector osztályból származik Last in First Out (LIFO) Hasznos metódusai: • Object pop() • Object push(Object item) • Object peek()
Hashtable l l l Egy olyan táblát definiál melyben kulcsok alapján kereshetünk Olyan objektumokat tárolhatunk melyek megvalósítják a hash. Code metódust Használata: Hashtable numbers = new Hashtable(); numbers. put("one", new Integer(1)); numbers. put("two", new Integer(2)); numbers. put("three", new Integer(3)); Integer n = (Integer)numbers. get("two"); if (n != null) { System. out. println("two = " + n); }
Enumeration (interfész) l l Egy interfészt specifikál Segítségével elemek listáján mehetünk végig Metódusai: • • boolean has. More. Elements() Object next. Element() Használata: for (Enumeration e = v. elements() ; e. has. More. Elements() ; ) { System. out. println(e. next. Element()); }
Input/Output osztályok l Input/Output osztályok: • • • java. io. Reader java. io. Writer java. io. Input. Stream java. io. Output. Stream java. io. Byte. Array. Input. Stream java. io. Byte. Array. Output. Stream java. io. Data. Input. Stream java. io. Input. Stream. Writer java. io. Input. Stream. Reader java. io. Print. Stream
Naptár és idő osztályok l Naptár és idő osztályok: • java. util. Calendar • java. util. Date • java. util. Timezone
Egyéb hasznos osztályok l Egyéb hasznos osztályok: • java. util. Random • java. util. Math
Kivételkezelő osztályok I. l Kivételkezelő osztályok: • • • • java. lang. Exception java. lang. Class. Not. Found. Exception java. lang. Illegal. Access. Exception java. lang. Instantiation. Exception java. lang. Interrupted. Exception java. lang. Runtime. Exception java. lang. Arithmetic. Exception java. lang. Array. Store. Exception java. lang. Class. Cast. Exception java. lang. Illegal. Argument. Exception java. lang. Illegal. Thread. State. Exception java. lang. Number. Format. Exception java. lang. Illegal. Monitor. State. Exception
Kivételkezelő osztályok II. l Kivételkezelő osztályok: • • • • java. lang. Index. Out. Of. Bounds. Exception java. lang. Array. Index. Out. Of. Bounds. Exception java. lang. String. Index. Out. Of. Bounds. Exception java. lang. Negative. Array. Size. Exception java. lang. Null. Pointer. Exception java. lang. Security. Exception java. util. Empty. Stack. Exception java. util. No. Such. Element. Exception java. io. EOFException java. io. IOException java. io. Interrupted. IOException java. io. Unsupported. Encoding. Exception java. io. UTFData. Format. Exception
CLDC specifikus osztályok l l l javax. microedition. io. * Generic Connection framework • • • Egységes módszer i/o Hálózat támogatás Java. net. * (20 osztály) nem használható Blue. Tooth, infravörös, … Általános forma: • Connector. open(<protokoll><cím>)
Definiált interfészek
Interfészek l l l l Connection (csak kinyitni és becsukni lehet, az open() statikus) • Public void close() • • public Input. Stream open. Input. Stream() public Data. Input. Stream open. Data. Input. Stream() • • public Output. Stream open. Output. Stream() public Data. Output. Stream open. Data. Output. Stream() • • • public String get. Type(); public String get. Encoding(); public long get. Length(); Input. Connection – adat olvasható ki Output. Connection – adat írható Stream. Connection – az előző két interfész kombinációja Content. Connection – a HTTP kapcsolat néhány alapvető paraméteréhez ad hozzáférést Stream. Connection. Notifier Datagram. Connection
try { conn = open. Connection(); update. Progress(); out = open. Data. Output. Stream(conn); out. write. Int(Message. Constants. LOGIN_USER); out. write. UTF(c. get. Username()); out. write. UTF(c. get. Password()); out. close(); update. Progress(); in = open. Data. Input. Stream(conn); update. Progress(); Példa } catch (IOException ioe) { throw new Application. Exception(Error. Constants. CANNOT_CONNECT); } finally { close. All(conn, out, in); }
Connector, Http. Connection open. Connection() throws IOException { Http. Connection result; result = (Http. Connection) Connector. open(servlet. Url); result. set. Request. Property("User-Agent", System. get. Property("microedition. profil es")); result. set. Request. Property("Content-Type", "application/binary"); result. set. Request. Method(Http. Connection. POST); return result; }
Data. Output. Stream open. Data. Output. Stream(Http. Connection conn) throws Application. Exception { try { return conn. open. Data. Output. Stream(); } catch (IOException ioe) { throw new Application. Exception(Error. Constants. CANNOT_CONNE CT); } }
Forrás l SUN: Connected, Limited Device Configuration (http: //java. sun. com/j 2 me/docs/)
- Slides: 63