GlassFish配置SonicMQ

      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控制台,大概就是这样,

 

 

    接下来,我就直接在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 

   


 

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

 

 

     至此你已经可以往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, [email protected].

 

 

猜你喜欢

转载自mybeautiful.iteye.com/blog/1233666