欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

GlassFish配置SonicMQ

程序员文章站 2024-03-18 21:12:04
...

      GlassFish使用集成的MQ的相当简单,没有什么要配置的。但是要使用其他MQ产品,则需颇费一番功夫。下面详细介绍下GlasshFish中配置SonicMQ的过程。

      软件信息 GlassFish3.1.1, SonicMQ 6.1.

ü 安装 Genericra

      下载地址: http://genericjmsra.java.net/  (据说可以用UpdateTool 下载并安装,我用Update Tool找不到这个东西)

       我下载了个最新的版本2.1,随笔放那里,假说C盘根目录吧。则按装方法为,

             a. 运行cmd开命令行,并进入C盘根目录 (你的genericra.rar放的地方);

             b. 运行asadmin (前提是你已经把 $glassFish/bin加入了Path)

             c. 然后敲入  deploy genericra.rar即可。

     

ü      建立Resource Adapter

       我使用的命令行 asadmin中),执行

 

create-resource-adapter-config --user admin --property SupportsXA=true:ProviderIntegrationMode=javabean:ConnectionFactoryClassName=com.sun.messaging.ConnectionFactory:\CommonSetterMethodName=setProperty:UserName=guest:Password=guest:\QueueConnectionFactoryClassName=com.sun.messaging.QueueConnectionFactory:\TopicConnectionFactoryClassName=com.sun.messaging.TopicConnectionFactory:\QueueClassName=com.sun.messaging.Queue:TopicClassName=com.sun.messaging.Topic:\LogLevel=info:UserName=guest:Password=guest:XAQueueConnectionFactoryClassName=com.sun.messaging.XAQueueConnectionFactory:\XATopicConnectionFactoryClassName=com.sun.messaging.XATopicConnectionFactory:\XAConnectionFactoryClassName=com.sun.messaging.XAConnectionFactory genericra
 

 

ü     建立连接池及连接工厂

create-connector-connection-pool --raname genericra --connectiondefinition javax.jms.QueueConnectionFactory qcpool

 

asadmin create-connector-resource --poolname qcpool jms/QCFactory

 

ü    创建Destination

asadmin create-admin-object --raname genericra --restype javax.jms.Queue --property DestinationProperties=Name\\=clientQueue jms/clientQueue

 

    至此,配置已经差不多了了。 (其实这些官方网站都写的很清楚),到Admin控制台,大概就是这样,

 
GlassFish配置SonicMQ
 

    接下来,我就直接在Admin Console中操作了,

    一, qcpool指定MQ server Jndi信息,就是你的sonicMQ server的连接信息。其中

JndiProperties = java.naming.factory.initial=com.sonicsw.jndi.mfcontext.MFContextFactory,java.naming.provider.url=tcp://192.168.0.125:2506,com.sonicsw.jndi.mfcontext.domain=Domain1,java.naming.security.principal=Administrator,java.naming.security.credentials=Administrator 

   

GlassFish配置SonicMQ
 

    二,把Sonic MQ相关的包放到$glassFish/lib中去,

 
GlassFish配置SonicMQ
 

     至此你已经可以往SonicMQ发消息了,比较让人振奋了。代码如下,

 

package com.apress.ejb3.chapter02;

import javax.annotation.Resource;
import javax.ejb.Stateless;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.*;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.Session;

/**
 * Session Bean implementation class MessageSender
 */
@Stateless(name="MessageSender", mappedName="ejb/MessageSender")
public class MessageSender implements MessageSenderRemote, MessageSenderLocal {
	@Resource(mappedName = "jms/QCFactory")
	private QueueConnectionFactory newGradeConnectionFactory;
	@Resource(mappedName = "jms/clientQueue")
	private Queue queue;

	/**
	 * Default constructor.
	 */
	public MessageSender() {

	}
	
