Java Development Kit 1.1

Proiectarea și scrierea de programe s-a mutat de mult din zona de cercetare în zona industrială. Iar atunci când vorbim despre industrie, vorbim despre componente prefabricate care trebuiesc asamblate împreună. Așa se face că, la succesul unui mediu de programare, cel mai mult contează aceste două lucruri: componentele prefabricate conținute în bibliotecile sau colecțiile de clase ale mediului și componentele care există pe piață și sunt compatibile cu mediul. Structurile sintactice ale limbajului de programare care însoțește respectivul mediu de programare rămân doar o bază, mai mult sau mai puțin flexibilă, cu ajutorul căreia se poate clădi funcționalitatea.

La apariția limbajului Java toată lumea a fost entuziasmată de noul limbaj, de portabilitatea și de securitatea pe care acesta le oferă. Plus un set de clase care sunt într-adevăr portabile între platformele pe care rulează Java. Nu e puțin lucru și totuși: timpul a trecut și o dată cu el entuziasmul a lăsat locul aplicațiilor concrete. Și odată cu scrierea acestor aplicații au apărut și primele probleme: ierarhia standard de clase Java avea o mulțime de lipsuri. Nu existau posibilități de arhivare sau internaționalizare, nu exista suport pentru serializarea obiectelor, nu exista suport pentru accesul la baze de date sau suport pentru crearea de componente software indispensabilă mediilor de dezvoltare interactive și vizuale după standardele moderne. Ba chiar s-au auzit voci care au criticat clasele care construiau suportul pentru construcția de interfețe grafice utilizator acestea nefiind nici destul de puternice și nici destul de flexibile.

În aceste condiții, unii dezvoltatori s-au simțit înșelați și s-au întors la vechile iubiri în timp ce alții au încercat să umple aceste goluri dezvoltând noi pachete de clase care să le satisfacă cerințele. Din păcate aceste pachete de clase, negăsindu-se standard în distribuția Java, trebuiau descărcate din rețea sau instalate folosind căile clasice de distribuție software.

Dar problema nu a fost foarte gravă atâta timp cât toți dezvoltatorii au respectat regulile jocului, și anume să scrie clasele de așa natură încât ele să fie disponibile pe orice platformă pe care rulează mașina virtuală Java. Problema s-a agravat atunci când au apărut implementării ale mașinii virtuale Java și clase care erau dependente de mașina pe care rulau și imposibil de portat pe alte mașini. Dintre acestea face parte mașina virtuală Java distribută de Microsoft, care oferă suport COM/DCOM disponibil doar pe mașinile care rulează sub sisteme de operare Microsoft (dar nu DOS). Desigur, pentru Microsoft tentația a fost prea mare atâta timp cât nu a existat un standard pentru dezvoltarea de componente software: suportul COM a permis introducerea în ecuație a controalelor ActiveX, noile jucării promovate de Microsoft.

Datorită acestor ultime evoluții, însuși conceptul care stă la baza limbajului și mediului de execuție Java a fost pus în pericol, lumea dezvoltatorilor fiind din nou pusă în situația de a alege între Microsoft și restul lumii. Ca răspuns la această situație, JavaSoft a luat două măsuri mai importante: Prima dintre ele este lansarea inițiativei "100% pure Java" care certifică aplicațiile care sunt 100% compatibile cu standardele Java și pot rula pe orice mașină virtuală Java standard. Această primă măsură, deși interesantă și susținută de foarte multe dintre firmele interesate în dezvoltarea aplicațiilor Java, nu poate avea efect fără cea de-a doua măsură: urgentarea terminării specificațiilor și implementării specificațiilor pentru componentele care lipsesc din pachetele de clase Java. Cea de-a doua măsură s-a concretizat la mijlocul lui februarie 1997 prin apariția JDK 1.1, după mai bine de 3 luni de stagiu beta.

Desi nu poartă numele de JDK 2.0, noul JDK nu este doar o actualizare cosmetică a vechiului produs ci este un pas semnificativ în direcția impunerii mediului Java ca un mediu puternic, capabil să suporte cerințele unor aplicații diverse și complexe. Am putea spune că, odată cu apariția JDK 1.1, Java a ajuns în sfârșit la maturitate.

Componente noi în JDK 1.1

