MokaByte Numero 21 - Luglio 1998
 

 
Java: ieri, oggi 
e domani 
di 
Antonio Cisternino 
 

 


 


Java è un linguaggio dalla storia complicata, che ha dovuto cambiare più volte faccia prima di giungere alla versione attuale.  In questo articolo cercherò di ripercorrere le tappe dell'evoluzione di Java cercando di capire in che modo la sua storia ha condizionato il suo sviluppo e la sua diffusione.


La genesi di Java
In principio Bill Gosling ha lavorato ad un linguaggio per sistemi embedded. Questo linguaggio portava il nome di OAK ed aveva degli obiettivi ben precisi: programmare in modo semplice dispositivi elettronici. In pratica chiunque, grazie ad OAK, avrebbe potuto scrivere il programma per la propria lavatrice senza cambiarla! Gli obiettivi di OAK hanno condizionato fortemente il linguaggio delineando alcuni dei tratti caratteristici che hanno decretato il successo di Java. Programmare sistemi embedded non è compito banale e quindi non era così stupido definire un linguaggio orientato allo sviluppo di sistemi embedded che ne innalzasse il livello di programmazione con un conseguente innalzamento della qualità dei prodotti realizzabili. Il linguaggio doveva supportare il paradigma della programmazione Object Oriented, doveva essere semplice da utilizzare ma allo stesso tempo doveva consentire di accedere alle funzionalità dell'hardware come accade in C. Un linguaggio di questo tipo è praticamente impossibile da realizzare in hardware se non con costosi supporti; hanno pensato quindi di utilizzare un compilatore per abbassare il livello del linguaggio poi effettivamente interpretato dal sistema embedded. In pratica volevano dare alla lavatrice un processore (ovviamente prodotto da Sun) su cui giravano programmi scritti in OAK, compilati e successivamente installati.

La programmazione di sistemi embedded introduce problematiche di concorrenza e real-time. Per questo motivo in OAK è stato previsto un supporto per la concorrenza direttamente nel linguaggio. Ecco quindi che abbiamo due elementi fondamentali: supporto per la concorrenza nel linguaggio, compilazione in uno pseudo codice interpretato dal sistema embedded. L'impronta più forte che OAK ha lasciato su Java è sicuramente la possibilità di realizzare in hardware un interprete per il linguaggio.

Il codice generato dalla fase di compilazione doveva essere infatti compatto e l'interprete doveva essere sufficientemente semplice per poter realizzare un chip che lo implementasse. Grazie a questo fondamentale requisito possiamo oggi parlare di JavaChip. Infatti, la JVM altro non è che un'evoluzione della macchina prevista per OAK. Il progetto OAK non ebbe comunque molto successo e stava per fallire miseramente quando vi fu un incontro "magico" tra Gosling e Mark Adresseen, colui che ha di fatto ideato Netscape e una buona parte delle tecnologie che adesso sono irrinunciabili nel web.

