2010-06-24 125 views
3

我試圖從一個JBoss AS 5.1實例向另一個發送JMS消息。對於我的測試,我有他們兩個在本地主機上運行,​​客戶端的JBoss AS實例與正常的端口設置和服務器的JBoss AS與所有端口由100通過連接池將JMS消息發送到JBoss AS中的遠程隊列

在客戶端上的偏移在一個EAR項目的設置,我「已經定義在文件中的JMS提供者加載器叫做jmstest-service.xml的在我耳邊用下面的內容根:

jmstest-service.xml中:

<mbean code="org.jboss.jms.jndi.JMSProviderLoader" name="jboss.messaging:service=JMSProviderLoader,name=MyJMSProvider"> 
    <attribute name="ProviderName">MyJMSProvider</attribute> 
    <attribute name="ProviderAdapterClass">org.jboss.jms.jndi.JNDIProviderAdapter</attribute> 
    <attribute name="FactoryRef">java:/XAConnectionFactory</attribute> 
    <attribute name="QueueFactoryRef">java:/XAConnectionFactory</attribute> 
    <attribute name="TopicFactoryRef">java:/XAConnectionFactory</attribute> 
    <attribute name="Properties"> 
     java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory 
     java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces 
     java.naming.provider.url=jnp://localhost:1199 
    </attribute>  
</mbean> 

在一個名爲jmstest-ds.xml我已經爲連接工廠定義了一個定義:

jmstest-ds.xml文件:

<tx-connection-factory> 
    <jndi-name>MyJmsXA</jndi-name> 
    <xa-transaction/> 
    <rar-name>jms-ra.rar</rar-name> 
    <connection-definition>org.jboss.resource.adapter.jms.JmsConnectionFactory</connection-definition> 
    <config-property name="SessionDefaultType" type="java.lang.String">javax.jms.Topic</config-property> 
    <config-property name="JmsProviderAdapterJNDI" type="java.lang.String">java:/MyJMSProvider</config-property> 
    <max-pool-size>20</max-pool-size>  
    <depends>jboss.messaging:service=ServerPeer</depends>  
</tx-connection-factory> 

當啓動客戶端的JBoss AS比如我看到正在創建的連接工廠。所以,我寫了下面的代碼來發送JMS消息:

InitialContext context = new InitialContext(); 
QueueConnectionFactory factory = (QueueConnectionFactory)context.lookup("java:/MyJmsXA"); 
QueueConnection connect = factory.createQueueConnection(); 

QueueSession session = connect.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); 

Destination destination = (Destination)getRemoteContext().lookup("/queue/nsQueue"); 
MessageProducer sender = session.createProducer(destination); 

ObjectMessage message = session.createObjectMessage("bla"); 
sender.send(message); 
connect.close(); 

隨着getRemoteContext()定義爲:

InitialContext getRemoteContext() { 
    Properties env = new Properties(); 
    env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory"); 
    env.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces"); 
    env.put(Context.PROVIDER_URL, "jnp://localhost:1199"); 
    return new InitialContext(env); 
} 

截至這裏基本上所有的作品。我從JNDI獲取連接池和遠程隊列的引用。然而,當我真正嘗試發送的消息是失敗的異常:

