O objetivo do Jnotify é notificar (como o próprio nome já sugere) sobre alguma alteração ocorrida em determinado diretório que está sendo monitorado. Isto é muito útil em situações em que precisamos saber quando alguém alterar determinado arquivo, deletar, criar ou modificar. Há inúmeras situações onde a biblioteca Jnotify pode ser aplicada, até mesmo em comunicação de sistemas totalmente distintos.
Imagine a seguinte situação: Você tem um sistema que funciona em COBOL e outro em Java, quando uma informações for inserida no sistema em COBOL você gostaria de replicar imediatamente essa informação em Java, como fazer isso ? (Esqueça Webservice). Uma solução é escrever os dados em um arquivo TXT, XML ou qualquer de sua preferência através do COBOL, e deixar o Java monitorando esse diretório através do Jnotify. Assim quando um dado for inserido no sistema em COBOL, ele escreverá um arquivo chamado “dado001.txt” e o Java capturará esse arquivo “dado001.txt” e irá fazer a inserção no banco, tudo automático sem interação homem-máquina, ou seja, essa é literalmente uma interação máquina-máquina.
Configurando Jnotify
Para este artigo utilizaremos a biblioteca Jnotify para o Linux 64bits (disponibilizada na seção de downloads deste artigo). Vamos ao passo a passo:
- Baixe a biblioteca libjnotify.so disponível na seção de downloads deste artigo.
- Coloque a libjnotify.so no diretório “/usr/lib/java/”.
- Crie um novo projeto Java no eclipse e crie também uma classe chamada Myjnotifyapp.java.
- Vá no menu Run -> Run Configurations...
- Na tela que abriu clique no ícone para adicionar uma nova configuração, assim como mostrado na figura 1.
Em “Project” selecione o seu projeto criado, em “Main Class” deve estar selecionada a classe Myjnotifyapp (em nosso caso). Após isso, clique na aba “Arguments” e na área “VM Arguments” digite: -Djava.library.path=/usr/lib/java.
Isso irá garantir a inicialização da biblioteca libjnotify.so pela VM (Virtual Machine), veja como ficou na figura 2.
Por fim temos que apenas adicionar a biblioteca jnotify.jar ao nosso projeto, este encontra-se na seção de downloads deste artigo.
Usando o Jnotify
Após a configuração acima ser realizada, estamos prontos para começar a utilização da biblioteca em questão. Como já temos criado uma classe Myjnotifyapp vamos trabalhar nesse para exemplificar melhor o uso do Jnotify, utilizaremos também a biblioteca LOG4J para criar logs da nossa aplicação, ou seja, quando arquivos forem criados, deletados, alterados e etc.
Veja abaixo na listagem 1 a nossa classe Myjnotifyapp completa com todos os recursos necessários para monitorar determinado diretório.
import org.apache.log4j.Logger;
import net.contentobjects.jnotify.JNotify;
import net.contentobjects.jnotify.JNotifyAdapter;
import net.contentobjects.jnotify.JNotifyException;
public class Myjnotifyapp {
private static Logger logger = Logger.getLogger(Myjnotifyapp.class);
/* Diretório que que o JNotify ficará monitorando para
ver se alguma das alterações solicitadas na variável
'mask' ocorreram.
*/
private static final String PATH_TO_LISTEN = "/home/admin/monitoring_dir";
/*
* a variável 'mask' guardará a mascará necessária para o JNotify
* saber o que ele deve monitorar no diretório acima. Em nosso caso
* ele irá monitorar: Criações, Deleções, Modificações e Renomeações de arquivos.
* */
private static int mask = JNotify.FILE_CREATED |
JNotify.FILE_DELETED |
JNotify.FILE_MODIFIED |
JNotify.FILE_RENAMED;
/*
* Serve para identificar se o JNotify irá ler um diretório que foi criado
* dentro do nosso diretório monitorado.
* Ex: /tmp/dir1. O diretório dir1 será monitorado pois está dentro de /tmp. Mas
* se criarmos /tmp/dir1/subdir1/, a variável 'watchSubtree' deverá estar habilitada para que
* o JNotify monitore também o subdir1.
* */
private static boolean watchSubtree = true;
/**
* @param args
*/
public static void main(String[] args) {
/*
* Iniciamos a criação de Watch apartir da API JNotify, e gravamos o seu ID na
* variável watchID, assim podemos remover posteriormente esse Watch pelo seu ID.
* */
try {
int watchID = JNotify.addWatch(PATH_TO_LISTEN, mask, watchSubtree, new JNotifyAdapter() {
@Override
public void fileCreated(int wd, String rootPath,
String name) {
logger.info("Arquivo criado: "+name);
}
@Override
public void fileRenamed(int wd, String rootPath,
String oldName, String newName) {
logger.info("Arquivo renomeado de: "+oldName+" para: "+newName);
}
@Override
public void fileDeleted(int wd, String rootPath, String name){
logger.info("Arquivo deletado: "+name);
}
@Override
public void fileModified(int wd, String rootPath, String name){
logger.info("Arquivo modificado: "+name);
}
});
Thread.sleep(1000000);
} catch (JNotifyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e){
e.printStackTrace();
}
}
}
A classe é autoexplicativa, foram adicionados vários comentários para cada passo afim de facilitar o entendimento desta. Vamos atentar apenas a alguns pontos importantes:
- O Jnotify gera uma checked exception, por isso precisamos fazer um bloco try-catch
- O Thread.sleep(tempo), serve para manter a nossa classe monitorando determinado diretório por um período de tempo, se tirássemos esse código, ela apenas iria inicializar e encerrar, quase que instantaneamente.
Faça você mesmo os testes, crie um diretório a seu gosto e crie arquivos, pastas, renomeie e veja o resultado.
Conclusão
Para quem já trabalha com Java 7 pode usufruir de bibliotecas nativas do Java que fazem a mesma tarefa do Jnotify, porém neste artigo consideramos a utilização de versões anteriores a 7, pois estas não possuem recurso nativo de monitoramento de diretórios, tal como o Jnotify o faz.