Проблема с вызовом WatchService внутри одноэлементного компонента

мы хотели периодически просматривать файл на наличие изменений, мы используем jboss 7. Ниже приведен фрагмент моего кода. Я инициализировал наблюдателя в методе postconstruct singleton bean и запланировал метод для опроса событий наблюдения. Я мог наблюдать изменения, когда я изменяю файл в первый раз, однако последующие изменения файла не получены. Может кто подскажет в чем может быть дело

  @Startup
  @ConcurrencyManagement(ConcurrencyManagementType.BEAN)
  @Interceptors(NonThrowingPostConstructInterceptor.class)
  @Singleton
  @Service
  @LocalBinding(jndiBinding=IHeartBeatProducerService.JNDI_LOCAL_BINDING)
 public class HeartBeatProducerService extends EMSingletonService implements IHeartBeatProducerService{

@EJB(mappedName=IMessageService.JNDI_LOCAL_BINDING)
public IMessageService messageService;

@EJB(mappedName=ICommandExecutionService.JNDI_LOCAL_BINDING)
public ICommandExecutionService commandService;

private final static String LAST_OPERATION_COMPLETED="Last Operation Completed";

private final static String STATUS="Status"; 

private WatchService watcher;

private Path dir;

private String concServer; 

public static final String TOPIC="foo";

private IMLogger logger = new IMLogger("foo");

private String content=null; 

@PostConstruct
@Override
public void init() {
    // TODO Auto-generated method stub
    super.init();
    try {


        watcher = FileSystems.getDefault().newWatchService();
        dir=Paths.get("/shared/foo");
        dir.register(watcher, StandardWatchEventKinds.ENTRY_MODIFY);
        logger.entering(0, IHeartBeatProducerService.class.getSimpleName(), "Initializing Heart Beat", new String[]{"Entered"});

    } catch (IOException e) {

        e.printStackTrace();
    }
}

@Schedule(second="*/10", minute = "*", hour="*")
private void checkStatus()
{
    logger.entering(0, IHeartBeatProducerService.class.getSimpleName(), "Checking Status", new String[]{"Entered"});
    final String[] command={"pidof","server"};
    commandService.run(command, null, false);
    concServer=(commandService.getExitCode()==0)?"UP":"DOWN";
    if(concServer.equals("UP"))
    {
        watch();
    }
    else
    {
        content="foo:Failed";
    }
    produce();
}


public void watch()
{       
        logger.entering(0, IHeartBeatProducerService.class.getSimpleName(), "Entering watch()", new String[]{"Entered"});
        WatchKey key = null;

        try 
        {           
         key = watcher.take();
        }
        catch (InterruptedException e)
        {               
            logger.error(HeartBeatProducerService.class.getSimpleName(),"Interupted Exception " +  e.getMessage());
        }

        for ( WatchEvent<?> event: key.pollEvents())
        {
            WatchEvent.Kind kind = event.kind();

            logger.info(HeartBeatProducerService.class.getSimpleName(),"Watch Event :" + kind.name()); 

            if(kind.name().equals("OVERFLOW"))
            {
                continue;
            }
            if(kind.name().equals("ENTRY_MODIFY"))
            {
                Path concLog = (Path) event.context();

                logger.info(HeartBeatProducerService.class.getSimpleName(),"Modified File Name:" + concLog.getFileName()); 

                if(concLog.endsWith("current_status.txt"))
                {
                    logger.info(HeartBeatProducerService.class.getSimpleName(), "Reading Status");                  
                    readStatus();
                }
            }

        }

        boolean valid = key.reset();

        if ( !valid)
        {               
            logger.error(HeartBeatProducerService.class.getSimpleName(),"Key Unregistered"); 
        }
}





private void parse(String output)
{       
    // parse file contents
}

private void readStatus() {

    //read status and parse()

}
private void produce() 
{

    try {

        messageService.publish(TOPIC, content, PublishType.ASync);

    } catch (MessageException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

}

Уже есть ссылка, объясняющая то же самое с тегом @Asynchronous (EJB 3.1 и NIO2: Мониторинг файловой системы). однако мне нужно знать, что может быть не так в этом подходе.


person Saravana    schedule 26.09.2013    source источник


Ответы (1)


Ваш метод просмотра должен работать в бесконечном цикле. То, что происходит сейчас, это то, что после

     try {           
       key = watcher.take();
     }

вы обрабатываете событие, а затем метод watch() завершается. Попробуйте эффект от

     for(;;) {

перед приведенными выше строками, заканчивая блок for после проверки правильности. Вы видели пример в Учебниках по Java?

person jlweb    schedule 20.11.2013
comment
но я запланировал watch() каждые 10 секунд. См. метод checkStatus. - person Saravana; 21.11.2013
comment
Саравана, я не видел твоих аннотаций. Я не уверен, в чем проблема. Мне интересно, что происходит, когда вы вызываете take() для WatchService, который уже заблокирован при вызове take()? К сожалению, у меня нет доступной установки JBoss, чтобы попытаться воспроизвести вашу проблему. Возможно, было бы неплохо попробовать это без аннотации @Schedule и посмотреть, работает ли это так, как ожидалось (в цикле)? - Джон - person jlweb; 07.01.2014