Cerca nel blog

Visualizzazione post con etichetta free. Mostra tutti i post
Visualizzazione post con etichetta free. Mostra tutti i post

lunedì 11 ottobre 2010


Abbiamo già parlato in un altro articolo dell'architettura della crittografia nel linguaggio Java.
Oggi proponiamo un esempio di come poter ottenere un Message Digest da un  testo in chiaro.



import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Main {

    public static void main(String[] args) {

        try {
            byte[] testoChiaro = "This is a test!".getBytes("UTF8");
            MessageDigest md = MessageDigest.getInstance("MD5");
            //visualizzo il provider utilizzato
            System.out.println("Provider:\n"+md.getProvider().getInfo());
            //cifro il messaggio
            md.update(testoChiaro);
            System.out.println("Message Digest:\n" + new String(md.digest(), "UTF8"));
        } catch (NoSuchAlgorithmException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }

    }
}

mercoledì 6 ottobre 2010

JCA-Java Criptography Architecture

Abbiamo già parlato di crittografia per quanto riguarda il linguaggio Java.
Ora parleremo di JCA, il framework di base per la crittografia, è costruito intorno alla J2SA(Java 2 Security Architecture).
Si basa sui principi della Criptography Service Provider Architecture:
  • indipendenza dell'implementazione(Algorithm indipendences)
  • interoperabilità
  • estendibilità
L'indipendenza dell'implementazione o Algorithm indipendences utilizza classi astratte di tipo "engines" che dichiarono le funzionalità di un dato tipo di algoritmo crittografico, impiega poi classi "provider" che implementano un certo insieme di funzionalità crittografiche per un Criptographic Service Provider(CSP).

In genere un'applicazione crittografica può richiedere genericamente un'implementazione di un dato algoritmo senza curarsi di quale provider lo fornisca, infatti una volta installati possono coesistere uno o più CSP anche di differenti produttori, il provider di default si chiama SUN ed è integrato nel JDK.
In Pratica:
  • Engine class: definiscea crypto service in an absract class senza implementazione
  • Service provider interface: provvede ad una crypto interface dell'applicazione via "engine"
Cryptographic service provider: ogni classe "engine" ha una corrispondente SPI che definisce esattamente un crypto method implementato da CSP. 

Principali engine class:
  • KEY: defisce le funzionalità condivise da chivi "opache"
  • KEY SPEC:definisce una chiave di tipo trasparente
  • KeyFactory:prende una chiave di tipo KEY "opaca" o "trasparente"
  • KeyPairGenerator:genera una coppia di chiavi assimentriche
  • AlgorithmParameters: gestisce i parametri di un algoritmo
  • AlgorithmParametersGenerator:genera i set di parametri di un algoritmo
  • MessageDigest:calcola l'hash di dati specifici
  • SecureRandom:genera numeri causali o pseudo casuali
  • Signature:appone e verifica la firma digitale
  • CertificateFactory:crea e revoca certificati di chiavi pubbliche
  • KeyStore:crea e gestisce un database(Keystore) di chiavi e certificati sicuri.
Il provider SUN include:un'implementazione dell'algoritmo DSA (Digital Signature Algorithm), un algoritmo MD5 e SHA-1 di MessageDigest, un KeyPairGenerator per DSA, AlgorithmParameter ed AlgorithmParameterGenerator per DSA, un KeyFactory per DSA, un CertificateFactory  per certificati X.509 e per CRLs, un'implementazione del KeyStore proprietario JKS.

Le estensioni JCE(Java Cryptographic Extension) e JSSE(Java Secure Sockects extension) implementano ed estendono le tecniche  crittografiche definite dalla JCA fornendo CSP alternativi a SUN.
Invece i restanti set di package offrono funzionalità di sicurezza aggiuntive e sono quindi complementari alla JCA.
  • JAAS:servizi di autenticazione, amministrazione e autorizzazione
  • CertPath:gestione dei certificati e catene di certificati
  • JGSS:meccanismi di comunicazione generici e specifici per beyberos v5