	public String sendMessage(String txtmsg){
		System.out.println("Start to sendMessage.");
		QueueConnection connect = null;
		try {
			// create a session for use in this thread/transaction
			connect = newGradeConnectionFactory.createQueueConnection();
			QueueSession session = connect.createQueueSession(true, 10);
//			// create a new message
//
			QueueSender sender = session.createSender(queue);
			Message msg = session.createTextMessage(txtmsg);
//			return newGradeQueue.get?QueueName();
			sender.send(msg);
//			session.commit();
		} catch (Throwable je) {
			je.printStackTrace();
			// throw a more friendly exception
		} finally {
			if (connect != null) {
				try {
					connect.close();
				} catch (Exception e) {
				}
			}
		}
		return "successfully";
	}

}

 

 

 

    但用MDB收消息是否也可以了呢?结果是不行的。并且MDB不能这用Annotation,必须要使用xml去配置。配置文件如下,

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sun-ejb-jar
  PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 8.1 EJB 2.1//EN"
    "http://www.sun.com/software/appserver/dtds/sun-ejb-jar_2_1-1.dtd">
<sun-ejb-jar>
	<enterprise-beans>
		<ejb>
			<ejb-name>DemoDataRequestProcessor</ejb-name>

			<mdb-resource-adapter>
				<resource-adapter-mid>genericra</resource-adapter-mid>
				<activation-config>
					<activation-config-property>
						<activation-config-property-name>ConnectionFactoryJndiName
						</activation-config-property-name>
						<activation-config-property-value>jms/QCFactory
						</activation-config-property-value>
					</activation-config-property>
					<activation-config-property>
						<activation-config-property-name>DestinationJndiName
						</activation-config-property-name>
						<activation-config-property-value>jms/clientQueue
						</activation-config-property-value>
					</activation-config-property>
					<activation-config-property>
						<activation-config-property-name>destinationType
						</activation-config-property-name>
						<activation-config-property-value>javax.jms.Queue
						</activation-config-property-value>
					</activation-config-property>

				</activation-config>
			</mdb-resource-adapter>
		</ejb>
	</enterprise-beans>
</sun-ejb-jar>

 

 

     你的MDB理论上可以工作了,测试代码如下,

 

package sonicMQ.testing;

import javax.ejb.MessageDriven;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

/**
 * Message-Driven Bean implementation class for: DemoDataRequestProcessor
 * 
 */
@MessageDriven(name="DemoDataRequestProcessor",mappedName="jms/clientQueue")
@TransactionManagement(value= TransactionManagementType.BEAN)
public class DemoDataRequestProcessor implements MessageListener {

	/**
	 * Default constructor.
	 */
	public DemoDataRequestProcessor() {
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see MessageListener#onMessage(Message)
	 */
	public void onMessage(Message message) {
		try {
			if (message instanceof TextMessage) {
				TextMessage orderMessage = (TextMessage) message;
				System.out.println("DemoDataRequestProcessor recieved = " + orderMessage.getText());
			} else {
				System.out.println("Invalid message ");
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}

	}

}

 

     但是我这边,总是抛异常,如下

 

java.lang.ClassCastException: com.sun.genericra.outbound.SessionAdapter cannot be cast to progress.message.jimpl.Session
	at progress.message.jimpl.aspi.wd.handleMessage(Unknown Source)
	at progress.message.zclient.MessageHandler.doNextWorkItem(Unknown Source)
	at progress.message.zclient.lx.threadMain(Unknown Source)
	at progress.message.zclient.DebugThread.run(Unknown Source)

 

 

     无赖之下,我不得不研究了下genericra的相关代码,最终改了两个类,改的比较下;

          InboundJmsResourceset方法,改动后如下,

         SessionAdapter加了个getPhysicalSession方法,如下

 

          两个java文件也加加附件中了。

 

          至此,MDB终于也可以工作了。虽然其中走了很多弯路,没一个小小的细节搞明白都包含了N次失败的尝试,最终终于完成了,当然其间也了解很多其它与此不相关的东西。

----------------------------------------------------------------------

张瑜,Mybeautiful, aaa@qq.com