2010-11-27 19 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(); 
     } 
    } 
} 

ローカルインタフェースである:

Iタイムアウトメソッドが後に呼び出されるWebコンテナ(私はストライプのフレームワークを使用する)を介してBeanを呼び出す
import java.io.File; 

public interface TimedFileDeletionBeanLocal { 

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

指定された時刻が "タイムアウトが発生しました"だけを出力し、ファイルを削除せず、例外をスローします。これはコンソール出力です:

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

アドバイスをいただければ幸いです。それが問題かもしれません表示されます

答えて

0

は、対話状態は維持されません。ステートレスBeanのインスタンス変数は呼び出し間で共有されるため、重複する可能性があります。

したがって、あなたが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

ことの一つは、あなたがsetRequiredInfoメソッドにファイルへの参照を渡しているということです。そのリファレンスはデバッガを使用してローカルに保存されますが、タイマーが起動するとリファレンス値が同じであることを確認します。私はそれがもはや参照された同じファイルではないかもしれない、またはFileオブジェクトが一時的かもしれないと思う。また

、EJBTimersとJBossとほんの少しの警告。このバージョンのJBossでは、タイマー付きのすべてのEJBに対してスレッドが実行されます。したがって、これらのEJBで500個のファイルを削除すると、JBossは500個のスレッドをスピンアップします。この動作は望ましくないが、EJB仕様(実装上はあいまい)に準拠している。これらのスレッドは、コンテナが再起動し、タイマが起動するのを待っている場合に再作成されます。ステートレスセッションBeanで

+0

感謝。私はservletContextListenerを通して一度だけ実行するEJBタイマーを作成し、数分ごとに古いファイルをチェックします。 – Alex