JCE
Java Cryptographic Extension
La JCE ha il compito di fornire  un'implementazione completa delle funzionalità di cifratura e decifratura dichiarate dalla JCA.
JCE offre supporto:
  • cifrari simmetrici a blocco e a flusso
  • cifrari asimmetrici
  • cifrari con password
applicazioni su:
  • Data
  • I/O streams
  • Serializable Object
in meccanismi quali:
  • MAC(Message Authentication Code)
  • KeyGenerator/KeyAgreement
JCA-Message Digest
Java Criptography Architecture offre la classe "engine" MessageDigest astratta che provvede a fare da design per offrire la funzionalità di cifratura di messaggi sicuri con algoritmo SHA-1 o MD5, questo messaggio criptato è detto: Message Digest o semplicemente indicato con MD.
Un message digest è un messaggio in chiaro di lunghezza variabile tradotto in un messaggio "sicuro" di lunghezza fissa.
Un MD ha due proprietà:
  1. se x->h(x), e y ed x sono diversi, non si può avere h(y)=h(x)
  2. non si possono avere collisioni 
Ad esempio in Internet è utilizzato MD5-128 bit che non garantisce nulla per quanto riguarda la collisione.
Le API Java sono:
  • MessageDigest.getInstance("MD5")  per ottenere un MD
  • .update(plaintext) per calcolare MD con il testo in chiaro
  • .digest() per leggere il message digest

JCA-Message Authentication Code(MAC)
MACs usa una chiave per preservare l'integrità del messaggio.JCA supporta gli algoritmi:
  • HMAC/SHA-1
  • HMAC/MD5
Le API Java sono:
  • KeyGenerator.getInstance("HMACMD5") e .generateKey() per generare la chiave
  • Mac.getInstance("HMACMD5") crea un oggetto MAC
  • .init(plaintext) e .doFinal() inizializza un MAC object
  • .update(plaintext) e .doFinal() calcolano il MAC object con testo in chiaro




lunedì 4 ottobre 2010

Java Cryptography

Il linguaggio Java divide la sicurezza in due livelli:
  • un livello basso di sicurezza JVM Layer:garbage collection,class file verification, etc.
  • un livello alto di sicurezza Application Layer:sandbox, security policy, security APIs, etc.
Fino a JDK 1.4 esistevono package esterni per creare applicazioni sicure:
  • JCE (Java Cryptography Extension)
  • JSSE (Java Secure Socket Extension)
  • JAAS (Java Authentication and Authorization Service)
Dalle versioni successive a JDK 1.4 sono state aggiunte due nuove funzionalità:
  • JGSS (Java General Security Service)
  • CertPath API (Java Certificate Path API)

JVM Layer



JVM Layer
JVM Layer: Java Virtual Machine
  • è responsabile dell'indipendenza della piattaforma
  • è responsabile della macchina astratta
  • ha un set di istruzioni
  • può manipolare la memoria a runtime
  • non interpreta il codice Java ma il bytecode
  • il bytecode è memorizzato nei class file
JVM Layer: Class file structure
Il class file è composto da:
  • da una "magic" costant OxCAFEBABE
  •  version number
  • Access flag
  • "costant pool"
  • Informazioni sulla classe corrente(nome, superclasse, etc.)
  • Informazioni a riguardo i metodi e le proprietà di una classe
  • Informazioni di Debbugging

JVM Layer: The Class File Verification
  • Verifica di base della struttura della classe
  • Verifica base del "looks" delle:
    referenze di classe
    referenze dei campi
    referenze sei simboli
  • Verifica del bytecode
  • Verifica effettiva:
    referenze di classi
    accesso e modifica dei campi e metodi chiamati

Application Layer
Application Layer:Class verification
  •  Il class loader carica le classi su richiesta
  • Riduce la memoria usata
  • Enforces type-safety alongside the JVM
  • Migliora il tempo di risposta del sistema
  • Istanze di classe caricate:
    Primordial/bootstrap class loader
    System class loader
    Application class loader
  • Il class loader è chiamato è chiamato dalla JVM
  • Il class loader è responsabile di caricare le classi e di dargli un namespace
  • Associa le classi caricate ad un dominio di protezione
