各位,大家好。
小弟遇到一些困难,请大家指教。我想用Spring提供的JmsTemplate发送一个文本消息(Topic方式),给Jboss上的一组消息驱动bean。Spring我是这样配置的。<!-- 这个是要放送的Destination,是用JNDI方式查找到的 -->
<bean id="defaultTopic" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="topic/A" />
<property name="lookupOnStartup" value="true" />
<property name="proxyInterfaces">
<list>
<value>javax.jms.Topic</value>
</list>
</property>
</bean><!-- 这个是ConnectionFactory的实例,也是通过JNDI查找到的 -->
<bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="ConnectionFactory" />
<property name="lookupOnStartup" value="true" />
<property name="proxyInterfaces">
<list>
<value>javax.jms.ConnectionFactory</value>
</list>
</property>
</bean><!-- 这个就是JmsTemplate啦 -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory" />
<property name="defaultDestination" ref="defaultTopic" />
</bean>
测试代码如下@ContextConfiguration("classpath*:spring*.xml")
public class TestCases extends AbstractJUnit4SpringContextTests { @Resource
private JmsTemplate jmsTemplate; @Test
public void case0() {
jmsTemplate.send(new MessageCreator() {
public Message createMessage(Session session) throws JMSException {
TextMessage textMessage = session.createTextMessage();
textMessage.setText("......");
return textMessage;
}
});
}
}
测试这个case的话,会出现如下异常。小弟不明原因,还请各位指教。org.springframework.jms.InvalidDestinationException: Not a JBossDestination:JBossTopic[TestTopicA]; nested exception is javax.jms.InvalidDestinationException: Not a JBossDestination:JBossTopic[TestTopicA]
at org.springframework.jms.support.JmsUtils.convertJmsAccessException(JmsUtils.java:285)
at org.springframework.jms.support.JmsAccessor.convertJmsAccessException(JmsAccessor.java:168)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:469)
at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:534)
at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:526)
at test.TestCases.case0(TestCases.java:23)
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.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: javax.jms.InvalidDestinationException: Not a JBossDestination:JBossTopic[TestTopicA]
at org.jboss.jms.client.JBossSession.createProducer(JBossSession.java:206)
at org.springframework.jms.core.JmsTemplate.doCreateProducer(JmsTemplate.java:971)
at org.springframework.jms.core.JmsTemplate.createProducer(JmsTemplate.java:952)
at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:563)
at org.springframework.jms.core.JmsTemplate$3.doInJms(JmsTemplate.java:536)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:466)
... 31 more
指出我的目标并不是一个JBoss的Destination,我不清楚这个具体是什么意思。我直接使用JMS的API,发送消息给MessageDrivenBean是没有问题的。 所以我推断并不是JBOSS的配置有什么问题。分数不多,200分送上。

解决方案 »

  1.   

    信息很明确: javax.jms.InvalidDestinationException: Not a JBossDestination:JBossTopic[TestTopicA]检查创建的destination topic是不是有问题
      

  2.   

    谢谢各位朋友的关注,我认真核对过了,Jboss(5.1.0.GA)上的配置应该是没有问题的。public class MsgProducer { public static void main(String[] args) throws NamingException, JMSException {
    Context jndiCtx = new InitialContext();
    ConnectionFactory connectionFactory = (ConnectionFactory) jndiCtx.lookup("ConnectionFactory");

    Destination destination = (Destination) jndiCtx.lookup("topic/A");
    System.out.println(1);

    Connection connection = connectionFactory.createConnection();
    Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
    System.out.println(2);

    MessageProducer producer = session.createProducer(destination);
    TextMessage textMessage = session.createTextMessage();
    textMessage.setText("hello, world.");
    System.out.println(3);

    producer.send(textMessage);
    System.out.println(4);
    connection.close();
    System.out.println(5);
    }
    }
    使用以上代码(不使用Spring,直接用JMS API),可以毫无问题的驱动MDB。
      

  3.   

    必须在JBoss的deploy目录下创建消息地址,也就是一个xxx-service.xml文件,必须带有-service,必须是xml文件。在其中定义消息地址;另外消息驱动bean中也要注解从哪个地址获取消息。
    一下是ms-service.xml的文件内容,注意JNDIName的值:<?xml version="1.0" encoding="UTF-8"?>
    <server>
      <mbean code="org.jboss.mq.server.jmx.Topic" name="jboss.mq.destination:service=Topic,name=EJBTest">
    <attribute name="JNDIName">EJBTest/topic</attribute>
        <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
      </mbean>
    </server>
    一下是消息驱动bean的注解,放在MDB的类定义外面.注意最后一行:@MessageDriven(mappedName = "jms/ReceiverD", activationConfig = {
    @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"),
    @ActivationConfigProperty(propertyName = "destination", propertyValue = "EJBTest/topic")})
      

  4.   

    接楼上,MDB代码如下:@MessageDriven(mappedName = "jms/ReceiverD", activationConfig = {
    @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"),
    @ActivationConfigProperty(propertyName = "destination", propertyValue = "EJBTest/topic")})
    public class ReceiverD implements MessageListener {
    public void onMessage(Message mes) {
    System.out.println("ReveiverD收到消息:");
    try{
    TextMessage tm=(TextMessage)mes;
    System.out.println(tm.getText());
    }catch(Exception e){}
    }}
    消息发送者代码,必须导入jbossall-client.jar,此包在JBoss的client目录下:public class Test {
    public static void main(String[] args) {
    try {
    Properties props=new Properties();
    props.setProperty("java.naming.factory.initial","org.jnp.interfaces.NamingContextFactory");
    props.setProperty("java.naming.provider.url", "localhost:1099");
    props.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming");
    InitialContext context=new InitialContext(props);TopicConnectionFactory fac=(TopicConnectionFactory)context.lookup("TopicConnectionFactory");
    TopicConnection con=fac.createTopicConnection();
    TopicSession ses=con.createTopicSession(false,TopicSession.AUTO_ACKNOWLEDGE);
    Destination dest=(Destination)context.lookup("EJBTest/topic");
    MessageProducer mp=ses.createProducer(dest);

    TextMessage tm=ses.createTextMessage("Hello,world.");
    mp.send(tm);
                    } catch (Exception e) {
    e.printStackTrace();
    }
    }}
      

  5.   

    还是谢谢 比特 啦。 你说的那些我都明白,现在的问题不在应用服务器(Jboss)上,是在客户端上。估计是我Spring配置有点问题,反正现在暂时用native jms代码混过去了。 等有空了,我再好好研究研究。