JDK 1.1 aduce o mulțime de pachete și clase noi care completează fucționalitatea în multe dintre ariile de interes pentru dezvoltatorii Java. Să vedem pe scurt care sunt acestea.

Internaționalizare

Suportul pentru internaționalizare permite dezvoltarea de apleturi Java localizabile în diverse limbi. Cu alte cuvinte, putem scrie cod independent de limba care va fi folosită la rularea programului și să lăsăm apoi mediul de execuție să hotărască pentru noi, în funcție de limba curentă, care este formatul în care trebuie afișate numerele, data, care este mesajul corect pentru o anumită limbă și așa mai departe.

Suportul de internaționalizare din JDK 1.1 oferă următoarele facilități: se pot afișa caractere Unicode oarecare, ceea ce permite scrierea corectă a mesajelor în orice limbă, există un mecanism de setare a limbii curente, un mecanism de localizare a mesajelor pe care le afișează aplicația, un mod de afișare a datei, ore și numerelor senzitiv la limba curentă, servicii pentru sortarea șirulilor de caractere în funcție de alfabetul limbii curente, convertoare de seturi de caractere, suport pentru formatarea parametrizată a mesajelor (plecând de la niște șabloane și înlocuind în acestea parametrii potriviți) și suport pentru separarea cuvintelor și propozițiilor într-un enunț în funcție de limbă.

Suportul pentru arhive Java (JAR)

JAR este un format de fișier arhivă independent de platformă, fișier în interiorul căruia se pot stoca mai multe fișiere diferite. Principala idee este legarea împreună, în același fișier-arhivă, a tuturor componentelor necesare pentru execuția unui aplet Java (sau eventual mai multor apleturi) și descărcarea acestora din rețea printr-o singură tranzacție HTTP. În acest fel, se minimizează timpul de creare a conexiunilor Internet necesare descărcării tuturor componentelor unui aplet. În plus, formatul JAR suportă comprimarea fișierelor din interiorul arhivei ceea ce reduce și mai mult timpul de descărcare prin reducerea dimensiunii totale a arhivei. În fine, formatul JAR suportă semnarea componentelor individuale din interiorul unei arhive, făcând astfel posibilă autentificarea originii componentelor. Appletviewer-ul care vine cu JDK 1.1 permite apleturilor semnate digital să ruleze pe sistemul gazdă cu drepturi identice cu cele ale unei aplicații Java. Cu alte cuvinte, apleturile semnate au dreptul să acceseze sistemul de fișiere local, să inițieze conexiuni TCP cu alte sisteme decât cel de pe care au fost descărcate, etc. JavaSoft promite pe viitor un control mai precis asupra permisiunilor pe care le are un aplet semnat digital.

Formatul JAR este implementat integral în Java, fiind astfel foarte ușor extensibil.

Suport pentru securitate și semnarea apleturilor

Noul API pentru securizarea apleturilor include suport pentru ca dezvoltatorii să-și poată securiza apleturile pe mai multe nivele. API-ul, deși specificat complet, este doar parțial implementat în JDK 1.1. Printre facilitățile implementate se numără semnăturile digitale, clasificarea mesajelor, managementul cheilor și listele de control la acces.

Suportul pentru semnături digitale folosește algoritmi de tip DSA și este util pentru generarea de perechi de chei publice și chei private precum și semnarea și autentificarea datelor. Clasificarea mesajelor, cu algoritmi de tip MD5 și SHA-1 este utilă pentru crearea unor amprente digitale ale datelor care pot fi folosite în semnături digitale și în indexarea și identificarea rapidă a datelor. De exemplu, Marimba Castanet folosește o semnătură generată cu algoritmul MD5 pentru a identifica fișierele care s-au modificat în interiorul unui canal Castanet. Managementul cheilor este o abstracție care permite controlul unor entități precum utilizatorii și grupurile de utilizatori, cheile și certificatele acestora. Această facilitate permite aplicațiilor să implementeze propriul sistem de management al cheilor și să interopereze cu alte sistem de acest tip. Implementarea unor formate de certificate specifice precum X.509 v3 este amânată pentru o versiune viitoare a JDK. Listele de control la acces sunt utile pentru a specifica drepturile de acces pentru enități ca utilizatorii sau grupurile de utilizatori. JDK 1.1 nu folosește intern această facilitate și JavaSoft anunță că acest API va suporta modificări ulterioare.