Netscape, Mark Adresseen, il nome e la svolta
È vero, questo è un articolo su Java, ma mi voglio prendere la libertà di aprire una parentesi su Netscape e sul web al momento in cui OAK stava per morire e vi fu il suddetto incontro. Questo perché se alcuni tratti di Java sono nati con OAK altrettante caratteristiche sono state fortemente condizionate dall'incontro con Netscape. Al tempo di cui stiamo parlando Mark Adresseen aveva da poco lasciato NCSA per mettersi in proprio e fondare la Netscape per proseguire l'esperienza dello sviluppo di Mosaic che alla NCSA si stava in qualche modo esaurendo. Il problema principale era legato ad HTML, allora ancora alla versione 2.0, che aveva forti limitazioni riguardo al contenuto delle pagine. In particolare era possibile realizzare solo pagine statiche in cui veniva presentato il contenuto sotto forma di ipertesto; c'era poi lo scomodo meccanismo dell'interazione CGI che non era particolarmente flessibile e non si prestava a realizzare animazioni ma solo pagine statiche il cui contenuto cambiava dinamicamente.
In quel periodo Mark aveva proprio un bel problema! Agitare le pagine web dotandole di contenuti dinamici animazioni e suoni e di interazioni di livello più alto. Per caso Adresseen venne in contatto con Gosling e OAK, e decise che questo linguaggio era adatto per il suo scopo. Aveva infatti due requisiti fondamentali: era un linguaggio semplice e pensato per essere eseguito con un supporto semplice. Ecco quindi che i due si ritrovarono a tavolino per discutere come far evolvere il linguaggio per venire incontro all'esigenza di agitare le pagine web. La leggenda vuole che proprio durante questo incontro una tazza di caffé (o meglio quel liquido colorato che gli americani non osano neanche chiamare caffé ma solo Java) cadde sui fogli su cui stavano lavorando ed... ecco il nome per il nuovo linguaggio, Java! Era un nome sicuramente più incisivo e meno cacofonico di OAK, sicuramente il nome giusto per un prodotto di successo. Dopo l'accordo fu presa la decisione di sviluppare Java in modo indipendente da Netscape e successivamente integrare le due tecnologie. Resta comunque il fatto che molte caratteristiche di Java siano state condizionate proprio dalle necessità di Netscape. Vorrei quindi riflettere un attimo su quali erano le principali esigenze di Netscape a proposito del linguaggio che ormai si chiamava Java. Netscape voleva delle pagine web dinamiche, che permettessero delle interazioni di livello più elevato rispetto a quelle che consentiva HTML con il semplice click su di un link oppure il riempimento di una form. Poiché Netscape era un browser multipiattaforma, Java avrebbe dovuto girare su più piattaforme Ecco quindi che l'architettura che prevedeva una compilazione del linguaggio in un pcode più semplice da interpretare si rivelava fondamentale per quello che oggi è considerato uno dei maggiori pregi di Java: "write once run everywhere". La macchina virtuale di Java doveva quindi definire un formato standard per tutti gli oggetti accessibili, in particolare per i numeri e la loro rappresentazione. Altri tre punti erano essenziali alla buona riuscita del progetto: la sicurezza, la possibilità di realizzare grafica e riprodurre suoni e la capacità di accedere in modo semplice alla rete.
Il primo punto era chiave: le applet Java erano dei veri e propri programmi messi in esecuzione in modo automatico, quindi un buon modello di sicurezza risultava fondamentale per garantire che l'esecuzione dei programmi non potesse danneggiare in nessun modo i client che caricavano le pagine web contenenti le applet.Proprio in quel momento fu definito il modello di sicurezza della sand-box che tuttora si è dimostrato funzionante a meno di bachi nell'implementazione. Il secondo punto era necessario per raggiungere l'obiettivo di Netscape: offrire interazioni più ricche di quanto fosse allora possibile nel web. Questo obiettivo è stato in parte mancato con la nascita di paradigmi alternativi e spesso più semplici per rendere più dinamico il contenuto del web. In compenso in quel contesto fu definita una delle librerie che sicuramente hanno reso Java particolarmente appetibile: l'Abstract Windowing Toolkit (AWT). La libreria AWT permette infatti di poter programmare interfacce grafiche in modo indipendente dalla piattaforma. Questa è stata praticamente una rivoluzione pari all'ideazione della metafora degli stream di I/O su cui praticamente tutti i linguaggi basano la propria libreria standard.
Le due dimensioni non si erano ancora affacciate nelle librerie standard dei linguaggi. L'esistenza poi di un meccanismo di concorrenza nel linguaggio si è rivelato essenziale per poter sviluppare in modo semplice animazioni.
Il fatto che Java fosse così intimamente legato alla rete ha portato come naturale conseguenza la definizione di meccanismi di accesso standard alla rete basati sulla metafora delle Socket. L'uso delle Socket fu però reso più semplice ed intuitivo rendendo così di fatto molto più abbordabile la scrittura di programmi che facevano uso della rete. Per questo anche la programmazione di rete è entrata a fare parte della libreria standard del linguaggio. Il risultato di tutto il progetto Java fu la versione 1.0 (poco dopo rimpiazzata dalla versione 1.0.2), integrata nel browser di Netscape (capace di essere autonoma rispetto al browser). Il grande punto di forza del nuovo linguaggio era appunto una libreria standard veramente nutrita. Chiunque abbia mai programmato in qualche linguaggio sa perfettamente che la libreria standard definisce ciò che è meglio usare per scrivere i propri programmi.
Java ha sicuramente avuto il merito di introdurre nella libreria standard di un linguaggio aspetti moderni di programmazione quali: interfacce grafiche, programmazione concorrente e soprattutto un supporto di rete.

