0

Session.CLIENT_ACKNOWLEDGE確認モードとして使用して、トランザクションのない JMS セッションを開始しようとしています。

残念ながら、セッションを開始すると、確認モードは常にSession.AUTO_ACKNOWLEDGE. なんで ?

リモートのグラスフィッシュ クライアントからグラスフィッシュ サーバーに接続しています (標準の組み込み OpenMQ ブローカーを使用)。セッション初期化コードは

    boolean transacted = false;
    int acknowledgeMode = Session.CLIENT_ACKNOWLEDGE;
    session = getConnection().createSession(transacted, acknowledgeMode);
    if(transacted!=session.getTransacted())
        throw new UnsupportedOperationException("seems like the broker doesn't want us to use untransacted connection");
    if(acknowledgeMode!=session.getAcknowledgeMode())
        throw new UnsupportedOperationException("seems like the broker doesn't want us to use Session.CLIENT_ACKNOWLEDGE");

[編集1]

セッションは、 connectionFactory が JNDI を使用してルックアップされる Connection/ConnectionFactory ペアから取得されます。

connectionFactory = (ConnectionFactory) getContext().lookup(JMSConstants.CONNECTION_FACTORY_NAME);

したがって、 @raffianが提案したように、リモート接続ファクトリのデフォルト設定を実際に使用する場合があります

4

1 に答える 1

0

テストは疑わしいですか?か否か ?

getTransacted()そこで、それを調査するために、セッションを作成してとの値をチェックする単体テストを作成しましたgetAcknowledgeMode()

このテストは、私が上で尋ねた質問を明らかに確認しました。つまり、Session.CLIENT_ACKNOWLEDGE結果を、で構成された JMS セッションに入力すると、Session.AUTO_ACKNOWLEDGE

ええ、私も完全に唖然としました。

ここにドラゴンがいます

それで、Glassfish で遊ぶときに皆さんがすべきことをしました。Jadclipseの最新バージョンをインストールし、テストを再開して、できる限りのデバッグを行いました。

作成ConnectionFactoryは問題ないようでした

作成ConnectionもOKのようでした

しかし、セッションの作成はまさにそのコードから始まりました (私の Jadclipse セッションから再現com.sun.messaging.jms.ra.ConnectionAdapter- を見てくださいConnectionAdapter#createSession)。

 if (ResourceAdapter._isFixCR6760301())
 {
   localXASessionImpl = (XASessionImpl)this.xac.createSession(overrideTransacted(paramBoolean), overrideAcknowledgeMode(paramInt), (this.inACC) ? null : this.mc);
 }
 else {
   localXASessionImpl = (XASessionImpl)this.xac.createSession((this.mc.xaTransactionStarted()) ? true : paramBoolean, paramInt, (this.inACC) ? null : this.mc);
 }

したがって、明らかに、私の承認モードは への呼び出しの恵みによって書き直されますConnectionAdapter#overrideAcknowledgeMode。願わくば、grepCode のコードにこの非常に有益なコメントが含まれていることを願っています。

        // EJB spec section 13.3.5 "Use of JMS APIs in Transactions" says
        // "The Bean Provider should not use the JMS acknowledge method either within a transaction 
        // or within an unspecified transaction context. Message acknowledgment in an unspecified 
        // transaction context is handled by the container." 
        // 
        // The same restriction applies in web container: JavaEE Spec: "EE.6.7 Java Message Service (JMS) 1.1 Requirements" says
        // "In general, the behavior of a JMS provider should be the same in both the EJB container and the web container.
        // The EJB specification describes restrictions on the use of JMS in an EJB container, 
        // as well as the interaction of JMS with transactions in an EJB container. 
        // Applications running in the web container should follow the same restrictions.

しかし、残念なことに、Glassfish クライアントをちょっと変わったモードで実行しています (正確には inACC ではありませんが、それに非常に似ています)。

それで、なにかお手伝いできますか ?

ドラゴンに乗る

ああ、確かに、上で言及した悪名高いバグを見ることができました: CR6760301 .. うーん、実際には、いや、できないようです (さらに、どの高品質がオラクルによって提供される FAQ であるかの通知 .. .)。

残りの解決策は...、ええ、痛いので、セッション作成の前に少し静的なものを挿入することです

static {
    /*
     * Want to know why ? http://stackoverflow.com/q/19277018/15619 this is why
     */
    System.setProperty("imq.jmsra.fixCR6760301", Boolean.FALSE.toString());
}
于 2013-10-10T13:04:34.967 に答える