Visualizzazione post con etichetta Batch java. Mostra tutti i post
Visualizzazione post con etichetta Batch java. Mostra tutti i post

lunedì 1 settembre 2014

Creare eseguibili schedulati con Quartz

Vai all'indice

L'obiettivo di questo post è creare un'applicazione batch eseguibile schedulata. Per fare questo ho inserito la libreria Quartz nell'esempio descritto nel post precedente, per cui lanciando il processo il risultato dell'elaborazione sarà lo stesso, ma ripetuto ad un intervallo di tempo prestabilito.
Quartz è una libreria open source che permette di schedulare, ovvero pianificare, i processi da una qualsiasi applicazione java. Per fare questo Quartz utilizza la stessa sintassi utilizzata dal crontab di Linux.





Per prima cosa creo un nuovo Java project (File>New>Java project) con Eclipse e definisco un pacchetto prova. Clicco sull'icona di progetto col tasto destro e seleziono Properties dal menù. Mi posiziono sulla scheda Libraries dalla voce Java Build Path ed importo le librerie nel classpath come riportato nella figura.



A questo punto definisco una nuova classe HelloJob.java ed inserisco il codice creato nel post precedente (il test sulle classi String, StringBuilder e StringBuffer).


package prova;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class HelloJob implements Job
{
private static StringBuilder oString = new StringBuilder(""); 
public void execute(JobExecutionContext context)
throws JobExecutionException {

   long start=System.currentTimeMillis();
   testString();
   long end=System.currentTimeMillis();
   oString.append("Tempo di esecuzione testString() "+(end-start)+" millis.\n");
   
   start=System.currentTimeMillis();
   testStringBuffer();
   end=System.currentTimeMillis();
   oString.append("Tempo di esecuzione testStringBuffer() "+(end-start)+" millis.\n");
   
   start=System.currentTimeMillis();
   testStringBuilder();
   end=System.currentTimeMillis();
   oString.append("Tempo di esecuzione testStringBuilder() "+(end-start)+" millis.\n");
  
   File file = new File("output.txt");
    try {
    FileWriter fw = new FileWriter(file);
    fw.write(oString.toString());
    fw.flush();
    fw.close();
    } catch (IOException e) {                        
    System.out.println(e);         
    }  
    }  

 private static void testString() {
   String x = "";
   for(int i=0;i<15000;i++){
     //operazione di append
     x+=i;
   }
 }

 private static void testStringBuffer() {
   StringBuffer x = new StringBuffer("");
   for(int i=0;i<15000;i++){
     //operazione di append
     x.append(i);
   }
 }

 private static void testStringBuilder() {
   StringBuilder x = new StringBuilder("");
   for(int i=0;i<15000;i++){
     //operazione di append
     x.append(i);
   }
 }  

}


Definisco la classe Prova.java come entry point. All'interno del metodo main inserisco il codice per l'esecuzione del CronTrigger di Quartz, che tramite un'espressione tipica di Unix ci consente di specificare le date e gli orari in cui eseguire il job.


package prova;

import org.quartz.CronScheduleBuilder;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.core.*;
import org.quartz.Scheduler;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;

public class Prova  implements Job{

    public static void main( String[] args ) throws Exception
    {
   
    JobDetail job = JobBuilder.newJob(HelloJob.class)
.withIdentity("dummyJobName", "group1").build();

    Trigger trigger = TriggerBuilder
.newTrigger()
.withIdentity("dummyTriggerName", "group1")
.withSchedule(
CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))
.build();

    //schedulo
    Scheduler scheduler = new StdSchedulerFactory().getScheduler();
    scheduler.start();
    scheduler.scheduleJob(job, trigger);

    }

@Override
public void execute(JobExecutionContext arg0) throws JobExecutionException {
// TODO Auto-generated method stub

}
}


In sostanza il codice costruisce un job partendo dalla classe HelloJob e la manda in esecuzione ogni 5 secondi. La riga che determina la pianificazione è:
CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))

Per comprenderla vi consiglio di cercare su Google documentazione sul Crontab di Linux.
Terminata la stesura del codice ho salvato il progetto come Jar eseguibile e creato il file .exe utilizzando Launch4j come descritto nel post precedente.
Lanciando l'eseguibile, il processo ogni 5 secondi accoda nel file output.txt un nuovo report sui tempi di esecuzione delle tre classi String, StringBuffer e StringBuilder.

Nota per chi testasse questo esempio; Una volta lanciata l'esecuzione vi consiglio di terminare il processo javaw tramite  la scheda Processo del pannello di Gestione Attività, in caso contrario il processo continuerà a ciclare fino allo spegnimento del pc.

Hai apprezzato questo post? Conferma le mie competenze o scrivi una segnalazione sul mio profilo Linkedin!

