2012-03-29 13 views
4

EJB 3タイマーに複数の問題が発生しました。 多くのブログで説明されているように、アノテーションにタイマーを設定するのではなく、プログラム設定を使用します。私は私のログを見ると、私はそれが二回ジョブを開始証明し、ログイン二回「ジョブ開始」を取得し、今EJB3タイマーが複数回実行される

@Singleton 
@Startup 
public class AutoAssignTask extends AbstractDirectoryMonitor { 

    @Resource 
    private TimerService timer; 

    @Inject 
    @PropertyResource(name = "timer.hour", resource = "/DL4/app.conf") 
    private String hour; 
    @Inject 
    @PropertyResource(name = "timer.minute", resource = "/DL4/app.conf") 
    private String minute; 
    @Inject 
    @PropertyResource(name = "timer.second", resource = "/DL4/app.conf") 
    private String second; 

    @EJB 
    private AutoAssignService autoAssignService; 

    @PostConstruct 
    public void init() { 
      // initializing with an expression. 
     this.initSchedule(); 
    } 
    protected void initSchedule() { 
     ScheduleExpression exp = new ScheduleExpression(); 
     if (!StringUtils.isEmpty(this.getHour())) { 
      exp.hour(this.getHour()); 
     } 
     if (!StringUtils.isEmpty(this.getMinute())) { 
      exp.minute(this.getMinute()); 
     } 
     if (!StringUtils.isEmpty(this.getSecond())) { 
      exp.second(this.getSecond()); 
     } 
     this.getTimer().createCalendarTimer(exp); 
    } 

    @Timeout 
    public void process() { 
     // do something 
     AutoAssignTask.LOG.info("starting job."); 
    } 

のは、私は毎分のためのタイマーを設定しましょう:ここに私のコードです。

何が問題なのですか?

+0

これはEJB 3.1コードであり、3.0ではなく、それに応じてタグが変更されました。 –

答えて

1

いくつかの考え:

  1. initSchedule()方法を示すために、コードを更新します。問題はScheduleExpressionにある可能性があります。
  2. サーバのバグを排除することはできません。 @PostConstructが2回呼び出されていないことを確認してください。これは、サーバーが2つのシングルトン(一般的な競合状態の問題)を作成した場合に発生します。
  3. サブクラス化があるので、AutoAssignTaskがさらにサブクラス化されている場合は@PostConstructAutoAssignTaskのまま呼び出されることにご注意ください。より簡単に言えば、EJBのスーパークラスの@PostConstructメソッドも呼び出されます。最も古い親が最初に呼び出されます。
数2と3については

、単純な静的のAtomicIntegerと文が働くだろうログ:

パブリッククラスAutoAssignTaskはAbstractDirectoryMonitor {

private static final AtomicInteger instances = new AtomicInteger(); 

@PostConstruct 
public void init() { 
    System.out.println("AutoAssignTask instance "+instances.incrementAndGet()); 
    //.... 
} 
+0

リードに感謝します。 インスタンスカウンタを追加して、タイマーが2回インスタンス化されていないことを確認しました。 私のGFサービスを再起動した後、もう問題はありません。私は何度も私のサーバーを再起動して以来、ここに投稿しています。ある時点でJavaプロセスを手動で終了し、サーバーが再起動したときにGFがタイマーを再利用してタイムアウトを2回開始したことは事実です。アプリケーションをリロードするとすべてが修正されました。 私はサーバーを監視し続け、問題を特定します。 – Rwanou

+0

もちろん、タイマーはデフォルトで永続的です。私は可能性のある原因としてそれを逃したとは信じられません!フォローアップをありがとう。タイマーは、必要に応じて非永続的に変更することができます。開発にはいいかもしれません。 –

+0

OK、GlassFishの動作が検出されました。サーバーが再始動すると、既存のモニターが永続化され、新しいモニターが作成されます。逆に、アプリケーションを再デプロイしたり再ロードしたりすると、モニタが置き換えられます。 – Rwanou

3

(質問はかなり古いかもしれないが、それは見えますが拡張少なくともJBoss EAP 7の場合)、タイマーは%JBOSS_HOME%\ standalone \ data \ timer-service-dataにXML形式で格納されます。したがって、そこから複数のScheduleExpressionを読み込む可能性は非常に高いです。少なくともそれは私の場合でした。すべてのXMLを削除してアプリケーションを再デプロイすると、問題が解決しました。

+0

私のために働いたタイマーフォルダの内容を削除する。 JBossは、アプリケーションをデプロイするたびに新しいタイマーを追加するようです。私は一度に53台のタイマーを持っていました。最初のタイマーは配備が完了した直後に始まります。アプリケーションを再デプロイまたはアンデプロイするときにタイマーが削除されることはありません。 – homaxto

+0

TimerService.createTimer()は永続タイマーを作成し、各デプロイメントは新しいタイマーを作成するようです。 2つの解決策が私のために働いた。 1. TimerService.getAllTimersを呼び出して、新しいものを作成する前にキャンセルします。 2. TimerServiceを使用します。createIntervalTimerを呼び出し、永続性をfalseに設定します。 – homaxto

+0

私はWildly 10.1.0で同じ問題に直面しました。 XMLファイルを削除して、それを修正しました。どうもありがとう。 – Boomer

関連する問題