Protection domain
  • associa i permessi alla classe per quanto riguarda le locazioni, i certificati, etc.
  • è definito dalla security policy
  • la security policy di default si riferisce al system-wide policy ed implementa la policy di default per la sandbox 
  • policy addizionali sono user-defined
  • si possono avere una o più policy security
  • tutte le referenze alla security policy sono specificate nel security property file localizzato nella directory di installazione del JDK(o JRE)

    Addio P2P: Come scaricare e ascoltare musica gratis sul pc!

    Dire addio a Emule, limewire ed affini è molto semplice , basta utilizzare un ottimo e semplice programma , Songr.

    Songr, un programma gratuito che permette di ascolare o scaricare le canzoni sul vostro pc gratuitamente! Come? utilizzando i più famosi motori di ricerca per mp3 come , 4shared.com, Hypster.com, Mp3Realm.org, etc etc.

    venerdì 23 luglio 2010

    File e Directory in Linux

    I file possono avere un nome costituito da caratteri alfabetici, di sottolineatura o numerici, possono includere punti e virgola. Tuttavia il nome di un file non può iniziare con un punto se non in casi particolari. la lunghezza massima di un nome può essere di 256 caratteri. Linux organizza i file in un insieme di directory in modo gerarchico. Una directory a sua volta può contenere files o altre directory. Una struttura di questo tipo di solito viene definita struttura ad albero.






    Comandi di visualizzazione dei file
    Per visualizzare il contenuto di un file si utilizzano i comandi cat e more.
    Il comando cat visualizza in una sola volta tutto il contenuto del file anche se questo non è possibile visualizzarlo interamente nella finesta di shell. Oltrettuto nel momento in cui il contenuto del file viene visualizzato questo scorre velocemente a schermo rendendo impossibile la lettura. Per ovviare a questi spiacevili inconvenienti è stato pensato il comando more. Il comando more visualizza il file non tutto insieme ma a poco alla volta chiedendoci di premere il tasto " f " o la BARRA SPAZIATRICE per visualizzare la parte successiva del file. Inoltre con è possibile rivedere parti del file già visualizzate premendo il tasto " b " e per uscire dalla visualizzazione del file prima che esso sia finito si può premere il tasto " q ".

    Esempio: 
       joaquin@joaquin-laptop:~$ more /media/hda5/architetture\ software.odt


    Comandi di stampa
    Per mandare in stampa un file alla stampante collegata al sistema si utilizza il comando lpr seguito dal path del file da stampare, mentre per annullare la stampa di un file basta utilizzare il comando lprm seguito dal file da annullare.
    Esempio:
       joaquin@joaquin-laptop:~$ lpr /media/hda5/architetture\ software.odt (manda in stampa il file)
       joaquin@joaquin-laptop:~$ lprm /media/hda5/architetture\ software.odt (annulla la stampa del file)
    I processi di stampa vengono inseriti in una coda e vengono stampati uno alla volta in background, quindi durante la stampa è possibile continuare altre attività. Con il comando lpq è possibile visualizzare tutti i job in coda, il proprietario di un job di stampa, l'identificativo del job di stampa, la dimensione in byte e il file temporaneo a cui fa riferimento il job di stampa. 


    Comandi per la gestione delle directory
    Per creare una directory si utilizza il comando mkdir per eliminarne una il comando è rmdir, mentre per cambiare la directory di lavoro si utilizza il comando cd tutti questi comandi accettano come argomento il percorso della directory.

    Comandi per gestire i file
    Quando il numero dei file memorizzati diventano molti diventa difficiel ricordarsi in che punto del filesystem un determinato file sia memorizzato, quindi Linux mette a disposizione alcuni comandi molto utili per la gestione dei file. I comandi di cui stiamo parlando sono i comandi per ricercare,copiare rinominare e cancellare un file. Il comando cp permette di copiare i file, il comando mv che rinomina o sposta il file, il comando rm che cancella un file infine il comando ln che aggiunge un nuovo nome al file. In pratica aggiungere un nuovo nome ad un file permette ad un file di avere più nomi, questo permette di accedere a un file da un'altra directory, i nomi aggiunti vengono detti link. Esistono due tipi di link: fisici e simbolici.
    Per ricercare un file si ha a disposizione il comando find, questo comando accetta come argomento uno o più nomi di directory seguiti da opzioni che specificano il tipo e i criteri della ricerca, la ricerca di un file avviene nelle direcotory elencate e nelle subdirectory. Il comando find può eseguire anche ricerche sulla base del nome, del tipo, del proprietario e della data dell'ultimo aggiornamento.

    Permessi di accesso ai file
    In Linux ogni file e directory ha i proprio permessi di accesso che specificano quali utenti possono accedere al file e in che modalità. Si può permettere l'accesso ai file a tre tipi di categorie di utenti:

    1. Il proprietario
    2. Il gruppo
    3. Tutti gli "altri"

    Per file e directory è possibile definire i permessi di:
    • Scrittura
    • Lettura
    • Esecuzione

    Per ognuna delle categorie di utenti prima specificate vi sono permessi di scrittura, lettura ed esecuzione distinti che controllano la modalità di accesso da parte del proprietario, del gruppo e di tutti gli "altri utenti".



    Facendo riferimento all'immagine precedente si può notare che:
    • Il primo carattere è " - " questo perchè è un file comune in caso di directory avremmo trovato il carattere " d "
    • Per i permessi del proprietario leggiamo i primi tre carattere subito dopo il carattere che ci indica se il file è una directory oppure no. Come si può vedere il proprietario ha accesso in lettura(r), in scrittura(w) e in esecuzione(x).
    • Per la modalità di accesso del gruppo facciamo riferimento ai tre caratteri subito dopo quelli relativi al proprietario. Anche il gruppo ha modalità di accesso in lettura,scrittura ed esecuzione.
    • Gli ultimi tre caratteri indicano la modalità di accesso per tutti gli altri utenti del sistema. Per questo file i restanti utenti non hanno nessun permesso di accesso.

    Per modificare la configurazione dei permessi si deve utilizzare il comando chmod.

    Comandi per l'archiviazione dei file
    Il comando o come molto più spesso viene indicato programma di servizio tar crea degli archivi contenenti file e directory. Il comando tar viene utilizzato per creare archivi su i vari dispositivi o file. Si può chiedere al comando tar di creare un archivio su un dispositivo utilizzando l'opzione f e il nome del ispositivo o file. La signature del comando può essere questa:

    tar -opzioni f nome_archivio.tar directory_e_file

    opzione descrizione
    c crea un archivio
    vvisualizza l'esecuzione del comando sulla shell
    xestrae un archivio ricostruendo l'albero delle directory
    dtrova le differenze tra due archivi
    raggiunge un file all'archivio

    ci sono molte altre opzioni per conoscerle tutte basta utilizzare il comando man tar.   

    martedì 13 luglio 2010

    Linux file system proc

    Il process file system di Linux comunemente noto come filesystem /proc, è un filesystem particolare che il sistema genera nella memoria, di conseguenza non è scritto sul disco e viene generato ogni volta che il sistema viene avviato. Questo filesystem offre delle informazioni riguardanti il sistema, quindi i file /proc si possono considerare a tutti gli effetti interfacce con il kernel. Le subdirectory e file /proc sono elencati nella tabella sottostante:

    File Descrizione
    /proc/#num Una directory per ogni processo in esecuzione sul sistema, per esempio il processo con identificativo 1(processo init) è rappresentato da /proc/1.
    /proc/cpuinfo Offre informazioni sulla CPU:tipo,modello, marca ed prestazioni.
    /proc/devices Elenco dei driver configurati per il Kernel, in esecuzione in quel momento.
    /proc/dma Visualizza i canali DMA.
    /proc/filesystem Filesystem configurati nel Kernel.
    /proc/interrupts Visualizza gli interrupts in uso.
    /proc/ioports Mostra le porte di I/O in uso.
    /proc/kcore Immagine della memoria fisica.
    /proc/kmsg Messaggi generati dal kernel.
    /proc/ksyms Tabella dei simboli per il kernel.
    /proc/loadavg Visualizza il carico del sistema.
    /proc/meminfo Informazioni sull'utilizzo della memoria.
    /proc/modules Elenca i moduli del kernel caricati.
    /proc/net Restituisce informazioni sullo stato dei protocolli di rete.
    /proc/stat Statistiche operative sul sistema.
    /proc/uptime Periodo di attività del sistema.
    /pric/version Restituisce la verisone del kernel utilizzata.

    Questo filesystem come si può capire è molto utile, infatti permette a programmi di accedere a informazioni sul sistema leggendo semplicemente dei file. Un esempio classico è il comando ps che elenca tutti i processi in esecuzione sul sistema. Ecco alcuni esempi.
    La versione del mio kernel:

    Informazioni sulla CPU che sto utilizzando:

    venerdì 9 luglio 2010

    Tree Directory Linux

    L'albero delle directory di Linux si presenta molto diverso da quello di Windows. Una delle differenze sostanziali tra Windows e Linux, è che Windows utilizza una directory per ogni programma che istalliamo, mentre Linux presenta un albero di directory(tree directory) molto più complesso. L'albero delle directory può essere diviso in più parti, ognuna delle quali puù risiedere sulla sua partizione del disco. Questa suddivisione aggevola l'utente nelle operazioni di backup e nell'amministrazione, inoltre questa struttura è molto utile in una rete di PC Linux, che condividono delle parti del filesystem su dispositivi a solo lettura.


    L'albero di directory Linux si presenta nel seguente modo:

    /
    +---bin
    +---boot
    +---etc
    +---home
    +---+---users1
    +---Desktop
    +---+---users2
    +---+---users3
    +---Desktop
    +---+---users_n
    +---proc
    +---sys
    +---usr
    +---lib
    +---dev
    +---var
    +---media
    +---sbin
    +---mnt
    +---opt

    / è la directory principale.
    /bin contiene i programmi di base per interagire con il sistema operativo. Per intenderci sono i comandi che digitiamo sulla shell.
    /boot contiene i file per la fase di boot del sistema.
    /etc contiene i file di configurazione del sistema, e sono specifici per ogni sistema.
    /home è la directory home di ogni utente eistente nel sistema. ad esempio sul mio sistema esiste una directory /home/joaquin .
    /proc è una dirctory virtuale o meglio è un filesystem virtuale per ottenere informazioni sul sistema. Per esempio prvate a dare il seguente comando da shell cat /proc/cpuinfo per ottenere tutte le info sulla vostra cpu, oppure il comando cat /proc/version per controllare la versione del kernel Linux che utilizzate.
    /sys è una directory virtuale per estrarre informazioni del sistema.
    /usr è definita da molti una gerarchia secondaria. In effetti essa contiene molte directory come quelle presenti nella radice principale. questa directory contiene tutti i programmi utenti, le librerie, e la docuemntazione
    /lib contiene le librerie e i moduli fondamentali per il fuzionamento del sistema alcune di queste librerie sono anche condivise da più software.
    /dev contiene i file dei dispositivi.
    /var dati variabili
    /media è il punto di montaggio per i dispositivi mobili.
    /sbin contiene file binari essenziali per il sistema.
    /mnt punto di montaggio per file system temporane.
    /opt pacchetti e software opzionali.

    mercoledì 7 luglio 2010

    Thread Java

    Il linguaggio Java supporta i Thread mettendo a disposizione degli sviluppatori
    la classe Thread oppure è possibile implementare l'interfaccia Runnable.
    Nel caso si decide di utilizzare la classe Thread per far si che il thread esegua quelle che si vuole bisogna fare l'override del metodo run(), un modo alternativo per implementare i threads è quello di creare una classe che implementa
    l'interfaccia Runnable e definire quindi il metodo run(), poi si deve passare come parametro un'istanza di tale classe al costruttore della classe Thread.
    In entrambi i modi di implementare i thread il corpo del thread stesso risiede nel metodo run().


    LifeCycle

     

    Come si può notare dalla figura i thread si possono trovare in quattro diversi stati
    1. Nuovo
    2. Eseguibile(o runnable)
    3. Bloccato
    4. Concluso
    Ora vediamo cosa significano i quattro stati in cui un thread si può trovare.
    • Nuovo:il thread è in questo stato quando grazie all'operatore new si crea un nuovo thread per esempio new Thread(t) dove t è un oggetto di una classe che implementa l'interfaccia Runnable.
    • Runnable:dopo aver chiamato il metodo start() il thread si trova nello stato eseguibile(o runnable), anche se effettivamente non sia detto che questo sia in esecuzione magari perchè il sistema operativo non l'abbia ancora schedulato. Quindi ci si deve ricordare che quando un thread è nello stato runnable non è detto che esso sia davvero in esecuzione.
    • Bloccato:un thread si può trovare nello stato bloccato quando:




      • Il thread è sospeso da una chiamata del metodo sleep()
      • Il thread è bloccato nell'attesa di completamento di un richiesta di I/O
      • Il thread tenta di ottenere l'accesso(lock) ad una risorsa condivisa detenuta da un altro thread
      • Il thread attende che si verifichi una particolare condizione
      Quando un thread è bloccato rilascia la CPU, e il sistema operativo può quindi schedulare un altro thread pronto per essere eseguito.
      Il thread sospeso ritorna nello stato runnable solo quando la condizione che l'ha portato nello stato bloccato cessa di esistere quindi:




      • Quando i millisecondi indicati nella chiamata del metodo sleep() sono terminati
      • Quando si conclude l'operazione di I/O richiesta
      • Quando riesce ad ottenere il lock alla risorsa condivisa
      • Quando la condizione che aspettava si è verifica
      Quindi un thread bloccato può ritornare nello stato eseguibile solo ripercorrendo lo stesso percorso che l'ha portato nello stato bloccato.
    • Concluso:un thread può concludersi perchè il codice del metodo run() viene eseguito tutto e quindi il metodo stesso termina, oppure perchè un'eccezione non catturata termina il metodo run(). Per interrompere un thread si può utilizzare il metodo stop(), mentre per verificare se un thread è nello stato eseguibile o bloccato si può utilizzare il metodo isAlive() che ritorna il valore true se il thread è appunto eseguibile o bloccato, mentre ritorna il valore false se il thread non è ancora runnable o concluso.


    Proprietà dei thread

    • Priorità dei thread:Nel linguaggio Java ogni thread ha una priorità è possibile aumentare o diminuire questa priorità utilizzando il metodo setPriority(int newPriority), si può impostare la priorità con un valore compreso tra MIN_PRIORITY(definito come 1 nella class Thread) e MAX_PRIORITY(definito come 10 nella class Thread). Tuttavia si deve tener conto che la priorità dei thread è molto legata al sistema operativo, quindi la priorità viene mappata rispetto ai livelli di priorità del sistema operativo ospite, questi livelli possono essere diversi da quelli definiti dal linguaggio Java si dovrebbe evitare quindi di strutturare programmi che funzionano con la priorità dei thread.
    • Thread demoni:un thread può essere trasformato in un demone chiamando il metodo setDaemon(true) un thread di questo tipo ha lo scopo di servire altri thread.
    • Gruppi di thread:il linguaggio Java permette di classificare i thread di uno stesso programma in gruppi, ciò è possibile grazie alla classe ThreadGroup.
      Esempio:




      ...

      String nomeGrupp="pippo";

      ThreadGroup g=new ThreadGroup(nomeGruppo);

      Thread t=new Thread(g,"nomeThread");

      ...
    Vediamo alcuni semplici esempi di thread:


    public class ExampleThread extends Thread {

         public ExampleThread(String name) {

           super(name);

         }

         public void run() {

           for (int i = 0; i < 100000; i++) {

             System.out.println(this.getName()+" "+i+" volte");

           }

         }



         public static void main(String[] args) {

           ExampleThread t = new ExampleThread("ExampleThread");

           t.start();

           for (int i = 0;i<1000000;i++)

             System.out.println("Main "+i+" volte");

          }

         }



    Vediamo invece ora l'implementazione di Runnable


    public class ExampleRunnableThread implements Runnable {
         public void run() {

           for (int i = 0; i < 100000; i++) {

              System.out.println(Thread.currentThread().getName() + " " + i + " volte");

           }

         }


         public static void main(String[] args) {

           ExampleRunnableThread r = new ExampleRunnableThread();

           Thread t=new Thread(r);

           t.setName("ExampleRunnable thread");

           t.start();

           for (int i = 0;i<1000000;i++)

             System.out.println("Main "+i+" volte");

         }

         }


    I due esempi illustrati dovrebbero mostrarvi come la CPU per un certo periodo esegue il thread main e per un certo intervallo l'altro thread con un'alternanza dei due thread.

    martedì 6 luglio 2010

    La riflessione in Java

    La riflessione Java è uno strumento potente, per scrivere programmi che possono elaborare dinamicamente il codice Java. Un programma è riflessivo se è in grado di analizzare le funzionalità delle classi. La riflessione Java è uno strumento utilizzato sopratutto da coloro che realizzano strumenti per lo sviluppo. Iniziamo la nostra navigazione all'interno delle classi che la libreria standard Java ci mette a disposizione per utilizzare questo potente strumento.


    Le classi che permettono di utilizzare la riflessione sono:
    • Class
    • Constructor
    • Field
    • Method

    Class
    Quando un programma è in esecuzione il sistema runtime di Java mantiene il tipo in runtime degli oggetti. Questa informazione è utilizzata dalla Java Virtual Machine per la selezione del metodo corretto. Per accedere a questa informazione si utilizza il metodo getClass() della classe Object che restituisce un'oggetto della classe Class.
    Un esempio di come ottenere il tipo a runtime di un oggetto:


    import java.util.LinkedList;

    import java.util.List;

    public class Riflessione {

       public static void main(String[] arg){

         try {

          List<String> l = new LinkedList<String>();

          Class c = l.getClass();

          System.out.println(c);

          String name = "java.util.ArrayList";

          Class cl = Class.forName(name);

          System.out.println(cl);

         }

         catch (ClassNotFoundException ex) {

          System.out.println(ex.getMessage());

         }

       }

    }


    Dal codice si può notare che oltre ad utilizzare il metodo getClass() della classe Object per ottenere un oggetto della classe Class, si può utilizzare anche il metodo statico forName() della classe Class passando a tale metodo una stringa che deve essere un nome valido di una classe o di una interfaccia, altrimenti il metodo genera un'eccezione verificata ClassNotFoundException. Un altro metodo molto utile della classe Class è newIstance(), questo metodo utilizzato in combinazione con il metodo forName() permette di creare un ogetto dal nome contenuto nella stringa che si passa al metodo forName()


    String name = "java.util.Date";

    Object o=Class.forName(name).newInstance();


    I due metodi utilizzati in combinazione come nell'esempio precedente possono generare due eccezioni verificate InstantiationException e IllegalAccessException.

    Field,Method e Constructor
    Le classi Field,Method e Constructor sono tutte classi che fanno parte del pacchetto java.lang.reflect queste classi descrivono ripettivamente i campi, i metodi e i costruttori di una classe.

    La classe Field ha un metodo getType() che ritorna anch'esso un oggetto della classe Class relativo al tipo del campo che descrive. La classe Method ha alcuni metodi utilissimi tra i quali getName() che ritorna un oggetto di tipo String che descrive il nome del metodo, il metodo getParameterTypes()

    che ritorna un array di oggetti ancora una volta di tipo Class che rappresenta il tipo dei parametri formali inseriti nel vettore secondo l'ordine in cui sono scritti nella signature del metodo, l'array può avere un numero di elementi uguale a 0, in questo caso significa che il metodo rispettivo non ha parametri.Il metodo getReturnType() ritorna un oggetto di tipo Class che rappresenta il tipo di ritorno del metodo. Il metodo getExceptionTypes() ritorna anch'esso un array di tipo Class e contiene tutte le eccezioni che il metodo specifica nella clausola throws, la dimensione di questo array può essere 0 se il metodo non specifica eccezioni.
    La classe Constructor specifica tra i metodi anch'essa il metodo getParameterTypes() ma in questo caso gli elementi dell'array che ritorna il metodo, identificano i parametri che il relativo costruttore richiede, naturalmente questo array di ritorno può avere 0 elementi.
    Tutte le classi descritte specificano un metodo getModifiers() questo metodo restituisce un intero con un insieme di bit di stato posti ad on/off per indicare i modificatori utilizzati per il rispettivo metodo, campo o costruttore a cui il metodo è applicato. I metodi della classe Class getFields(),getMethods() e getConstructors() ritornano rispettivamente array dei campi, dei metodi e dei costruttori pubblici e tutti i membri pubblici della superclasse, metre i metodi getDeclaredFields(),get DeclaredMethods() e getDeclaredConstructors() restituiscono array costitutiti da tutti gli attributi, metodi e costruttori dichiarati nella classe, anche i membri privati e protetti, ma non i membri della superclasse.

    Cron


    Nei sistemi Unix e nei sistemi Linux di consegueza è un potente strumento per la pianificazione
    delle operazioni da eseguire in determinati istanti che può non essere nell'immediato, oppure per eseguire operazioni ad intervalli di tempo regolari.
    Lo strumento di cui staimo parlando è cron. Il comando crontab consente lo scheduling di comandi e/o operazioni, cioè registra i comandi presso il sistema operativo
    affinchè siano mandati in esecuzione nell'istante di tempo specificato. Il crontab è un semplice file di testo contenente appunto i comandi registrati presso il sistema.
    Per eseguire i comandi registrati presso il sistema, in background gira un demone chiamato cron che elabora il file crontab ed esegue i comandi in background nel sistema, un comando mandato in esecuzione da cron è detto cronjob.
    Entriamo in dettaglio:i files crontab contengono la lista dei job che il demone elabora e decide se un comando deve essere mandato in esecuzione.
    Ecco come si presenta un crontab lanciato con il comando crontab -e:
    Come si può vedere dall'immagine abbiamo una prima riga che è composta nel modo seguente:

    # m h dom mom dow command

    I primi cinque campi permettono di specificare la frequenza con cui eseguire il sesto campo cioè il campo in cui è specificato il comando da eseguire.
    Vediamo in dettaglio ogni campo cosa indica e che valori può assumere:

    CampoCosa indica e range di valori
    mminuti (0-59)
    hore (0-23)
    domgiorno del mese (1-31)
    mommese (1-12)
    dowgiorno della settimana (0 - 7) (domenica = 0 oppure 7)
    commandcomando da eseguire


    Ogni campo può specificare valori multipli utilizzando alcuni operatori, gli operatori sono:

    OperatoreCosa specificaEsempio
    operatore ','permette di specificare una sequenza di valori1,5,7,8
    operatore '-'permette di specificare un'intervallo di valori13-20
    operatore '*'permette di specificare tutti i possibili valori per un campo
    operatore '/' (supportato solo da alcune estensioni del demone)permette di saltare un certo numero di valorise nel campo ora specifichiamo "*/4" indicherà i valori "0,4,8,12,16,20"


    Vediamo ora qualche esempio di comando:
    mhdommomdowcommand
    0803***rm -r /home/joaquin/prova/
    il comando specifica che alle ore 03:08 di notte di ogni giorno dell'anno si vuole svuotare il contenuto della directroy prova.

    Se invece volessimo far eseguire lo stesso comando tutti i giorni ogni due ore:
    mhdommomdowcommand
    **/2***rm -r /home/joaquin/prova/

    Se vogliamo che il comando venga eseguito alle ora 17:00 dal 4 al 15 maggio ma anche il lunedì allora il comando dovrà essere:
    mhdommomdowcommand
    0174-1551rm -r /home/joaquin/prova/

    È possibile specificare di voler eseguire può comandi utilizzando l'opertore ; nel campo comand
    mhdommomdowcommand
    [0-59][0-23][1-31][1-12][0-7]comando_1;comando_2;comando_3

    mentre se vogliamo eseguire un comando solo se un primo comando va a buon fine allora dovremmo usare l'operatore && e la sintassi è la seguente:
    mhdommomdowcommand
    [0-59][0-23][1-31][1-12][0-7]comando_1 && comando_2


    Diamo ora un'occhiata alle opzioni con cui il comando cronotab
    ComandoopzioneCosa indica
    crontab-epermette di modificare il crontab corrente
    crontab-lpermette di visualizzare il crontab corrente nell'output standard
    crontab-rpermette di rimuovere il crontab corrente