Java:
introduzione al linguaggio e alla tecnologia
Java
in questo momento è una parola molto di moda e praticamente anche
i non addetti ai lavori ormai ne hanno sentito parlare. Se invece andiamo
a chiedere precisamente di cosa si tratti, non è detto che si riesca
ad avere con altrettanta facilità una risposta chiara ed esauriente:
infatti oltre ad una mancanza di informazioni precise, nell’ambiente informatico
circolano una serie di notizie più o meno vere che cercano
di denigrare Java o di esaltarne le qualità oltre misura.
In
questa sessione cercheremo di analizzare in maniera obiettiva le effettive
potenzialità di Java, al fine di permettere una comprensione chiara
e completa degli argomenti di base. Al termine del Worklab, dovrebbero
essere stati acquisiti inoltre certi elementi basilari di pratica
che permettano di iniziare a sviluppare semplici applicazioni Java.
Java...
Cos’è?
Molto
sinteticamente possiamo dire che con la parola Java si può indicare
sia un linguaggio ad oggetti, sia una tecnologia basata su macchina
virtuale che interpreta le istruzioni di tale linguaggio appositamente
compilato.
Anche
se le due cose possono sembrare profondamente differenti fra loro, esse
sono strettamente legate, e danno luogo a quella che a volte viene detta
tecnologia Java.
Breve
storia di Java
Nel
1988 in Sun viene fatto partire un progetto per un nuovo sistema di interfaccia
grafica, denominato News, basato su un concetto nuovo per l’epoca: maggiore
astrazione rispetto all’hardware sottostante, sia in termini di riferimenti
alle risorse, sia dal punto di vista logico (la visualizzazione Postcript
aveva proprio questo scopo).
Nonostante
le enormi risorse messe a disposizione, Sun procede lentamente nel
progetto che diviene una esperienza isolata contrapposta a quello
che in quel momento veniva fatto dagli altri colossi mondiali. A
prescindere dai risultati del lavoro, questa esperienza servì per
far maturare nella testa di personaggi come Gosling,
Naugthon e Joy, l’importanza della necessità di un soluzione nuova
al problema dell’astrazione dall’hardware sottostante e della portabilità.
Dalle
difficoltà di News e della sua gestione, in Sun si decise verso
il 1990 di far partire un progetto gestito indipendentemente da un gruppo
esterno. La filosofia principale era la massima autonomia dalle scelte
politiche e tecnologiche di Sun. Non ci si sarebbe appoggiati a nessuna
piattaforma in particolare, ma anzi dopo aver ipotizzato l’utilizzazione
della piattaforma PC si pensò alla realizzazione di un hardware
specifico, che fosse fortemente orientato alla grafica.
Il
progetto si sarebbe rivolto al mercato di largo consumo, avrebbe dovuto
avere una interfaccia grafica irresistibile ma al tempo stesso originale.
La prima mossa fu quella di realizzare un computer portatile basato su
qualcosa di simile alla tecnologia Sun dell’epoca. Il kernel del
S.O. era un derivato del SunOs riadattato in modo che potesse girare su
un sistema molto più piccolo. Nacque il progetto Green, predecessore
di Java.
Nel
1992 viene presentato il prototipo, Star 7, una specie di supporto per
applicazioni di largo consumo, come cercapersone o guide per programmi
televisivi. Prende forma il padre di Java, un linguaggio ad oggetti multimediale
e con una spiccata capacità per la gestione delle comunicazioni,
unitamente ad una astrazione dal basso nuova per l’epoca. Il linguaggio
venne denominato OAK.
Il
prototipo hw realizzato doveva essere un surrogato di un elettrodomestico
di diffusione di massa. Purtroppo questo settore era troppo concorrenziale
e non pronto a digerire la diffusione di una macchina tecnologicamente
così avanzata.
A
causa dei fallimenti in tale direzione, unitamente agli enormi sviluppi
del mercato del PC, nel 1994 si comprese che proprio il PC era l’elettrodomestico
di largo consumo che si cercava. Viene abbandonata l’idea di realizzare
una piattaforma hw dedicata.
Il
progetto si affaccia ad internet: per battere la concorrenza e le avversità
politiche, il linguaggio e la piattaforma (sorgenti compresi) viene
rilasciato free su internet. Siamo verso I primi del 1995, nasce il progetto
live OAK. In questa fase si focalizza l’attenzione sulla parte del
linguaggio.
Nel
1996 nasce Java come linguaggio slegato dalla piattaforma e fortemente
progettato per internet. Il gruppo di lavoro indipendente da Java ormai
si è completamente disciolto, e come ultima cosa realizza una semplice
applicazione, ed un ambiente in grado di interpretare l’html. Nasce la
prima applet (Duke che saluta) ed il primo ambiente in grado di gestirla
(il padre di HotJava).
Java:
il linguaggio
Analizzando
Java semplicemente dal punto di vista del linguaggio possiamo individuare
alcune caratteristiche fondamentali: la prima e più importante è
che il codice bytecode, senza necessità di ricompilazioni, è
eseguibile su ogni tipo di piattaforma hardware-software che metta
a disposizione una macchina virtuale Java.
Dato
che ormai le VM sono disponibili per ogni tipo di sistema operativo
e per ogni tipo di hardware, il bytecode è di fatto il primo esempio
di portabilità reale e totale.
Java
è un linguaggio ad oggetti puro, nel senso che non è
possibile programmare non OO in parte o del tutto (come invece
accade ad esempio col C++).
La
gestione della memoria, per motivi di sicurezza e di semplicità
di programmazione, viene fatta in automatico dalla VM per mezzo di un efficiente
(ma non sempre) Garbage Collector.
Una
delle caratteristiche fondamentali di Java è che esso mette a disposizione
un meccanismo di multithreading, col quale è possibile, all’interno
della stessa applicazione, eseguire contemporaneamente più task.
La
VM inoltre implementa un sistema di caricamento delle classi automatico,
che permette di caricare le classi (nel caso di applicazioni internet,
di scaricare dalla rete) solo al momento dell’effettiva necessità,
in maniera molto simile a quanto avviene con le DLL.
Il
linguaggio Java infine è stato progettato con il preciso obiettivo
di garantire la massima sicurezza (dell’applicazione ma anche del client
su cui viene mandato in esecuzione), e la massima semplicità d’implementazione
e di debug (che diviene molto meno necessario rispetto ad altri linguaggi).
Anche
l’apprendimento è molto più semplice: sono stati eliminati
certi costrutti complessi, che oltre a pregiudicare in certi casi la correttezza
formale del programma, ne rendeva difficile la comprensione. Il fatto
che la sintassi sia molto simile a quella del C++ rende il passaggio a
Java meno indolore, e sicuramente non così difficile come l’apprendimento
di un linguaggio nuovo.
La
mancanza dei puntatori rende molto più sicuro il codice
e meno facile l’insorgere di bug insidiosi. Il livello di astrazione dato
dall’introduzione di uno strato di software aggiuntivo svincola dal doversi
preoccupare delle problematiche tipiche della piattaforma sottostante.
Java
e il WWW
Anche
se Java è un linguaggio per tutte le stagioni, è sicuramente
vero che la maggior parte delle sue caratteristiche si adattano, o meglio,
sono particolarmente indicate per la programmazione per la rete. Una delle
modalità per utilizzare applicazioni Java in rete (ma non l’unica)
è quella di far eseguire i programmi direttamente al browser che
contiene al suo interno una macchina virtuale.
Prima
di vedere come funzioni tale meccanismo, vediamo cosa accadeva prima
dell’introduzione di Java. In tale situazione, nel momento in cui il browser
si trovava a dover gestire un documento non direttamente interpretabile,
esso doveva far riferimento ad una applicazione esterna o utilizzare un
plug-in preventivamente installato. In ogni caso non si trattava di una
vera e propria esecuzione diretta di codice, ma solo una specie di forward
di codice alle applicazioni interessate. E’ ovvio che in tale situazione
non era possibile dar vita ad una vera e propria programmazione distribuita
che sia interattiva.
L’introduzione
di Java ha cambiato notevolmente le cose: infatti adesso il browser è
in grado, per mezzo di una VM integrata, di eseguire direttamente le applicazioni
inserite in pagine html, che ha scaricato preventivamente dalla rete. Questo
tipo di applicazione viene detta applet, e vedremo in seguito cosa essa
sia. Per il momento possiamo dire che si tratta di una normale applicazione
Java tarata per essere scaricata dalla rete e per essere eseguita
all’interno di un browser. Per poter permettere il download e l’esecuzione
automatica, una applet deve essere inserita in una pagina html per mezzo
del tag <applet>
La
rete diviene quindi un canale di comunicazione da cui prelevare il software,
ed il browser, un client che esegue un programma in locale. Attualmente
tutti i browser più famosi incorporano una macchina virtuale e sono
in grado di eseguire applet.
La
programmazione distribuita ed il Network Computing
Ovviamente
la modalità applet non è l’unica possibile, ma in ogni caso
la possibilità di eseguire applicazioni attraverso la rete, da’
vita ad un nuovo modo di intendere la programmazione: non più Personal
Computer (PC) ma Network Computer (NC).
Contrariamente
ad un semplice PC collegato in rete, un NC non scarica solo i dati su cui
deve eseguire certe operazioni, ma anche le applicazioni per gestire tali
dati: da un NC, oltre a scaricare un certo documento, si scarica anche
l’applicazione per poter manipolare quel documento.
A
partire dal sistema operativo (tranne eventualmente un mini loader che
risiede in locale per le operazioni di caricamento) fino alla più
banale delle applicazioni, tutto viene da fuori per essere eseguito in
locale. Anche se l’avvento del network computing è ancora una cosa
del futuro, apre effettivamente un modo nuovo di intendere l’informatica.
Vediamo
quali sono le caratteristiche fondamentali di un NC: come prima cosa esso
può e deve essere una macchina semplice dalle potenzialità
ridotte. In linea di principio è sufficiente che esso sia
in grado di mandare in esecuzione una VM. Essendo tutti i dati (applicazioni
e dati reali) provenienti dall’esterno, non è necessario nessun
supporto di memorizzazione locale; eventualmente può essere utile
un sistema di back-up o di cache locale, che renda il lavoro più
veloce.
La
dipendenza dal tipo di hardware sottostante, aspetto oggigiorno di fondamentale
importanza, diverrà sempre più secondaria, dato che la presenza
di una macchina virtuale permetterà al software di ultimo livello
(quello utente o di sistema) di poter girare indifferentemente su ogni
piattaforma per la quale sia disponibile una VM. Da questo punto di vista
è importante notare che un qualsiasi processore può ospitare
una macchina virtuale ed il set di API che formano il sistema operativo.
Sun
da questo punto di vista ha provveduto a rilasciare tre processori appositamente
pensati per l’esecuzione di codice Java: PicoJava, MicroJava, ed
UltraJava. Al momento è disponibile solo il primo, il meno potente,
destinato al settore dei piccoli dispositivi elettronici (telefoni cellulari,
elettrodomestici, etc.).
La
definizione di un set completo di api per la VM permette di dar vita in
maniera quasi banale ad un sistema operativo in Java e per Java: JavaOs.
Software
Renting
Il
meccanismo di download, non solo dei dati, ma anche del software necessario
per manipolarli, permette di ipotizzare un nuovo modo di intendere il software
e la sua distribuzione di massa. Infatti, se oggi per poter utilizzare
un certo applicativo è necessario comprare la licenza d’utilizzo
e il supporto per l’installazione (floppy disk, CDRom, network download
o altro), in un futuro dominato dai NC potrebbe essere sufficiente pagare
per la licenza d’utilizzazione e scaricare di volta in volta il software
voluto. Questo meccanismo, se da un lato permette di avere sempre l’ultima
versione del software voluto, dall’altro permette di pagare solo quando
necessario, e per il tempo voluto, dando luogo ad una specie noleggio del
software.
Al
momento attuale i NC sono al centro di discussioni che vedono contrapposti
ai fautori dell’avvento di Java coloro che invece ritengono che la
tecnologia attuale possa soddisfare le necessità della comunità
informatica mondiale. L’alleanza Microsoft-Intel è quella che ovviamente
ha maggiore interesse affinché il NC di Java non si diffonda,
per questo versioni alleggerite di Windows eseguite su PC a basso costo
dovrebbero contrapporsi alla soluzione Java. Le discussioni fra le due
fazioni a volte vertono su aspetti del tutto futili, appellandosi alle
definizioni dell’avversario per sostenere la bontà del proprio progetto.
A
parte questi particolari, e a parte le definizioni NC, NetPC, Thinclient,
FatClient e quanto altro verrà introdotto nel prossimo futuro, il
concetto di Zero Administration Computer (ZAC) sta attraendo l’attenzione
di tutti.
Sviluppo
di applicazioni Java
Il
problema delle performance è allo stato attuale il tallone di Achille
del codice Java: dato che si deve utilizzare uno strato di software interpretato,
una applicazione Java non è sempre competitiva, dal punto di vista
dell’efficienza, con una scritta in C.
Questa
osservazione è meno vera nel caso si prendano in esame applicazioni
distribuite o fortemente orientate all’uso della rete. La semplicità
con cui Java si adatta a questo mondo permette di costruire applicazioni
Net-oriented, che per mezzo di soluzioni distribuite o multi-layer possono
scavalcare la cronica mancanza di larghezza di banda tipica di Internet.
Questi
trucchi permetttono di dar vita a soluzioni che, benché scritte
con il lento Java e quindi meno veloci di equivalenti scritte
in C/C++, richiedono un tempo di sviluppo e di manutenzione
minore.
In
ogni caso tecniche di compilazioni al volo (JIT compiling) permettono
di ottenere codice di poco più lento di un compilato vero (80-90%).
Le
considerazioni sulla velocità in ogni caso perdono la loro importanza
se si prende in considerazione quelli che sono gli obiettivi principali
di Java, e cioè portabilità, sicurezza, robustezza.
JDK
Sun,
oltre ad aver definito questo nuovo linguaggio e la tecnologia ad esso
connessa, ha creato un set completo di API ed una serie di tool per lo
sviluppo di applicazioni Java. Il tutto, liberamente scaricabile da internet,
è contenuto nel Java Development Kit (JDK), che si evolve
nel tempo a seconda delle innovazioni introdotte: al momento l’ultima versione
è la 1.1.
Le
innumerevoli classi contenute nel JDK coprono tutte le casistiche di programmazione
(dalla grafica alla gestione del multithreading, alla programmazione per
la rete, alla manipolazione infine di basi di dati).
Le
classi sono raggruppate in package secondo una organizzazione molto precisa.
Ecco i package di base più importanti:
java.lang
le classi di base per poter sviluppare una applicazione minima.
java.util:
una serie di classi di pubblica utilità, dalla gestione delle funzioni
matematiche, alle stringhe a strutture complesse (vettori, tabelle hash...)
java.io:
supporto per l’I/O.
java.net:
supporto per la programmazione di rete.
java.awt:
mette a disposizione un set fondamentale di oggetti grafici per la
creazione di GUI. I vari widget sono un subset di quelli utilizzati nelle
varie piattaforme
Applet
Java
Si
è detto che un programma Java può essere inserito in una
pagina html e scaricato dinamicamente dalla rete. Il meccanismo, si ricorda,
è del tutto automatico e a carico del classloader del browser. Chiunque
si sia imbattuto in una pagina web Java-powered si sarà reso
conto che in effetti non si ha la minima impressione di avere che fare
con tale linguaggio.
Per
poter inserire un programma in una pagina ipertestuale, si deve creare
una applet. Essa è un qualcosa di molto simile ad una normale applicazione,
ma in cui il ruolo di start-up code non viene svolto dal main(), ma da
un metodo apposito detto init(). In questa parte del programma si ha l’inizializzazione
di tutte le variabili del programma e viene lanciato l’esecuzione del programma.
Anche se non è una prerogativa indispensabile, normalmente una applet,
essendo inserita in una pagina html, viene fornita di un’interfaccia grafica
in modo da poterla controllare completamente in fase di esecuzione.
Una
applet è una applicazione a tutti gli effetti, che viene eseguita
dalla macchina virtuale del browser. Non ha particolari limitazioni rispetto
ad una normale applicazione, se non quelle imposte per motivi di sicurezza
dal security manager della macchina virtuale del browser. Sotto queste
condizioni una applet non può accedere in nessun modo al file system
della macchina locale, non può scrivere sul server da cui proviene
e non può accedere ad host diversi da quelli di provenienza.
In
genere queste restrizioni, che possono sembrare vincolanti una qualsiasi
attività della applet, sono risolte utilizzando strutture client
server o 3-Tier, che permettono una avanzata gestione delle risorse
distribuite.
In
ogni caso modificando la politica restrittiva del security manager è
possibile allentare le restrizioni imposte, ottenendo applicazioni più
potenti ma anche più pericolose. Esistono tecniche di certificazione
delle applet che permettono al browser di identificare l’applet come fidata
e di abbassare la guardia quando sono mandate in esecuzione.
Si
tenga presente che il problema dei vincoli legati alla sicurezza è
di fondamentale importanza per creare un sistema di NC sicuro ed affidabile.
Tool
del JDK
Come
accennato precedentemente il Java Development Kit mette a disposizione,
oltre alle librerie di base contenute nei vari packages, una serie
di programmi per sviluppare e testate le proprie applicazioni Java. Vediamo
brevemente di cosa si dispone:
Il
comando javac manda in esecuzione il compilatore di bytecode. Deve
essere invocato passando come argomento I nomi dei file da compilare.
Come in ogni altro suo simile è possibile, tramite degli switch
appositi, specificare le varie opzioni di compilazione, come ad esempio
l’inclusione delle informazioni per debug, o la directory dove sono incluse
le librerie. La versione javac_g permette di compilare in modo da facilitare
l’eventuale debugging, che si effettua con il comando jdb. Questo
tool è molto scomodo da utilizzare, non tanto per il fatto che si
debba lanciarlo da riga di comando, ma per la difficoltà dei comandi
e delle istruzioni da eseguire. Come disse Brian Ritchie il migliore
debugging si effettua con delle printf ben messe. In questo caso tale affermazione
è quanto mai veritiera.
Ogni
applicazione compilata può essere mandata in esecuzione dall’interprete
eseguibile per mezzo del comando java.. Nel caso di una applet si deve
utilizzare l’apposito visualizzatore (appletviewer) al quale si deve passare
il nome del file html nel quale è inserita l’applet. Questo tool
non fa altro che mandare in esecuzione l’interprete sulla classe AppletViewer.
E’
possibile generare automaticamente un file di documentazione in formato
html a partire dai commenti inseriti all’interno del codice Java.
Ogni riga di commento inserita fra /** e **/ viene ignorata
dal compilatore ma non dal tool javadoc, che genera il file html.
Nel commento del codice è quindi possibile inserire tag html come
<B> o <I> per migliorare l’aspetto finale del documento. Caratteristica
interessante è la possibilità di inserire tag non html (nel
formato @<XXX>) che vengono interpretati dal javadoc per eseguire operazioni
particolari. Ad esempio @<see> genera un link ad altre classi.
Il
tool javah che permette di creare file header .h per far interagire
classi java con codice C.
Infine
il javap che esegue un disassemblamento del bytecode restituendo il sorgente
java .
La
prima applicazione
Come
ultima cosa, al termine del worklab vediamo come di generare una semplice
applicazione Java. Senza troppa originalità implementeremo
il classico «Hello Word» sia come applicazione che come applet.
public
class Salve {
public
static void main(String[] args){
System.out.println(«Ciao mondo»);
}
}
come
si può notare la struttura di questo mini programma è molto
simile ad un equivalente scritto in C.
Per
stampare nella finestra di shell, si esegue una semplice chiamata alla
println che fa parte del pacchetto out e di System.
Il
nome del file dovrebbe, in teoria, essere lo stesso della classe,
ed è per questo che si dovrebbero avere per ogni classe java un
file corrispondente.
Prima
di passare alla fase di compilazione si devono definire le due variabili
d’ambiente PATH e CLASSPATH: la prima deve puntare fra le altre cose alla
directory java\bin, mentre il CLASSPATH deve indicare dove si trova
il file classes.zip che contiene le librerie di sistema.
A
questo punto per mezzo del comando
javac Salve.java
si
ottiene il bytecode relativo interpretabile per mezzo
java Salve
A
questo punto vediamo come si può ottenere qualcosa di simile con
una applet. Il testo da visualizzare verrà in questo caso
passato come parametro esterno alla applet tramite il tag html.
import
java.applet.*;
import
java.awt.*;
public
class Salve extends
Applet {
String
text;
public
void init() {
super.init();
text = new String(getParameter("text"));
}
public
void paint (Graphics g) {
g.drawString(text,50,50);
}
}
Nell’ordine
si possono notare le seguenti parti
-
Per creare
una applet si deve necessariamente implementare la classe Applet.
-
Non è
necessario definire un main(): l’applet parte automaticamente dopo aver
lanciato il metodo init dove si mettono tutte le istruzioni di inizializzazione
della applicazione.
-
Il testo
da stampare viene prelevato dall’esterno come parametro della applet, per
mezzo di getParameter(). Si veda avanti come deve essere strutturato tale
file.
-
La stringa
non viene stampata ma disegnata nel metodo Paint per mezzo di una chiamata
a drawString().
Il file
html deve essere così definito
<APPLET
code="Salve.class" width=450 height=120>
<PARAM
NAME=text value="Salve Mondo">
</APPLET>
L’applet
viene inserita e offerta al browser per mezzo del tag <APPLET>.
Il keyword code specifica il nome del codice .class contenente l’applet.
Nel caso di più file class, esso deve riferire a quello contente
la classe principale (quella che deriva da applet).
Per
passare un parametro all’applet si utilizza il tag PARAM seguito da NAME
più il nome del parametro e da VALUE più il nome del parametro.
Prima
di concludere è bene affrontare un esempio un poco più complesso
che ci permetta di comprendere le effettive potenzialità del linguaggio.
Si è pensato di utilizzare una applet che mettesse in mostra le
possibilità di avere una applicazione dotata di interfaccia
grafica inserita in un browser.
E’
tralasciato il caso delle applicazioni che sono sostanzialmente simili
alle applet.
Rispetto
al caso precedente si noti la presenza della sezione di inizializzazione
degli oggetti grafici (oggetti anche nel senso di OOP) e la loro successiva
aggiunta al pannello principale per la visualizzazione.
Dopo
aver creato gli oggetti e visualizzati, l’altra sezione importante è
quella relativa alla gestione degli eventi, che sono intercettati dalla
handleEvent().
Ecco
il codice dell’esempio
import
java.awt.*;
import
java.applet.*;
public
class MyApplet extends
Applet {
java.awt.TextField textField1;
java.awt.Checkbox checkbox1;
java.awt.Button button1;
java.awt.Label label1;
publicvoid
init() {
super.init();
setLayout(null);
addNotify();
resize(453,358);
textField1 = new
java.awt.TextField();
textField1.reshape(12,48,312,36);
add(textField1);
checkbox1 = new
java.awt.Checkbox("Rosso");
checkbox1.reshape(12,12,132,24);
Font f= new Font("TimesRoman",
Font.BOLD, 24);
checkbox1.setFont(f);
add(checkbox1);
button1 = new
java.awt.Button("Vuota");
button1.reshape(336,48,84,36);
add(button1);
label1 = new java.awt.Label("text",Label.CENTER);
label1.setFont(new Font("Courier",Font.BOLD,
35));
label1.reshape(24,120,351,113);
add(label1);
}
publicboolean
handleEvent(Event event) {
if
(event.target==textField1){
if (checkbox1.getState())
label1.setForeground(new
Color(255,0,0));
else
label1.setForeground(new Color(0,0,0));
label1.setText(textField1.getText());
}
if
(event.target==button1){
textField1.setText("");
label1.setText(textField1.getText());
}
return
super.handleEvent(event);
}
}
Questo
secondo esempio è costituito da una serie di componenti grafici
elementari molto semplici per mezzo dei quali è possibile inserire
del testo e visualizzarlo successivamente; è anche possibile cambiare
il colore del testo.
|