Las tareas programadas dentro de una aplicación nos pueden ayudar en gran medida, algunos ejemplos de uso son cuando nuestra aplicación genera una gran cantidad de logs, para no darle la responsabilidad al área de infraestructura, bien desde la aplicación de pueden borrar, otro ejemplo podría ser si queremos ejecutar una función dentro de la aplicación cada cierto tiempo, ya sea para sincronizar un proceso, para enviar data a la base de datos, entre otros.

En este laboratorio les enseñaré como podemos usar la clase Timer y hacer crear tareas programadas de una forma muy sencilla.

Este ejemplo lo vamos a realizar ejecutando un script .bat de windows desde la aplicación y luego escribiremos en un log el registro de la ejecución.

Primero debemos crear el script .bat que queremos ejecutar, en mi caso le pondré algo sencillo:

ipconfig

Luego crearemos un proyecto java application, dentro crearemos la siguiente estructura:

En la primera clase, Archive.java será la clase con la funcionalidad que necesitamos, extenderá de la clase TimerTask, a esta clase le importaremos las siguientes librerías:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.TimerTask;

Dentro de la clase vamos a sobrescribir el método run de la clase TimeTask, esto nos ayudará a ejecutar nuestro script .bat:

public class Archive extends TimerTask {

@Override 
public void run() {   //Sobreescribimos el método run
 try {         
    String linea;
    //Colocamos la ruta del archivo .bat que ejecutaremos
    Process p = Runtime.getRuntime().exec("C:\oracle\execute.bat");
    //Definimos un BufferedReader para leer la impresión que realice la ejecución de nuestro script
    BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));         
    while ((linea = input.readLine()) != null) {  
    //Mientras que nuestro input imprima data, imprimeremos la salida por consola        
       System.out.println(linea);         
    }         
      input.close(); //Cerramos el input
    } catch (Exception err) {         
      err.printStackTrace();     
    } 
  }

}

Ahora debemos crear la clase main, dentro de ella vamos a importar las siguientes librerías:

import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.logging.ConsoleHandler;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

Luego dentro de la clase main crearemos una variable final que se encargará de escribir nuestro log de registro:

protected final static Logger LOG_MONITOREO = Logger.getLogger("tareaprogramada");

Ahora bien dentro del método main vamos a colocar lo siguiente:

public static void main(String[] args) throws InterruptedException, IOException {
     System.out.println("Inicio exitoso de la aplicación!");

         Handler consoleHandler = new ConsoleHandler();
//Definimos la ruta donde se escribirá nuestro log y establecemos los métodos para la escritura
         Handler fileHandler = new FileHandler("C:\\oracle\\execute.log", 100000000, 1);
         SimpleFormatter simpleFormatter = new SimpleFormatter();
         fileHandler.setFormatter(simpleFormatter); 
         LOG_MONITOREO.addHandler(consoleHandler);
         LOG_MONITOREO.addHandler(fileHandler); 
         consoleHandler.setLevel(Level.ALL); 
         fileHandler.setLevel(Level.ALL);

//Instanciamos nuestra clase Timer
         Timer temporizador = new Timer();
        
        while (true) { /*El proceso se debe ejecutar infinitamente, ya que se debe validar que la hora sea la correcta en cada ciclo, se podría establecer para que después de cierto día se detenga, sin embargo para este ejemplo dejaremos infinito mientras se ejecute la aplicación*/

        //Estableceremos la hora, minutos y segundo en que queremos que se ejecute nuestro proceso
        Date dia = new Date();         
        Calendar hora7 = Calendar.getInstance();
        hora7.set(Calendar.HOUR_OF_DAY, 11); // 11 am del día
        hora7.set(Calendar.MINUTE,29); // Con 29 minutos
        hora7.set(Calendar.SECOND, 0); // Con 0 segundos

        Date horaEjecucion7 = hora7.getTime();   

        Thread.sleep(1000); /*En algunos casos me he dado cuenta que sin el sleep de un segundo, la ejecución de la tarea no funciona correctamente*/

        if (dia.toString().contains(horaEjecucion7.toString())) {//Verificamos si la hora actual es la hora de ejecución de la tarea
        LOG_MONITOREO.log(Level.INFO, dia + " Script de ARCHIVE Ejecutado");//Escribimos la ejecución en el log
        temporizador.schedule(new Archive(), horaEjecucion7); //Ejecutamos la tarea programada 
        }          
       /*Por último para evitar un crecimiento en el uso de la memoria de la aplicación, cada instancia la vuelvo a null en cada ciclo, así se mantiene la cantidad de memoria usada por la aplicación*/
        dia = null;
        hora7 = null;         
        horaEjecucion7 = null;     
    } 
}

Por último compilamos y ejecutamos nuestra aplicación, al ser la hora que hayamos colocado en el main.java se ejecutará el método run de la clase archive y nos generará un log con la fecha de ejecución y la salida del comando por consola según como lo programamos.

Impresión del comando por consola
Log de registro de la ejecución

Esta aplicación se desarrollo en un ambiente windows server, donde el programador de tareas por un error de windows no ejecutaba las tareas programadas correctamente, por ello se procedió a crear una solución como esta.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *