以前の回答と議論で、耐久性のないサブスクリプションは移植性がないという仮定がある理由がわかりません。これは、耐久性がなく、JMS 1.1に準拠しているコードサンプル(ダウンロードリンク)です。
session = connection.createSession(transacted, Session.AUTO_ACKNOWLEDGE);
myDest = (Destination)ctx.lookup(dLookup);
MessageConsumer myConsumer = session.createConsumer(myDest);
Message inMessage = null;
do {
inMessage = myConsumer.receive(10000);
if( inMessage instanceof TextMessage ) {
System.out.println( "\n" + "Got message: "+((TextMessage) inMessage).getText());
}
session.commit();
} while ( inMessage != null );
myConsumer.close();
前の例ではサブスクライバーが永続的でないだけでなく、JNDIルックアップから取得されるトピックであるかキューであるかは関係ありません。上記のリンクは、WMQ v6用に記述された動作するコードサンプルとJNDIオブジェクトを含む記事へのリンクですが、WMQ v7でも同様に動作します(ただし、pub / subは個別のブローカーコンポーネントを必要としないため、QMgrでのセットアップがわずかに異なります)。
それを除けば、元のレスポンダーは、アプリがJMS仕様に準拠している限り、JMS準拠のトランスポートで実行する必要があるという点で正しいです。それが真実である限り、ベンダーのトランスポート実装の違いがJMS抽象化を通じてバブルし、コードに影響を与えることは考慮されていません。
たとえば、JMSはマルチレベルの例外を提供します。トップレベルはJMS例外であり、次のレベルはリンクされた例外です。これは、ベンダーがベンダー固有のエラーコードを配置できるリンクされた例外です。たとえば、WMQでは、キューがいっぱいであることを示すリンク例外や、キューが破損していることを示すリンク例外が発生する場合があります。これらの1つは一時的なものであり、再試行動作は適切ですが、もう1つは致命的なエラーを示します。リンクされた例外のエラーをアプリが理解しない場合、違いはわかりません。
ポータブルを目的とした一部のアプリは、すべての例外を致命的なものとして扱うだけでこれに対処します。すべてのオブジェクトと接続を閉じて、再初期化します。また、開発者が移植性のすべての試みをあきらめ、ベンダー固有のコードのリンクされた例外を調べるアプローチを見てきました。これらのアプローチの間のどこかに、JMSオブジェクトをラップするベンダー固有のシムまたはサブクラスがあるショップがあります。これにより、アプリは移植性を維持しながら、ベンダー固有の例外に適切に対応できます。
これらが問題ではないと仮定しても、ベンダーが仕様をどのように解釈して実装したかを理解することは依然として重要です。たとえば、一部のトランスポートは、ブローカーに障害が発生したときにクライアントをシームレスにフェイルオーバーします。開発者はその動作に依存し、アプリから再接続ロジックを省略している可能性があります。しかし、問題がブローカーではなく、クライアントのネットワーク接続にある場合はどうなるでしょうか。フェイルオーバーを試みてアプリがハングする時間と、ユーザーには何が表示されますか?仕様はこれらの問題に対処しておらず、移植性はこれまでのところしか得られません。
したがって、必ず仕様を理解し、移植可能なコードを記述してください。また、ベンダーによる仕様の実装と、移植性の境界がその実装のどこにあるかについても理解してください。いずれにせよ、その境界は永続的なサブスクリプションと非永続的なサブスクリプションの間にありません。