Rodar comando diariamente sem aplicação estar aberta

13 respostas
emailjavamysql
F

Meus caros, boa noite!

Gostaria de saber se é possível em Java ou no MySQL, executar um comando diariamente mesmo sem o programa estar aberto.
Tenho uma aplicação desktop em java.
Preciso conferir se uma data já foi ultrapassada todos os dias para depois estar enviando um email de alerta.
Exemplo:
Tenho a data 05/06/2017 cadastrada em um registro no banco. Preciso ver todos os dias se já foi ultrapassada essa data. Rodando hoje, ela estaria ultrapassada e alteraria o status de outra chave para EM ATRASO.
Depois iria enviar um email para alguém com alguma informação.

Tem como fazer isso, ou só é possível com a aplicação aberta mesmo?

13 Respostas

L

Você pode agendar trabalhos no sistema operacional, e isso vai mudar de SO pra SO. Esse job invocaria teu programa, e você faz o que tiver de fazer.

Eu desconheço uma maneira de fazer isso com Java e também gostaria de saber se existe. Acho muito difícil que haja.

EDIT: Dei uma pesquisada aqui e encontrei isso: What is the best solution to perform scheduled tasks in Java, whatever the OS?

O cara faz um if else para definir o sistema operacional, e a partir disso agenda o trabalho de acordo. Tem cheiro de gambiarra, mas não acho que seja problemático porque não é todo dia que surge um SO novo adotado em massa para você ter que adicionar mais uma cláusula na tua condição.

F

Obrigado pela atenção Lucas!
Eu também acho que seja praticamente impossível, já que o sistema fica fechado.
Mas como é feita essa verificação nos outros sistemas?

Fica uma instancia do programa aberta sempre no servidor usando Quartz?

L

Ele fez assim, no cliente:

// Pra descobrir o sistema operacional
final String osName = System.getProperty("os.name");
if (osName == null) {
    L.e("Unable to retrieve OS!");
} else if ("Mac OS X".equals(osName)) {
    currentOS = SupportedOS.MAC_OS;
} else if (osName.contains("Windows")) {
    currentOS = SupportedOS.WINDOWS;
} else {
    L.e("Unsupported OS: "+osName);
}

// Para agendar o job
switch (currentOS) {
        case MAC_OS:
            final String cron = new SimpleDateFormat("mm HH d M '*' ").format(when.getTime()) + alarmCL;

            commandLine = new String[] {
                    "/bin/sh", "-c",
                    "crontab -l | (cat; echo \"" + cron + "\") | crontab"
            };
            child = Runtime.getRuntime().exec(commandLine);
            break;

        case WINDOWS:
            commandLine = new String[] {
                    "schtasks",
                    "/Create",
                    "/ST "+when.get(Calendar.HOUR_OF_DAY) + ":" + when.get(Calendar.MINUTE),
                    "/SC ONCE",
                    "/SD "+new SimpleDateFormat("dd/MM/yyyy").format(when.getTime()), // careful with locale here! dd/MM/yyyy or MM/dd/yyyy? I'm French! :)
                    "/TR \""+alarmCL+"\"",
                    "/TN \""+getAlarmName(alarmId)+"\"",
                    "/F",
            };
            L.d("create command: "+Util.join(commandLine, " "));
            child = Runtime.getRuntime().exec(commandLine);
            break;
        }
F

Entendo, mas digo em outros sistemas, sem gambiarra.
É necessário a aplicação ficar sempre aberta no servidor né?

L

Reli tua pergunta e entendi diferente agora. Eu achei que você queria necessariamente executar uma tarefa no cliente diariamente. Como você tem a data no servidor (no banco de dados), pode agendar esse job no servidor mesmo.

Cria um job que chama um programa que consulta o banco e manda um email pra quem for necessário baseado na data.

L

Pode usar o cron mesmo, é algo bem simples. O sistema vai invocar a JVM com teu programa, e dali você faz o que precisar. Quando o programa terminar, a instância da JVM morre e só é invocada novamente no outro dia.

F

Que bacana Lucas!
É exatamente isso que precisava!
Tem algum material pra me indicar pra ler sobre isso?

L

Cara, eu aprendi num livro que eu tenho aqui, chamado “Your UNIX/Linux: The Ultimate Guide - 3rd Edition”, do Sumitabha Das. Eu tentei achar esse livro em PDF na época, há quase 2 anos, e ainda não tinha nenhum. Talvez tenha a segunda edição, que deve ser bem parecido. É extremamente didático, só precisei ler o que ele diz pra aprender a usar.

Mas tipo, o cron é um negócio bem comum no Linux, então deve ter bastante material bom pela Internet. Com certeza esse livro não é o único recurso bom. Como de costume, os melhores materiais estão em inglês:

Achei em português esses aqui:

F

No caso, quando disse Quartz me referi à uma biblioteca do Java que agenda tarefas.
Gostaria de ter o material sobre os Jobs no banco de dados.
Algo que o banco pudesse invocar todos os dias para verificar essa data e alterar o valor de outra chave.

L

Entendi, não sabia que o Quartz era uma biblioteca Java. Ele agenda o job no sistema operacional ou no próprio programa Java (como um Timer ou ScheduledExecutorService)?

Acho que também tem algo parecido em bancos de dados, porque isso é uma parada extremamente útil para fazer backups, por exemplo. Mas nunca estudei nada do gênero, não tenho o que recomendar.

F

Pelo que sei, ele agenda no próprio Java.
Mas o que necessito é estilo backup mesmo. Seria uma tarefa agendada diariamente.

Pelo que vejo, apenas com o programa aberto constantemente no servidor irei conseguir fazer isso.

L

Exatamente, se o job é agendado dentro do Java, o programa deve estar rodando para o job ser chamado. Inclusive, não sei se o Quartz lida com isso, mas se você reiniciar o programa, perde os jobs já agendados.

F

É complicado…

Vou ver se encontro alternativa para não precisar deixar o programa rodando.
Caso encontrar, posto aqui.
Obrigado Lucas!

Criado 7 de junho de 2017
Ultima resposta 7 de jun. de 2017
Respostas 13
Participantes 2