La versione 1.0.2: il successo e i suoi limiti
Lasciando in qualche modo la preistoria possiamo parlare di ciò che ormai è quasi storia: la versione 1.0.2 di Java. Questa versione è una pietra miliare nello sviluppo del linguaggio ed è la versione che è stata più stabile finora. Tuttora, a causa del ritardo con cui i browser hanno cominciato a supportare la versione 1.1, questa versione viene ancora utilizzata.

Molte sono le macchine che, oltre alla mia, hanno installato sopra entrambe le versioni, con qualche script che permette di selezionare la versione da utilizzare. Abbiamo già discusso come la genesi di questo linguaggio lo abbia profondamente segnato; vorrei quindi concentrarmi ora su quegli aspetti della versione 1.0.2 che erano il punto cardine: il modello di sicurezza e le applet. Il modello di sicurezza di Java, più noto col nome di sand-box model, è una delle principali ragioni del successo di Java ma è allo stesso tempo uno dei suoi più grandi limiti. La metafora si basa sulla buca di sabbia in cui un bambino può giocare tranquillamente senza però essere capace di uscirne.

Il modello di sicurezza previsto poggia su una particolare classe che è il tristemente noto Security Manager. Il modello è più flessibile di quanto possa apparire in prima battuta. Infatti l'architettura prevede un controllo della sicurezza con una granularità molto fine: in pratica tutte le chiamate della libreria standard controllano se è stato installato un security manager e in tal caso lo interrogano chiedendo se possono fare o meno una certa operazione. Le applet di Java 1.0.2 erano eseguite in un ambiente in cui il SecurityManager vietava di fare qualsiasi cosa se non sfruttare le capacità grafiche della macchina ed aprire Socket col server da cui l'applet era stato caricato.

Uno dei principali punti di forza doveva essere proprio il modello di sicurezza, poiché in un primo tempo di Java si parlava solo a proposito delle Applet. Per superare la sfiducia diffusa verso la possibilità di eseguire programmi scaricati dalla rete il browser doveva essere blindato. Molti sanno quanto dolorosa è stata questa scelta per gli sviluppatori, costretti a convivere con queste limitazioni non banali per la scrittura di applet che siano utili e non si limitino a rendere graficamente più dinamiche le pagine web. Il sottoscritto, come del resto molti altri sviluppatori Java, è stato spesso costretto a scrivere numerosi server custom che raccogliessero su un server i dati elaborati dalle applet.

Purtroppo però nella maggior parte dei casi queste forti limitazioni imposte dal modello di sicurezza hanno fatto sì che da una parte Java fosse sempre abilitato sui browser ma dall'altra hanno condizionato il tipo di applet scritte che per lo più erano applet banali scritte per superare le innumerevoli limitazioni dell'HTML. Java 1.0.2 segna anche l'ingresso di Microsoft nel mondo di Java. Con la versione 3.0 infatti viene implementato Java anche in Internet Explorer contribuendo così al consolidarsi di uno standard. Allo stesso tempo Sun cerca di definire uno standard di Java sfruttando la sua posizione che in quel momento è sostanzialmente di monopolio industriale.

La versione 1.1
Passiamo ora ai giorni nostri e vediamo di scorrere rapidamente le novità introdotte con la versione 1.1 del linguaggio cercando successivamente di capire quali siano le tendenze di Java e quale sia il suo futuro. Con la versione 1.1 Java muove i suoi passi da giocattolo divertente per gli sviluppatori a prodotto vero e proprio. Molti sono i segnali che ce lo fanno capire: il modello di gestione degli eventi dell'interfaccia grafica viene sostanzialmente rivoluzionato e vengono introdotti nuovi package che estendono incredibilmente le potenzialità del linguaggio. Le novità sostanziali sono sicuramente costituite dall'aggiunta di tre elementi al sistema: il supporto alla crittografia e alla sicurezza, il supporto a RMI e Java Beans.

Tali estensioni introducono nuovi livelli di complessità nel linguaggio, offrendo caratteristiche spesso costose da implementarsi in modo custom. Il modello di sicurezza poi viene modificato in parte ammettendo che applet firmate con meccanismi di firma elettronica possano uscire dalla sand-box per comportarsi come delle vere e proprie applicazioni che vengono inviate al cliente. Purtroppo con la versione 1.1 arrivano anche le prime incompatibilità nelle implementazioni.

In particolare viene introdotto il meccanismo di firma delle applet che non è compatibile con quello proposto da Netscape. Inoltre Microsoft, con il suo Internet Explorer, cerca di minare il successo del linguaggio introducendo una versione di Java non compatibile nel suo browser. La versione 1.1 afferma, come se ce ne fosse ancora bisogno, la veste di Java come di un linguaggio di rete. Infatti lo studio dei meccanismi di autenticazione è profondamente legato alla possibilità di identificare persone in una rete. Lo stesso si può dire a proposito dei supporti ad RMI, un interfaccia per l'invocazione di metodi remoti. Inoltre Java si sta dimostrando fondamentale nella realizzazione di framework per agenti mobili, come ad esempio Aglets di IBM.

Le caratteristiche di sicurezza e di poter girare su qualsiasi piattaforma rendono molto semplice la scrittura di classi in grado di spostarsi durante l'esecuzione da un calcolatore ad un altro. È possibile quindi scrivere in modo molto naturale agenti che ricercano e comunicano tra loro usando la rete. La crescita smodata della libreria di classi di Java non è solo un aspetto fondametale e positivo ma anche in parte negativo. La Sun sta aggiungendo al linguaggio numerose interfacce (con o senza la relativa implementazione) che si occupano di elevare il livello di astrazione del linguaggio. Alcune di queste sono JFC, JMAPI, Java Speech... La crescita spropositata del numero di queste interfacce rende sensibilmente più complesso padroneggiare il linguaggio. La curva di apprendimento del linguaggio si sta innalzando perché non basta più sapere come si scrive un ciclo o come si scrive una classe ma bisogna capire e padroneggiare con una certa disinvoltura la libreria standard. Questo forse è il momento più difficile: si tratta di cercare di indovinare cosa sarà Java nel breve e nel lungo futuro. La cosa non è facile perché sono molti i fattori in gioco, Microsoft in prima fila.

La versione 1.2
Per quanto riguarda il prossimo futuro sicuramente troviamo Java 1.2 che vuol dire: nuovo modello di sicurezza ma anche Java 3D e Swing. L'ulteriore crescita delle librerie standard influenzerà la grafica delle applicazioni e delle applet offrendo un look finalmente professionale di qualità paragonabile alle interfacce grafiche native. Il nuovo modello di sicurezza di fatto elimina la sand-box sfruttando appieno le potenzialità del SecurityManager e introducendo la possibilità di specificare un numero impressionante di permessi alle applet e alle applicazioni. Ad esempio si potrà dire che una certa applicazione può aprire solo un dato file oppure una classe di file, se scriverci dentro o meno eccetera. In questo modello appare tutta la superiorità negli aspetti di sicurezza di Java rispetto ad ActiveX: in Java si possono controllare le singole attività di un'applicazione concedendo i diritti necessari, in ActiveX abbiamo una situazione del tipo "tutto o niente". Ovviamente è lecito chiedersi se questo cambiamento di modello nella sicurezza introdurrà security leaks. Finora il sand-box model è stato inviolato come modello e tutti i sistemi con cui è stato aggirato si poggiavano su bachi di implementazione. È presto per dirlo ma sicuramente sarà fondamentale per la riuscita del linguaggio poter eseguire applicazioni direttamente dalla rete, a patto che non danneggino il computer o, forse peggio, non diffondano informazioni riservate. L'introduzione della libreria Java 3D (disponibile nella prima versione Early Access il 24 Marzo a JavaOne insieme alla beta 3 di JDK 1.2) nel panorama di Java ha molti risvolti significativi. Gli obiettivi di questa libreria sono l'efficienza e la semplicità d'uso. Questo significa che presto sarà possibile con poco sforzo e in modo assolutamente standard scrivere applicazioni che usano la grafica 3D. L'introduzione del framework JFC ed in particolare di swing segna un'inversione di rotta nell'architettura di base dell'AWT.

Uno dei principi base dell'AWT era quello di implementare i componenti dell'interfaccia grafica sfruttando quelli disponibili nelle interfacce grafiche native. Ogni componente AWT aveva quindi un peer. In pratica un bottone veniva visualizzato come bottone dell'interfaccia grafica e gestito attraverso Java. Sono evidenti i vantaggi di tale approccio ma introducono anche molte limitazioni dovute alle profonde differenze che troviamo nelle diverse interfacce grafiche. Con il miglioramento della gestione degli eventi e dell'interfaccia grafica Sun ha intrapreso un'altra strada: usando le primitive di base (che sono praticamente comuni a tutte le interfacce) ha definito la propria interfaccia grafica. In pratica ha disegnato le proprie finestre, le proprie scrollbar ecc.