Extensii ale Abstract Window Toolkit (AWT)

După cum aminteam mai sus, AWT 1.0x a fost țintă a repetate atacuri din partea celor care au încercat să dezvolte interfețe utilizator elaborate în Java. Poate tocmai de aceea au apărut deja diverse pachete care rescriu sau completează AWT, cel mai cunoscut fiind, desigur Internet Foundation Classes (IFC) dezvoltat de Netscape. Un alt toolkit, secondat și de un utilitar de editare rapidă a interfețelor este Bongo de la Marimba. În fine, anunțat, dar încă nelansat pe piață, este toolkit-ul Microsoft AFC (Java Foundation Classes). AFC va fi lansat împreună cu Internet Explorer 4.0.

Ca urmare a acestor critici și pachete alternative de clase, JavaSoft a rescris AWT obținând în același timp funcționalitate și performață superioară. Noua implementare a AWT are o arhitectură modificată pentru a permite dezvoltări ulterioare importante, are API-uri pentru imprimare (estențiale pentru aplicațiile comerciale), un sistem mult mai bun de derulare a conținutului ferestrelor și mult mai ușor de utilizat, meniuri popup, suport de tip clipboard care oferă facilități de cut&paste, specificarea formei cursorului pentru fiecare componentă a interfeței în parte, un model de evenimente modificat bazat de delegare, extensii în zona de afișare și prelucrare a imaginilor și, desigur, un suport superior pentru specificarea fonturilor, absolut necesar API-ului de internaționalizare. În ceea ce privește implementarea AWT pentru Win32, aceasta a fost integral rescrisă pentru a mări performanța și pentru a obține consistență deplină cu celelalte platforme pe care a fost portat JDK.

Extensii în clasele de rețea

S-a introdus suport pentru o parte dintre opțiunile de lucru cu sockets din BSD în pachetul de clase java.net, și anume TCP_NODELAY, SO_LINGER, SO_TIMEOUT și IP_MULTICAST_IF. Au ramas in continuare de implementat SO_KEEPALIVE, MSG_OOB, SO_OOBINLINE (date out-of-band) și RAW/ICMP SOCKETS. Alte extensii includ transformarea claselor Socket și ServerSocket din clase finale în clase extensibile, adăugarea de noi clase derivate din SocketException pentru a mări finețea mesajelor semnalate de mecanismul de excepții și mutarea clasei MulticastSocket din pachetul sun.net în pachetul java.net, clasa devenind astfel standard. Desigur, alte extensii se referă la îmbunătățirea performaței și la eliminarea bug-urilor din vechea versiune.

Extensii în clasele de intrare/ieșire

Pachetul de intrare/ieșire a fost puternic extins prin apariția unor clase destinate lucrului cu stream-uri de caractere. Acest nou tip de stream-uri este similar cu cel de octeți dar lucrează cu caractere Unicode de 16 biți. Această extensie a fost absolut necesară pentru a se putea cu șiruri oarecare de caractere și pentru a se oferi suport de internaționalizare. Aproape toată funcționalitatea specifică stream-urilor de octeți este disponibilă și pentru cele de caractere. Cele două clase principale care implementează stream-urile de caractere sunt clasa java.io.Reader și clasa java.io.Writer.

Extensii ale pachetului matematic

Sau introdus două noi clase, BigInteger și BigDecimal. În cazul BigInteger, această clasă reprezintă întregi de precizie arbitrară, similari cu celelalte tipuri întregi din Java. În plus, pachetul java.lang.math are acum suport pentru calculul celui mai mare divizor dintre două numere, verificarea faptului că un număr este prim sau nu, generarea numerelor prime și manipularea numerelor întregi la nivel de bit. Clasa BigDecimal este destinată numerelor zecimale cu semn de precizie arbitrară, utilă operațiilor care implică sume de bani.

Apelul metodelor la distanță (RMI)

