2010-11-27 115 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