MokaByte
Numero 19 - Maggio 1998
|
|||
|
fatto in casa |
||
Andrea Scarpa |
Sulla base di quanto offre VisualAge for Java, implementiamo un tool che ci aiuti nello sviluppo e nell'apprendimento di Java.Transfert Protocol, e come utilizzarlo in Java | ||
Introduzione
Uno dei problemi
che mi sono trovato ad affrontare nell'apprendere i primi rudimenti di
Java, e' stato quello relativo alla sperimentazione di piccole porzioni
di codice che mi permettessero di capire come funziona il giocattolo.
E allora? Beh,
innanzi tutto incorporavo il testo da sperimentare in una classe con un
metodo main o in un applet, poi passavo alla compilazione, procedevo alla
correzione degli errori e quindi lanciavo la classe -o l'applet- e ne verificavo
il funzionamento.
Si intende che
tutte queste operazioni andavano ripetute ogni volta che si introduceva
la sia pur minima variazione del codice da sperimentare.
Un giorno, un
mio amico javista mi mostra come funziona lo scrapbook di VisualAge: un
missile! Si scrive il codice, si seleziona il testo da sperimentare e si
clicca su un'icona "run"... il risultato viene istantaneamente visualizzato
su una apposita finestra di output.
La velocita'
di apprendimento in questo modo si alza vertiginosamente specialmente se
si possiede un "onesto" portatile Pentium 100 come ho io...
Problemino:
VisuaAge costa parecchio e soprattutto vuole almeno 32 MB di memoria.
Al momento,
l'unico ambiente di sviluppo che poteva sopportare la mia macchinetta e'
il J++ 2 di Microsoft -che per quanto ne so non implementa questa graziosa
funzione-; l'idea e' stata dunque quella di realizzare una specie di scrapbook
in Java.
L'applicazione
che ne e' uscita e' molto artigianale, ma forse qualcuno la trovera' utile.
Nella versione
attuale, lo scrapbook funziona come applicazione e per di piu' con interfaccia
carattere; al momento infatti, per me l'uso del package java.awt e' roba
da marziani.
Lo scrapbook
Bene, la costruzione
dello scrapbook e' iniziata con la definizione di un testo "template" sul
quale costruire la classe nella quale verra' poi inserito il codice java
da sperimentare: esso e' definito nel file Scrapbook.txt.
import moka.*;
import java.io.*;
import java.util.*;
import java.lang.reflect.*;
public class Temp implements Interfaccia{
public void esegui(){
***
}
}
I packages importati sono:
public void esegui()
La porzione di testo *** e' per finire quella che verra' sostituita dal CS. Ripeto, si tratta di una soluzione artigianale; qualsiasi altro sistema potrebbe andar bene: l'importante e' riuscire a compilare la class Temp ed ottenere il file Temp.class.
Passo successivo: scrittura del CS. Qualsiasi editor va bene, l'importante e' che si scrivano correttamente delle isruzioni java; come e' stato detto queste istruzioni verranno poi sostituite agli asterischi nel corpo del metodo esegui della classe Temp.
Compilazione
della classe Temp: questo problema e' stato risolto in modo assai insoddisfacente.
Finora infatti non ho trovato niente di meglio se non lanciare un processo
che compilasse la classe Temp per mezzo di un compilatore definito (nel
mio caso jvc della Microsoft)
Il metodo usato
e' esegueExe della classe Util.
public void esegueExe(String fe,boolean spetta){
Runtime r = Runtime.getRuntime();
try{
Process p = r.exec(fe);
if (spetta){
p.waitFor();
}
}
catch (Exception e){
stln("errore runtime");
}
}
L'introduzione
della variabile boolean spetta si e' resa necessaria poiche' mi sono accorto
che il processo si concludeva correttamente solo in modalita' debug: cio'
era dovuto al fatto che in questo modo la compilazione si concludeva prima
che fosse eseguita l'istruzione successiva, cio' che spesso non accadeva
nella modalita' "run".
Una volta compilato
la classe Temp, si dovra' procedere alla sua istanziazione; cio' si ottiene
per mezzo della classe CL che e' naturlamente una subclass di ClassLoader;
essa ha 2 soli metodi:
public synchronized Class loadClass(byte d[])
public synchronized Class loadClass(String st1, boolean b)
Il primo richiede un array di byte corrispondente al file Temp.class; tale array viene prodotto per mezzo di un metodo della class Util che verra' descritto piu' avanti.
Il secondo utilizza una variabile boolean b solo allo scopo di sovrascrivere il metodo corrispondente di ClassLoader.
{
Class result;
try {
result = findSystemClass(st1);
return result;
}
catch (ClassNotFoundException e){
Util u = new Util();
u.stln("Non e' una classe di sistema.");
return null;
}
}
Dopo aver definito
la variabile Class result, si verifica se la classe specificata nella variabile
di tipo String st1, e' gia' stata caricata fra le classi di sistema. Questo
metodo verra' lanciato quando si istanziera' l'oggetto Object o descritto
nella class ScrapBook.
Un po' più
nel dettaglio
L'uso del ClassLoader
e' stato naturalmente indispensabile; pur con qualche dubbio che esistano
soluzioni alternative, l'unico modo che ho trovato per ricaricare una classe
gia' caricata, e' stato quello di usare il metodo loadClass(byte xx[]);
se si cerca infatti di ricaricare una classe Temp per mezzo di un metodo
loadClass (String Temp) dopo aver modificato il file Temp.class corrispondente,
-e questa e' l'operazione che sta alla base dello Scrapbook- si otterra'
sempre il medesimo output: quello relativo alla prima classe Temp caricata.
Questo perche'
il classLoader tiene nota delle classi di sistema in una variabile privata
Hashtable che non essendo modificabile, fara' si che se esiste un file
Temp.class in una delle directory definite nel classpath, essa sara' caricata
solo la prima volta che si tentera' di farlo.
L'uso del metodo
loadClass(byte xx[]) permette di aggirare l'ostacolo; bisogna cosi':
Entrambe
le operazioni sono eseguite nella classe ScrapBook.
La procedura
di istanziazione dunque risultera' (vedi il metodo lancia della classe
ScrapBook):
CL cl = new CL();Il cuore dello Scrapbook e' chiaramente la riga:
Object o;
try{
Class c=cl.loadClass(f_a);
try{
try{
o=c.newInstance();
((Interfaccia) o).esegui();
}
catch (IllegalAccessException cv) {
u.stln("Accesso illegale");
}
}
catch (InstantiationException n) {
u.stln("errore di istanziazione");
}
}
catch (ClassNotFoundException e){
u.stln("classe non trovata");
}
((Interfaccia) o).esegui();
essa infatti permette di eseguire tutte le operazioni definite nel metodo esegui() della classe Temp.
In realta', credo che non siano necessarie tutte le operazioni di catch poiche' non si dovrebbero mai verificare i problemi descritti nelle loro clausole.
La classe ScrapBook governa lo sviluppo dell'applicazione: essa comprende i metodi:
|
||
|
||
MokaByte ricerca
nuovi collaboratori
|
||
|