ERROR [ExceptionUtil] SessionEndpoint[pa-96fhptag-1-8wtzotag-7jdzy7-110j3] send [sa-mdkvptag-1-8wtzotag-7jdzy7-110j3] 
javax.jms.JMSException: Failed to route Reference[20928781172555777]:RELIABLE to nsQueue 
at org.jboss.jms.server.endpoint.ServerConnectionEndpoint.sendMessage(ServerConnectionEndpoint.java:757) 
at org.jboss.jms.server.endpoint.ServerSessionEndpoint.send(ServerSessionEndpoint.java:399) 
at org.jboss.jms.server.endpoint.advised.SessionAdvised.org$jboss$jms$server$endpoint$advised$SessionAdvised$send$aop(SessionAdvised.java:87) 
at org.jboss.jms.server.endpoint.advised.SessionAdvised$send_7280680627620114891.invokeTarget(SessionAdvised$send_7280680627620114891.java) 
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:111) 
at org.jboss.jms.server.container.SecurityAspect.handleSend(SecurityAspect.java:157) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
at java.lang.reflect.Method.invoke(Method.java:597) 
at org.jboss.aop.advice.PerInstanceAdvice.invoke(PerInstanceAdvice.java:122) 
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) 
at org.jboss.jms.server.endpoint.advised.SessionAdvised.send(SessionAdvised.java) 
at org.jboss.jms.wireformat.SessionSendRequest.serverInvoke(SessionSendRequest.java:95) 
at org.jboss.jms.server.remoting.JMSServerInvocationHandler.invoke(JMSServerInvocationHandler.java:143) 
at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:891) 
at org.jboss.remoting.transport.local.LocalClientInvoker.invoke(LocalClientInvoker.java:106) 
at org.jboss.remoting.Client.invoke(Client.java:1724) 
at org.jboss.remoting.Client.invoke(Client.java:629) 
at org.jboss.remoting.Client.invoke(Client.java:617) 
at org.jboss.jms.client.delegate.DelegateSupport.doInvoke(DelegateSupport.java:189) 
at org.jboss.jms.client.delegate.DelegateSupport.doInvoke(DelegateSupport.java:160) 
at org.jboss.jms.client.delegate.ClientSessionDelegate.org$jboss$jms$client$delegate$ClientSessionDelegate$send$aop(ClientSessionDelegate.java:499) 
at org.jboss.jms.client.delegate.ClientSessionDelegate$send_6145266547759487588.invokeTarget(ClientSessionDelegate$send_6145266547759487588.java) 
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:111) 
at org.jboss.jms.client.container.SessionAspect.handleSend(SessionAspect.java:661) 
at org.jboss.aop.advice.org.jboss.jms.client.container.SessionAspect_z_handleSend_1677669648.invoke(SessionAspect_z_handleSend_1677669648.java) 
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) 
at org.jboss.jms.client.container.FailoverValveInterceptor.invoke(FailoverValveInterceptor.java:92) 
at org.jboss.aop.advice.PerInstanceInterceptor.invoke(PerInstanceInterceptor.java:86) 
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) 
at org.jboss.jms.client.container.ClosedInterceptor.invoke(ClosedInterceptor.java:170) 
at org.jboss.aop.advice.PerInstanceInterceptor.invoke(PerInstanceInterceptor.java:86) 
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) 
at org.jboss.jms.client.delegate.ClientSessionDelegate.send(ClientSessionDelegate.java) 
at org.jboss.jms.client.container.ProducerAspect.handleSend(ProducerAspect.java:269) 
at org.jboss.aop.advice.org.jboss.jms.client.container.ProducerAspect_z_handleSend_1677669648.invoke(ProducerAspect_z_handleSend_1677669648.java) 
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) 
at org.jboss.jms.client.container.ClosedInterceptor.invoke(ClosedInterceptor.java:170) 
at org.jboss.aop.advice.PerInstanceInterceptor.invoke(PerInstanceInterceptor.java:86) 
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) 
at org.jboss.jms.client.delegate.ClientProducerDelegate.send(ClientProducerDelegate.java) 
at org.jboss.jms.client.JBossMessageProducer.send(JBossMessageProducer.java:164) 
at org.jboss.jms.client.JBossMessageProducer.send(JBossMessageProducer.java:207) 
at org.jboss.jms.client.JBossMessageProducer.send(JBossMessageProducer.java:145) 
at org.jboss.jms.client.JBossMessageProducer.send(JBossMessageProducer.java:136) 
at org.jboss.resource.adapter.jms.JmsMessageProducer.send(JmsMessageProducer.java:142) 

在這一點上我比有點卡住:(

我試着調試JMS一點,更。地方似乎失效是在org.jboss.messaging.core.impl.postoffice.MessagingPostOffice#routeInternal這個方法接收我的隊列(nsQueue)的名稱,但一些內部結構不包含對任何參考文獻:

private boolean routeInternal(MessageReference ref, Condition condition, Transaction tx, boolean fromCluster, Set names) throws Exception { 
if (trace) { log.trace(this + " routing " + ref + " with condition '" + 
        condition + "'" + (tx == null ? "" : " transactionally in " + tx) + 
        " from cluster " + fromCluster); } 

    boolean routed = false; 

    lock.readLock().acquire(); 

    try 
    { 
    List queues = (List)mappings.get(condition); 

    if (queues != null) // THIS IS INDEED NULL 

的routeInternal方法因此返回false和上述上述異常正在拋出。

如果我從遠程服務器請求(默認)連接工廠,那麼一切正常。 JMS消息被正確發送並被服務器正確接收。但是,出於性能原因,有必要使用本地連接池。

那麼,有沒有人知道這裏出了什麼問題,或者知道使用連接池作爲遠程JMS隊列的另一種方法?

回答

4

問題是您在提供程序加載程序的定義中使用了java:/ XAConnectionFactory。即使這個名字會被賦予遠程JNDI初始上下文,它仍然會轉到您的本地JNDI,而不是遠程JNDI,因爲您認爲它將被解析。這僅僅是JNDI的一個奇怪之處。

由於您的本地郵局正在嘗試查找隊列(「nsQueue」),您會得到該例外情況,並且顯然不知道該情況。由於代碼使用本地連接工廠,即使您認爲使用的是遠程連接工廠,也會詢問您當地的郵局。

只需更改對/ XAConnectionFactory的引用,它應該可以工作。