martedì 26 agosto 2014

Creare eseguibili Windows con Java

Vai all'indice

Una delle necessità apparentemente banali, ma che possono avere una soluzione non immediata, è la creazione di programmi java eseguibili da un pc Windows.
La prima cosa da fare è aprire Eclipse e creare un nuovo Java project (File>New>Java project). All'interno della cartella src creo un pacchetto "prova" nel quale definisco il file Main.java e inserisco il codice:


package prova;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;


public class prova {

   private static StringBuilder oString = new StringBuilder(""); 
   

   public static void main(String[] args) {

       long start=System.currentTimeMillis();
       testString();
       long end=System.currentTimeMillis();
       oString.append("Tempo di esecuzione testString() "+(end-start)+" millis.\n");
       
       start=System.currentTimeMillis();
       testStringBuffer();
       end=System.currentTimeMillis();
       oString.append("Tempo di esecuzione testStringBuffer() "+(end-start)+" millis.\n");
       
       start=System.currentTimeMillis();
       testStringBuilder();
       end=System.currentTimeMillis();
       oString.append("Tempo di esecuzione testStringBuilder() "+(end-start)+" millis.\n");
  
       File file = new File("output.txt");
        try {
           FileWriter fw = new FileWriter(file);
           fw.write(oString.toString());
           fw.flush();
           fw.close();
        } catch (IOException e) {                        
           System.out.println(e);         
        }         
    }            

        private static void testString() {
          String x = "";
          for(int i=0;i<15000;i++){
            //operazione di append
            x+=i;
          }
        }
        
        private static void testStringBuffer() {
          StringBuffer x = new StringBuffer("");
          for(int i=0;i<15000;i++){
            //operazione di append
            x.append(i);
          }
        }
        
        private static void testStringBuilder() {
          StringBuilder x = new StringBuilder("");
          for(int i=0;i<15000;i++){
            //operazione di append
            x.append(i);
          }
        }        




   }



L'obiettivo è creare un eseguibile java, quindi è indifferente il codice da utilizzare nella classe Main. Ne approfitto per introdurre le classi StringBuilder e StringBuffer, molto utili per gestire stringhe di caratteri. Esse ereditano le caratteristiche dalla classe madre String, ma sono più performanti e permettono operazioni sulle stringhe più veloci e meno onerose in termini di utilizzo della memoria. L'unica classe Main del progetto definisce ed esegue tre metodi che ciclando su tre oggetti delle classi String, StringBuilder e StringBuffer ne mostrano le performance. Il risultato è salvato in un oggetto StringBuilder e scritto nel file di testo output.txt.

Per salvare il progetto come Jar eseguibile è sufficiente cliccare col tasto destro sull'icona di progetto nella finestra dei progetti, selezionare l'opzione Runnable Jar file e seguire la procedura guidata, inserendo il nome del progetto ed il path di destinazione come descrive l'immagine.



A questo punto il file Jar ottenuto può essere eseguito in diversi modi: da linea comando o tramite script .bat su Windows o .sh su Linux.
Io ho preferito incorporare l'archivio Jar in un file .exe utilizzando Launch4j, un programma scaricabile dal sito http://launch4j.sourceforge.net .
Launch4J è uno strumento cross-platform per la creazione di applicazioni eseguibili su Windows partendo da applicazioni Java distribuite come Jar. L'eseguibile deve essere configurato per essere elaborato con la versione JRE disponibile nel proprio pc. Launch4J fornisce anche un'interfaccia user friendly tramite la quale è possibile impostare le opzioni di runtime, come la dimensione iniziale, l'heap-size massimo ecc... E' anche possibile assegnare un'icona di applicazione.


Installato e aperto Launch4j appare un'interfaccia a schede. Nella scheda Basic è necessario inserire il path dove si trova il file jar da convertire ed il path dove andrà creato il file exe di destinazione. Nella scheda JRE impostare la versione utilizzata per il progetto. A questo punto compilare il progetto cliccando il tasto ingranaggio ed eseguirlo col tasto play, o in alternativa un doppio click sul file eseguibile appena creato. Questo è solo un esempio basilare, come potete notare l'interfaccia è ricca di schede e parametri.


Il risultato dell'elaborazione è la creazione del file di testo output.txt contenente i tempi di esecuzione delle tre classi. Solo per curiosità, è interessante notare che le classi StringBuffer e StringBuilder hanno tempi di esecuzione molto più bassi della classe String.


Tempo di esecuzione testString() 2576 millis.
Tempo di esecuzione testStringBuffer() 5 millis.
Tempo di esecuzione testStringBuilder() 4 millis.


Nel prossimo post: Creare eseguibili schedulati con Quartz.

Hai apprezzato questo post? Conferma le mie competenze o scrivi una segnalazione sul mio profilo Linkedin!