Aplicațiile distribuite sunt o realitate în zilele noastre, așa că suportul pentru apelul metodelor la distanță este esențial pentru un mediu care vrea să se impună. RMI permite crearea unor aplicații Java în care metodele obiectelor dintr-o mașină virtuală Java pot fi apelate din altă mașină virtuală Java, care eventual poate rula pe un al calculator. Pentru a apela o metodă a unui obiect depărtat este suficient să se poată obține o referință către acel obiect. Această referință se poate obține căutând în registry-ul mașinii pe care rulează obiectul sau se poate primi referința ca parametru sau ca valoare de retur dintr-o metodă. Obiectele pot apela obiectele de pe un server în timp ce serverul poate acționa și el ca un client al altor servere de obiecte. Registry-ul este o aplicație de tip server care permite înregistrarea obiectelor cu un nume extern, ușor de identificat. Aplicațiile pot face apel la facilitățile clasei java.rmi.Naming pentru a obține o referință către un obiect dacă cunosc serverul pe care a fost înregistrat obiectul și numele sub care a fost acesta înregistrat.

Pentru a putea transmite parametrii și valorile de retur, RMI utilizează API-ul de serializare a obiectelor.

Serializarea obiectelor

Serializarea obiectelor este o interfață de programare care exinde clasele de intrare/ieșire cu posibilitatea de a transfera obiecte. Serializarea permite deci transformarea obiectelor într-un șir de octeți. Dacă din interiorul unui obiect sunt referite alte obiecte, atunci acestea sunt serializate împreună cu obiectul care le referă. Șirul de octeți obținut este în așa fel generat încât se pot construi oricând din el înapoi obiectele inițiale și legăturile dintre ele.

Serializarea este utilizată pentru o persistență simplificată și pentru transmiterea obiectelor în rețea și ca parametrii sau valoare de retur pentru RMI.

Pentru fiecare tip de obiecte există o serializare standard, operată automat de către sistem, dar dezvoltatorul este liber să-și dezvolte și propria implementare a serializării. Implementarea implicită protejează membrii privați ai obiectelor și nu transmite variabilele care au fost declarate tranziente. În cazul în care un obiect este referit de mai multe ori, el este serializat o singură dată în prima poziție în care apare, iar în următoarele poziții se memorează doar o trimitere către forma serializată a obiectului. Dacă dezvoltatorul a ales să-și implementeze propria serializare, atunci formatul este dependent doar de dezvoltator. Clasele de obiecte care pot fi serializate trebuie să implementeze interfața nou introdusă java.io.Serializable.

API-ul de reflexie

API-urile de serializare precum și JavaBeans cer să existe o posibilitate de a investiga membrii unei clase (constructori, metode, variabile) în momentul execuției. Desigur, aceste operații trebuie să se găsească sub restricții de securitate severe pentru a împiedica deconspirarea informațiilor private din interiorul claselor și instanțelor acestora. În cazul unui aplet nevalidat, accesul se poate face doar la membrii publici în timp ce un aplet validat și clasele sistem au drepturi sporite.

API-ul permite investigarea pornind de la o declarație de clasă sau de la o instanță pe baza clasei acesteia din momentul execuției. În plus, API-ul de reflexie poate fi utilizat și pentru a modifica membrii unei clase și pentru a accesa și eventual modifica tablouri de elemente.

API-ul definește trei noi clase în pachetul java.lang.reflect pentru accesul membrilor unei clase numite Constructor, Method și Field plus o a patra clasă utilizată pentru accesarea tablourilor numită Array. În plus, API-ul adaugă funcționalitate la clasa java.lang.Class.

JavaBeans

Componentele software reprezintă una dintre cele mai interesante descoperiri din ultimul timp în materia de tehnologie de dezvoltare a aplicațiilor. După această metodologie, se pot dezvolta componente prefabricate din care programatorii pot dezvolta produse complete doar punându-le una lângă cealaltă și făcâdu-le să comunice între ele. Programarea cu componente software tinde să se asemene cu un joc Lego care ne permite construcția unor modele complet diferite pornind de la aceleași componente. Numai că aceste componente nu mai sunt de mult privite ca un joc. Există pe piață la ora actuală firme care trăiesc (foarte bine) numai din construcția și vânzarea de componente software.

Pentru a dezvolta componente software este nevoie de specificații care să fie respectate atât de cei care produc componentele precum și de cei care utilizezază componentele în mod direct sau prin intermediul unui mediul de dezvoltare vizuală. Istoria componentelor software nu este mai lungă de patru cinci ani și include specificații precum VBX, OCX, ActiveX de la Microsoft, CORBA/IIOP, OpenDoc/Live Objects și, mai nou, JavaBeans în cadrul JDK 1.1.