In questo modo è stata capace di offrire componenti di più alto livello non standard nelle interfacce grafiche come ad esempio tabbed dialog, tree, grid e tooltip. Infine ha introdotto il concetto di look & feel: i componenti di base dell'interfaccia (poiché interamente disegnati da Java) quali, ad esempio, le finestre, le scrollbar e i bottoni hanno un look parametrico (determinato dal look & feel) che varia. In particolare è disponibile, ad esempio, il look & feel Windows: in tal caso anche su una Sun o su un Mac i bottoni dell'applicazione Java saranno come quelli di Windows. Analogamente accade per altri look & feel che si possono ispirare o meno ad interfacce grafiche esistenti.

Il futuro di Java
A questo punto non restano che le considerazioni più importanti: quelle sulle prospettive reali di Java.

Fino a questo momento Java è sicuramente una piattaforma di sviluppo con innumerevoli vantaggi rispetto alle piattaforme tradizionali. La semplicità del linguaggio unita alla grande ricchezza della libreria standard e alla presenza in questa di modi standard per programmare aspetti delle applicazioni che finora standard non erano disponibili, ci permette di dire che in potenzialità Java potrebbe essere la piattaforma per il futuro.

Java e le sue prospettive

Purtroppo però non è tutto oro quel che luccica e anche in questo caso ci sono parecchi "se" e "ma" tra Java e il suo reale successo. Sono due anni che mi sento dire che Java è il futuro, io stesso ho scritto il mio primo applet sulla terza beta della versione 1.0, eppure non credo che Java sia attualmente, se non in potenza, un reale successo. Le aziende si stanno iniziando a muovere ora per cercare di capire di cosa si tratta. Inoltre, sono ancora poche le applicazioni non banali scritte in Java. La comunità degli sviluppatori sta ancora giocando con Java ma sicuramente non lo usa in tutte le sue potenzialità. Ci sono poi molte incognite che preoccupano un po' gli sviluppatori (me in prima fila): la continua e apparentemente inarrestabile crescita della piattaforma introduce molte incertezze nel codice che si scrive; questa mancanza di stabilità può essere un ostacolo alla diffusione del linguaggio. Devo dire però che negli ultimi tempi comincio a vedere prodotti realmente interessanti scritti in Java e credo che Java stia raggiungendo un certo livello di maturità. Soprattutto gli sviluppatori cominciano ad utilizzarlo non più solo per sperimentarne le capacità. Si iniziano ad affacciare al mercato sistemi interamente scritti in Java. Un altro punto chiave per il futuro di Java è lo standard: con la release dell'SDK 2.0 di Microsoft è stato avvicinato Java a Windows introducendo una versione incompatibile con quella ufficiale di Sun. La strategia di Microsoft mira proprio a questa rottura per riportare gli sviluppatori a sviluppare per la propria piattaforma temendo di perdere l'egemonia grazie ad applicazioni in grado di girare su qualsiasi piattaforma. Sun sta rispondendo al colpo di Microsoft con Java Activator, un'interessante tecnologia che permette di decidere quale JVM utilizzare nel proprio browser consentendo così di poter utilizzare la JVM più recente senza dover aspettare chi sviluppa i browser. Inoltre così si può di fatto rendere compatibile Explorer con la versione 1.1. di Java. Sicuramente il DOJ (Department Of Justice) americano avrà un grande peso in questa faccenda poiché Microsoft sta investendo una quantità di risorse non indifferente sulla propria versione di Java. Uno degli ingredienti che ha decretato il successo di Java è la semplicità con cui è possibile programmare applicazioni che usano la rete; questo è sicuramente uno degli aspetti che condizionerà il futuro del linguaggio. Abbiamo però detto che l'interazione in ambienti di rete introduce problematiche di sicurezza e che queste sono fondamentali da affrontare; per cui l'evoluzione del modello di sicurezza sconvolgerà un'altra volta il panorama di Java aprendo nuove possibilità alla stesura del software di rete. Le applicazioni che fanno uso della rete inoltre non hanno particolari requisiti di efficienza poiché i tempi di accesso della rete sono non di poco inferiori ai tempi di elaborazione di un processore; per questo motivo il fatto che sia un linguaggio interpretato non influisce molto sulle performance. Un ruolo possibile che potrebbe giocare Java nel futuro è quello di essere una piattaforma standard che si pone "sopra" il sistema operativo e fornisce un'interfaccia unificata per scrivere applicazioni. In questo modo potremmo avere applicazioni che girano su qualsiasi architettura senza neanche il bisogno di essere ricompilate. Inoltre è proprio il caso di parlare di piattaforma poiché è possibile invocare, attraverso l'interfaccia JNI, la JVM da applicazioni native. Un possibile scenario potrebbe essere quello in cui le applicazioni critiche che svolgono la computazione vera e propria vengono scritte in linguaggi efficienti mentre la gestione dell'interfaccia grafica e delle altre risorse di sistema potrebbe essere gestita in modo standard attraverso Java.
 
 

