EJB 3 проблема таймера - PullRequest
       1

EJB 3 проблема таймера

0 голосов
/ 27 ноября 2010

Я использую JBoss 4.2.3 с JDK 1.5. Я создал EJB без сохранения состояния, целью которого является удаление файла через определенный промежуток времени (в миллисекундах).

Код EJB:

import java.io.File;

import javax.annotation.Resource;
import javax.ejb.Stateless;
import javax.ejb.Timeout;
import javax.ejb.Timer;
import javax.ejb.TimerService;

import org.jboss.annotation.ejb.LocalBinding;

@Stateless
@LocalBinding(jndiBinding = "TimedFileDeletion")
public class TimedFileDeletionBean implements TimedFileDeletionBeanLocal {

    @Resource
    TimerService timerService;

    File fileToDelete;

    public void setRequiredInfo(long intervalDuration, File fileToDelete) {
        timerService.createTimer(intervalDuration, "Created new timer");
        this.fileToDelete = fileToDelete;
    }

    @Timeout
    public void timeout(Timer timer) {
        System.out.println("Timeout occurred");

        if(fileToDelete.exists()) {
            fileToDelete.delete();
        }
    }
}

Локальный интерфейс:

import java.io.File;

public interface TimedFileDeletionBeanLocal {

    public void setRequiredInfo(long intervalDuration, File fileToDelete);
}

Когда я вызываю bean-компонент через веб-контейнер (я использую инфраструктуру Stripes), метод timeout вызывается по истечении указанного времени, но он выводит только «Timeout произошло», он не удаляет файл и вызывает исключение. Это вывод консоли:

INFO  [STDOUT] Timeout occurred
ERROR [TimerImpl] Error invoking ejbTimeout: javax.ejb.EJBException: java.lang.NullPointerException

Любой совет будет оценен.

Ответы [ 2 ]

0 голосов
/ 27 ноября 2010

В сеансном компоненте без сохранения состояния разговора не поддерживается.Переменные экземпляра компонента без сохранения состояния совместно используются вызовами, поэтому они могут перекрываться.

Поэтому, даже если вы устанавливаете файл с помощью setRequiredInfo (), по тайм-ауту он получает fileToDelete null.

Попробуйте проверить нулевое значение перед выполнениемоперация.Ниже приведен фрагмент кода, который может вам помочь.

class FileUtility {

// Make singleton class to store list of files to delete

public static List<File> files;

//-- get/set accessing methods

}

// ---------------------

public void setRequiredInfo(long intervalDuration, File fileToDelete) {
        timerService.createTimer(intervalDuration, fileToDelete.getName()+Math.random());
        FileUtility.files.add(fileToDelete);
}

// ---------------------

@Timeout
    public void timeout(Timer timer) {
        System.out.println("Timeout occurred");

    for(File fileToDelete : Fileutility.files){

        if(fileToDelete.exists()) {
            fileToDelete.delete();
        }
    }
}
0 голосов
/ 27 ноября 2010

Единственное, что может вызвать проблемы, - это то, что вы передаете в метод setRequiredInfo ссылку на файл.Эта ссылка затем сохраняется локально, используя отладчик. Я бы проверил, что значение ссылки остается тем же, когда срабатывает таймер.Я подозреваю, что это больше не тот же файл, на который ссылаются, или что объект File может быть временным.

Кроме того, просто небольшое предупреждение с EJBTimers и JBoss.Эта версия JBoss раскручивает поток для каждого EJB с таймером.Итак, если у вас есть 500 файлов для удаления с помощью этих EJB, JBoss раскрутит 500 потоков.Такое поведение, хотя и нежелательно, соответствует спецификации EJB (что неоднозначно при реализации).Эти потоки будут воссозданы, если контейнер перезапустится, а таймеры все еще ждут срабатывания.

...