5

JBoss 4.0.5、JBossMQ、および Spring 2.0.8 を使用して、リモート JMS キュー リソースに依存する Bean をインスタンス化するように Spring を構成しようとしています。私が遭遇したすべての例は、JNDI を使用してリモートの ConnectionFactory オブジェクトなどを検索することに依存しています。

私の問題は、メッセージをリモート キューに入れるマシンを起動しようとすると、リモート マシンが起動していない場合、JNDI ルックアップが単に失敗し、展開が失敗することです。展開の残りをブロックせずに、バックグラウンドでこのオブジェクトのルックアップを試行し続けるように Spring を取得する方法はありますか?

4

2 に答える 2

3

Spring の構成を見ずに確認するのは困難ですが、Spring を使用JndiObjectFactoryBeanして JNDI ルックアップを実行していると仮定すると、lookupOnStartupプロパティを false に設定できます。これにより、JNDI ターゲットが存在しない場合でもコンテキストを起動できます。JNDI 解決は、ConnectionFactory が初めて使用されるときに実行されます。

ただし、他のコンポーネントConnectionが起動時に JMS を取得しようとすると、開始した場所に戻るため、これは問題をチェーンのさらに上にシフトするだけです。他の Beanの属性を使用してlazy-init="true"、展開時にこれが発生するのを防ぐことができますが、誤って構成に何かを入れて、すべてを強制的に初期化するのは簡単です。

于 2009-08-24T18:43:54.583 に答える
1

あなたは絶対に正しいです。lookupOnStartup を false および lazy-init=true に設定してみました。これは、Queue を初めて使用しようとするときに問題を延期するだけです。次に、次のような例外がスローされます。

[org.jboss.mq.il.uil2.SocketManager] Failed to handle: org.jboss.mq.il.uil2.msgs.CloseMsg29702787[msgType: m_connectionClosing, msgID: -2147483606, error: null]
java.io.IOException: Client is not connected

さらに、ルックアップが再試行されることはないようです。リモート キューを持つマシンが再起動されると、その後メッセージは処理されません。これは、J2EE のナンセンスなユースケースの範囲内にあるように思えますが、それでも私はあまり運が良くありません...おそらく解決された問題であるべきだとさえ感じます。

補足として、Spring 構成の関連部分を以下に示します。

<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
        <property name="environment">
            <props>
            <prop key="java.naming.provider.url">localhost:1099</prop>
            <prop key="java.naming.factory.url.pkgs">org.jnp.interfaces:org.jboss.naming</prop>
            <prop key="java.naming.factory.initial">org.jnp.interfaces.NamingContextFactory</prop>
            </props>
        </property>
    </bean>

    <bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiTemplate">
            <ref bean="jndiTemplate"/>
        </property>
        <property name="jndiName">
            <value>ConnectionFactory</value>
        </property>
    </bean>

    <bean id="remoteJndiTemplate" class="org.springframework.jndi.JndiTemplate" lazy-init="true"> 
        <property name="environment"> 
            <props> 
            <prop key="java.naming.provider.url">jnp://10.0.100.232:1099</prop>
            <prop key="java.naming.factory.url.pkgs">org.jnp.interfaces:org.jboss.naming</prop>
            <prop key="java.naming.factory.initial">org.jnp.interfaces.NamingContextFactory</prop> 
            </props> 
        </property> 
    </bean> 

    <bean id="remoteConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean" lazy-init="true">
        <property name="jndiTemplate" ref="remoteJndiTemplate"/>
        <property name="jndiName" value="ConnectionFactory" />
        <property name="lookupOnStartup" value="false" />
        <property name="proxyInterface" value="javax.jms.ConnectionFactory" />
    </bean>

    <bean id="destinationResolver" class="com.foo.jms.FooDestinationResolver" />

    <bean id="localVoicemailTranscodingDestination" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiTemplate" ref="jndiTemplate"/>
        <property name="jndiName" value="queue/voicemailTranscoding" />
    </bean>

    <bean id="globalVoicemailTranscodingDestination" class="org.springframework.jndi.JndiObjectFactoryBean" lazy-init="true" >
        <property name="jndiTemplate" ref="remoteJndiTemplate" />
        <property name="jndiName" value="queue/globalVoicemailTranscoding" />
    </bean>

    <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate" >
        <property name="connectionFactory" ref="connectionFactory"/>
        <property name="defaultDestination" ref="localVoicemailTranscodingDestination" />
    </bean>

    <bean id="remoteJmsTemplate" class="org.springframework.jms.core.JmsTemplate" lazy-init="true">
        <property name="connectionFactory" ref="remoteConnectionFactory"/>
        <property name="destinationResolver" ref="destinationResolver"/>
    </bean>

    <bean id="globalQueueStatus" class="com.foo.bar.recording.GlobalQueueStatus" />

    <!-- Do not deploy this bean for machines other than transcoding machine -->
    <condbean:cond test="${transcoding.server}">
        <bean id="voicemailMDPListener"
              class="org.springframework.jms.listener.adapter.MessageListenerAdapter" lazy-init="true">
            <constructor-arg>
                <bean class="com.foo.bar.recording.mdp.VoicemailMDP" lazy-init="true">
                    <property name="manager" ref="vmMgr" />
                </bean>
            </constructor-arg>
        </bean>
    </condbean:cond>

    <bean id="voicemailForwardingMDPListener"
          class="org.springframework.jms.listener.adapter.MessageListenerAdapter" lazy-init="true">
        <constructor-arg>
            <bean class="com.foo.bar.recording.mdp.QueueForwardingMDP" lazy-init="true">
                <property name="queueStatus" ref="globalQueueStatus" />
                <property name="template" ref="remoteJmsTemplate" />
                <property name="remoteDestination" ref="globalVoicemailTranscodingDestination" />
            </bean>
        </constructor-arg>
    </bean>

    <bean id="prototypeListenerContainer"
          class="org.springframework.jms.listener.DefaultMessageListenerContainer"
          abstract="true"
          lazy-init="true">
        <property name="concurrentConsumers" value="5" />
        <property name="connectionFactory" ref="connectionFactory" />
        <!-- 2 is CLIENT_ACKNOWLEDGE: http://java.sun.com/j2ee/1.4/docs/api/constant-values.html#javax.jms.Session.CLIENT_ACKNOWLEDGE -->
        <!-- 1 is autoacknowldge -->
        <property name="sessionAcknowledgeMode" value="1" />
        <property name="sessionTransacted" value="true" />
     </bean>

     <!-- Do not deploy this bean for machines other than transcoding machine -->
     <condbean:cond test="${transcoding.server}">
         <bean id="voicemailMDPContainer" parent="prototypeListenerContainer" lazy-init="true">
           <property name="destination" ref="globalVoicemailTranscodingDestination" />
           <property name="messageListener" ref="voicemailMDPListener" />
         </bean>
     </condbean:cond>

     <bean id="voicemailForwardMDPContainer" parent="prototypeListenerContainer" lazy-init="true">
       <property name="destination" ref="localVoicemailTranscodingDestination" />
       <property name="messageListener" ref="voicemailForwardingMDPListener" />
     </bean>
于 2009-08-24T22:10:08.163 に答える