Проблем при извикване на WatchService в сингълтън bean

искахме периодично да наблюдаваме файл за промени, използваме jboss 7. Следва моят кодов фрагмент. Инициализирах наблюдателя в метода postconstruct на сингълтън 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