通过连接池将JMS消息发送到JBoss AS中的远程队列 [英] Sending JMS message to remote queue in JBoss AS via connection pool

查看:139
本文介绍了通过连接池将JMS消息发送到JBoss AS中的远程队列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从一个JBoss AS 5.1实例向另一个发送JMS消息。对于我的测试,我让它们都在localhost上运行,客户端JBoss AS实例使用正常的端口设置,服务器JBoss AS使用所有端口偏移100的设置。



在客户端的EAR项目中,我在我的EAR根目录中的一个名为jmstest-service.xml的文件中定义了一个JMS提供程序加载器,其中包含以下内容:



jmstest-service.xml:

 < mbean code =org.jboss。 jms.jndi.JMSProviderLoadername =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的文件中,我为连接工厂添加了一个定义: / p>

jmstest-ds.xml:

 < TX-连接工厂> 
< 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 =SessionDefaultTypetype =java.lang.String> javax.jms.Topic< / config-property>
< config-property name =JmsProviderAdapterJNDItype =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);

目的地目的地=(目的地)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);
返回新的InitialContext(env);
}

到此为止它基本上都可以。我从JNDI获取了关于连接池和远程队列的引用。但是,当我实际尝试发送消息时,它失败并出现异常:

  ERROR [ExceptionUtil] SessionEndpoint [pa-96fhptag-1 -8wtzotag-7jdzy7-110j3]发送[sa-mdkvptag-1-8wtzotag-7jdzy7-110j3] 
javax.jms.JMSException:无法路由引用[20928781172555777]:RELIABLE到org.jboss的nsQueue
.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 $ recommended $ SessionAdvised $ send $ aop(SessionAdvised.java:87)
at org.jboss.jms.server.endpoint。 advice.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)
在java.lang.reflect.Method.invoke(Method.java:597)
at org.jboss.aop.advice.PerInstanceAdvice.invoke(PerInstanceAdvice.java:122)
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:172 4)
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(其实现方法具dInvocation.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)
atg.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.jb oss.messaging.core.impl.postoffice.MessagingPostOffice#routeInternal 。此方法接收我的队列名称(nsQueue),但某些内部结构不包含任何对此的引用:

  private boolean routeInternal(MessageReference ref,Condition condition,Transaction tx,boolean fromCluster,Set names)抛出异常{
if(trace){log.trace(this +routing+ ref +with condition'+
condition +'+(tx == null?:事务性地在+ tx+
来自集群+ fromCluster; }

boolean routed = false;

lock.readLock()。acquire();

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

if(queues!= null)//这是INDEED NULL

因此,routeInternal方法返回false并抛出上述异常。



如果我从远程服务器请求(默认)连接工厂,那么一切正常。服务器正确发送并正确接收JMS消息。但是,出于性能原因,必须使用本地连接池。



那么,有没有人知道这里出了什么问题,或者知道使用连接池的替代方法对于远程JMS队列?

解决方案

问题是您在提供程序加载程序的定义中使用了java:/ XAConnectionFactory。即使这个名称将被赋予远程JNDI初始上下文,它仍将转到你的LOCAL JNDI,而不是远程JNDI反对你认为它将被解析。这只是JNDI的一个奇怪现象。



你得到那个例外,因为当地的邮局试图找到队列(nsQueue)而且它显然不知道关于那个。正在询问您当地的邮局,因为代码正在使用本地连接工厂,即使您认为它正在使用远程邮局。



只需更改对/ XAConnectionFactory的引用即可它应该工作。


I'm trying to send a JMS message from one JBoss AS 5.1 instance to the other. For my test I have them both running on localhost, the client JBoss AS instance with the normal port settings and the server JBoss AS with the setting where all ports are offset by 100.

In an EAR project on the client, I've defined a JMS provider loader in a file called jmstest-service.xml in the root of my EAR with the following content:

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>

In a file called jmstest-ds.xml I've put a definition for the connection factory:

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>

When starting up the client JBoss AS instance I see the connection factory being created. So, I've written the following code to sent the JMS message:

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();

With the getRemoteContext() defined as:

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);
}

Up till here it basically all works. I get references back from JNDI for the connection pool and for the remote queue. However when I actually try to sent the message it fails with an exception:

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)

At this point I'm more than a little stuck :(

I've tried to debug the JMS a little and where it seems to fail is in org.jboss.messaging.core.impl.postoffice.MessagingPostOffice#routeInternal. This method receives the name of my queue (nsQueue), but some internal structure doesn't contain any reference to that:

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

The routeInternal method thus returns false and the above mentioned exception is being thrown.

If I request the (default) connection factory from the remote server, then everything works. The JMS message is correctly sent and correctly received by the server. However, for performance reasons it's necessary to use a local connection pool.

So, does anyone knows what goes wrong here, or knows of an alternative method to use a connection pool for a remote JMS queue?

解决方案

The problem is that you used java:/XAConnectionFactory in the definition of the provider loader. Even though this name will be given to the remote JNDI initial context, it will still go to your LOCAL JNDI, not the remote JNDI against you think it will be resolved. This is just an oddity of JNDI.

You get that exception since your local post office is trying to find the queue ("nsQueue") and it obviously doesn't know about that. Your local post office is being asked, since the code is using the local connection factory, even when you think it's using the remote one.

Just change the references to /XAConnectionFactory and it should work.

这篇关于通过连接池将JMS消息发送到JBoss AS中的远程队列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