JavaChip e Network Computer
L'introduzione di Java sui sistemi embedded, in atto in questo periodo, probabilmente rivoluzionerà ulteriormente il panorama di Java. Sono già stati annunciati accordi che riguardano l'integrazione di tecnologia Java in sistemi embedded usando supporti hardware. Sun stessa supporta questo tipo di tecnologie definendo un'interfaccia standard. I sistemi embedded saranno presumibilmente basati sul JavaChip, un processore che implementa in hardware l'interprete JVM di Java. Avendo a disposizione un tale processore è possibile eseguire le applicazioni Java senza un interprete ma direttamente sfruttando l'hardware. Questo processore di fatto incrementerebbe le prestazioni delle applicazioni scritte in Java fino a renderle veloci quanto le applicazioni native. In compenso rimarrebbe la compatibilità con altri sistemi grazie all'implementazione dell'interprete sulle varie piattaforme. La possibilità di poter implementare Java su sistemi relativamente poco potenti lo rende un linguaggio ideale anche per la realizzazione di network computer. Sun commercializza un kit a basso costo per trasformare vecchi PC MS-DOS in network computer Java based. I JavaChip trovano poi una naturale applicazione nella realizzazione dei network computer. Sun sta già commercializzando le prime Java Station, Network Computer basati su JavaChip che usano JavaOS, un sistema operativo scritto in Java. Le JavaStation sono delle postazioni di lavoro diskless in cui il sistema operativo, JavaOS, viene caricato da un server di rete; sono in grado di scrivere sul disco del server ed offrono un'interfaccia basata su HotJava, il browser scritto in Java di Sun. Ovviamente una soluzione di questo tipo ha dei vantaggi piuttosto evidenti relativi all'abbattimento dei costi di gestione e mantenimento di una rete. Infatti è sufficiente configurare il server per amministrare tutti i client. I programmi, scritti in Java, vengono scaricati dalla rete per essere eseguiti direttamente sulla JavaStation. Oltre a quanto già detto a proposito della naturalezza con cui è possibile interagire con la rete in Java bisogna dire che la dimensione dei programmi è molto contenuta grazie al fatto che usano molto l'enorme libreria a disposizione diminuendo quindi la quantità di codice da linkare nelle proprie applicazioni. Questa caratteristica può rivelarsi molto utile per rendere più efficienti i Network Computer basati su Java.

Conclusioni
Le prospettive per Java nel futuro sono molte e non è facile dire cosa accadrà. Sicuramente il ruolo che di fatto sta cominciando a giocare Java (ed è proprio ciò che Microsoft non vuole) è quella di essere uno strato di software multipiattaforma che permetta di programmare applicazioni non banali che girano su piattaforme diverse senza neanche essere ricompilate. Inoltre le varie caratteristiche del linguaggio lo rendono particolarmente indicato a chi programma la rete. Gli interessi in gioco sono enormi, lo sta dimostrando la causa tra Sun e Microsoft in cui la disputa è proprio sulla compatibilità di Java. Sicuramente Java comincia a proporsi come una reale piattaforma per gli sviluppatori e non più come un giocattolo per scrivere semplici applet.
 
 

 
 
 


MokaByte Web  1998 - www.mokabyte.it 
MokaByte ricerca nuovi collaboratori. Chi volesse mettersi in contatto con noi può farlo scrivendo a mokainfo@mokabyte.it