JavaBeans este deci o specificație de construcție a componentelor software, împreună cu un set de clase care să faciliteze inspectarea și punerea în execuție a acestor componente. Împreună cu Beans Development Kit, inclus și în JDK 1.1, JavaSoft s-a grăbit să lanseze și JavaBeans-ActiveX bridge un produs care permite rularea unui componente JavaBeans în orice context în care se poate folosi o componentă ActiveX.

JavaBeans este o specificație complexă despre care vom avea cu siguranță ocazia să mai vorbim. Până atunci, să spunem doar că JavaBeans a fost foarte rapid adoptat de majoritatea mediilor de dezvoltare vizuală care există pe piață, începând desigur cu Symantec Visual Café și terminând cu viitorul JBuilder anunțat de Borland.

API-ul pentru SQL (JDBC)

JDBC este un API pentru execuția instrucțiunilor SQL. JDBC este o colecție de clase și interfețe dezvoltate complet în Java care fac posibilă scrierea aplicațiilor care lucrează cu baze de date direct în Java. Ideea de bază a JDBC este aceea de a putea păstra independența de platformă a programelor Java chiar și când acestea accesează baze de date. Cu JDBC este posibil să se scrie o aplicație care execută instrucțiuni SQL fără să fie nevoie să cunoști dinainte dacă aceste instrucțiuni vor rula pe un server Oracle, Sybase sau Microsoft.

JDBC nu este un API foarte complex. Cu ajutorul lui, se pot face doar următoarele operații: se poate conecta o bază de date, se poate executa pe ea o instrucțiune SQL și se pot prelucra rezultatele. Cu alte cuvinte, JDBC este doar un API de nivel jos, deasupra căruia se pot implementa API-uri de nivel înalt.

JDBC poate accesa direct o dază de date pe baza unui driver sau poate accesa o bază de date prin ODBC, folosind un bridge JDBC-ODBC. Desigur s-ar fi putut accesa direct driverele ODBC, dar în acest caz s-ar fi pierdut independența de platformă și eficiența datorită faptului că ODBC este în principal proiectat pentru C, deci folosind pointeri. JDBC interpune aplicație și baza de date un nivel scris în Java care este portabil și care este supus tuturor restricțiilor de sercuritate necesare. De altfel, noile produse din zona de baze de date de la Microsoft numite RDO, ADO și OLE DB merg în aceeași direcție.

În ceea ce privește standardul SQL folosit de JDBC, sunt de făcut câteva precizări: Este binecunoscut faptul că, deși există un nucleu standard de funcționalitate SQL în toate sistemele relaționale, acestea au și multe extensii care nu sunt conforme întotdeauna cu standardele SQL de ultimă oră. JDBC rezolvă această situație de fapt permițând transmiterea instrucțiunilor SQL nestandard. Desigur, aplicațiile trebuie să fie pregătite să primească în locul rezultatelor un cod de eroare.

Interfața nativă Java

Această interfață este proiectată pentru a oferi o cale comună de scriere a metodelor native Java precum și o cale de a apela mașina virtuală din aplicații scrise în cod nativ. Principalul scop al acestei interfețe este acela de a oferi compatibilitate bibliotecilor de funcții native între mașinile virtuale Java rulând pe același tip de platformă. Cu alte cuvinte, aceeași bibliotecă să poată fi folosită și sub mașina virtuală Sun pentru Win32 și sub mașina virtuală implementată de Microsoft pentru același Win32 sau sub mașina virtuală implementată în Asymetrix SuperCede Java Edition.

Clase interioare

Clasele interioare sunt clase care se pot defini în interiorul unor alte clase, în interiorul unui bloc de instrucțiuni sau chiar într-o expresie (caz în care sunt anonime). Până la apariția acestei specificații, în Java clasele puteau definite doar la nivelul cel mai de sus al sursei, în interiorul unor pachete.

Concluzii

JDK 1.1 aduce cu siguranță un nou suflu în lumea dezvoltatorilor de Java și este de așteptat ca cele mai importante firme să îmbrățișeze în curând noua versiune. În ceea ce privește JavaSoft, această firmă și-a portat deja toate produsele pe noua platformă, incluzând aici Serverul Web Java (Jeeves) și navigatorul HotJava care este deja în final beta și va fi lansat oficial la sfârșitul lunii Martie.


BYTE România - martie 1997


(C) Copyright Computer Press Agora