2010-11-27 155 views
0

我正在使用帶有JDK 1.5的JBoss 4.2.3。我創建了一個無狀態的EJB,其目的是在指定的時間段(以毫秒爲單位)後刪除文件。EJB 3計時器問題

的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); 
} 

當我打電話通過Web容器豆(我用的條紋框架)的超時方法之後調用指定的時間,但它只打印「超時發生」,它不會刪除該文件並引發異常。這是控制檯輸出:

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

任何意見,將不勝感激。

回答

0

在無狀態會話bean中,不會維護會話狀態。無狀態bean實例變量在調用之間共享,因此它們可能會重疊。

因此,即使您使用setRequiredInfo()設置文件,超時它也會得到fileToDelete null。

嘗試在執行操作之前檢查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

看起來可能是一個問題的一件事是,你傳遞給setRequiredInfo方法對文件的引用。然後使用調試器將該引用存儲在本地,然後在計時器觸發時驗證參考值是否相同。我懷疑它可能不再是相同的文件引用或File對象可能是暫時的。

此外,EJBTimers和JBoss只是一個小警告。這個版本的JBoss通過定時器爲每個EJB創建一個線程。所以,如果你有500個文件用這些EJB刪除,JBoss將啓動500個線程。這種行爲儘管不受歡迎,但符合EJB規範(這在實現上是不明確的)。如果容器重新啓動並且定時器仍在等待啓動,則會重新創建這些線程。

+0

感謝您的建議。我將創建一個只通過servletContextListener運行一次的EJB計時器,並且每隔幾分鐘檢查一次舊文件。 – Alex 2010-11-27 17:10:26