MokaByte Numero 19 - Maggio 1998
 

 
Uno ScrapBook 
fatto in casa
di
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

 


 
 



Scrivo questo articolo sulla base delle esperienze maturate quando, ancora neofito iniziai a programmare in Java. Allora mi ritrovai a dover lottare con il mio compilatore che, per la troppa complessità di esecuzione non i permetteva di apprendere in maniera semplice e veloce. Misi a punto una serie di tecniche che nel tempo mi hanno risolto un sacco di problemi. Le espongo qui, nella speranza che possano essere di aiuto per qualcun altro





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:

La class Temp implementa l'interfaccia Interfaccia; cio' si rendera' necessario in seguito quando si dovra' eseguire il CS. L'interfaccia definisce solo il metodo

    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();
    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");
    }
Il cuore dello Scrapbook e' chiaramente la riga:

    ((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:

Per finire, esiste la classe C che ha il metodo main() che lancia la classe ScrapBook.
Il programmino permette di risparmiare un bel po' di tempo nella sperimentazione di porzioni di codice: al momento, mi piacerebbe risolvere alcuni problemi: Conclusione
Per il momento mi fermo qui, continuerò nella mia ricerca: se qualcuno, avesse trovato interessante il lavoro da me fatto, e proseguendo, sullo spunto delle idee da me proposte, dovesse trovare soluzioni o idee più interessanti, sarò ben lieto di accogliere critiche, suggerimenti o quant'altro.
Ovviamente ricordo che tale lavoro rappresenta più una sperimentazione che una effettiva produzione di codice funzionante.
 
  
 

MokaByte rivista web su Java

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