Проблема, вызывающая WatchService внутри одноэлементного компонента
Мы хотели периодически просматривать файл на предмет изменений, мы используем jboss 7 . Ниже приведен мой фрагмент кода. Я инициализировал наблюдателя в постконструктивном методе синглтон-компонента и запланировал метод для опроса событий наблюдения. Я мог наблюдать изменения, когда я изменяю файл в первый раз, однако последующие изменения в файле не принимаются. Может кто-нибудь, пожалуйста, дайте мне знать, в чем может быть проблема
@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: мониторинг файловой системы) . Однако мне нужно знать, что может быть не так в этом подходе.
1 ответ
Ваш метод часов должен работать в бесконечном цикле. То, что происходит сейчас, это то, что после
try {
key = watcher.take();
}
Вы обрабатываете событие, а затем метод watch() завершается. Попробуйте эффект
for(;;) {
перед указанными выше строками, заканчивая блок for после проверки правильности. Вы видели пример на уроках Java?