クラスタ化された環境に JBoss-Server の複数のインスタンスがあります。バックグラウンド タスクには、登録されているすべてのジョブを管理するグローバル キューが利用可能です。このキューでは、各ノードに単純なリスナー (MDB) があり、着信メッセージを管理します。このリスナーは、シングルトン Bean の手動ルックアップ (インジェクションなし) を実行し、事前定義されたメソッドを開始します。これまでのところすべて正常に動作していますが、シングルトン Bean のメソッドは、状況によっては利用できない他の (シングルトン サービスではない) を使用しています。たとえば、ノードが再起動され、キューにメッセージが残っている (まだ処理されていない) 場合、メッセージはリスナーによって取得され、それ以降のすべての Bean は null になるため、ジョブは NPE を生成します。メッセージが取得された後、JMS-Listener で遅延時間を定義することは可能ですか?
MDB プロパティの "DeliveryActive" を false に設定し、完全なデプロイ後に Bean を開始することもできます。これをプログラムで(jmx-consoleではなく)簡単に実行できる方法はありますか?これに関するマニュアルを見つけた場合は、手動の jndi ルックアップにリダイレクトされます。アノテーションごとに Bean を注入して startDelivery() を呼び出すことが可能でなければならないと思いますか? アプリケーションでこれを行うのに適した場所はありますか?
別のヒントとして、application.xml の initialise in order プロパティに移動します。これは、問題が JBoss の展開順序に関連している可能性があるためです (一部の EJB はリスナーよりも後で使用可能になります)。ただし、JBoss 6.0にバグがあり、アップグレードすると6.1. オプションではありません。多分これのためのウォークスルーがありますか?
問題が十分に説明されていることを願っています。それ以外の場合は、さらに情報を求めてください。
前もってありがとう、ダニー
追加情報:
- JBoss 6.0.0 最終版
- HornetQ 2.2.5 Final (JBoss のデフォルト バージョンにバグがあるため、更新済み)
リスナー:
@MessageDriven(activationConfig =
{
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "/queue/SchedulerQueue")
})
public class SchedulerQueueListener implements MessageListener {
...
@Override
public void onMessage(Message message) {
...
service = (IScheduledWorkerService) new InitialContext().lookup(jndiName);
EJobResult eJobResult = service.executeJob(message);
...
}
サンプル ワーカー:
@Singleton
@LocalBinding(jndiBinding = SampleJobWorkerService.JNDI_NAME)
public class SampleJobWorkerService implements IScheduledWorkerService {
...
@EJB(name = "SampleEJB/local")
private ISampleEJB sampleEjb;
...
@Override
public EJobResult executeJob(Message message) {
int state = sampleEjb.doSomething(message.getLongProperty(A_PROPERTY));
}
この場合、sampleEjb - メンバーは時々 null になります