openjms的使用 下载、安装、启动、使用、点对点代码demo
Openjms的使用
jms:java message service中文名字是“java消息服务”
Openjms是实现jms的一个开源程序,它包含一个服务器端和一堆的编程调用jar包。
官方当然有英文版的使用说明,这里只是说说我使用openjms的一些过程。
按照官方的要求,使用openjms分为4个步骤:
1、下载
2、安装
3、启动(启动服务器端)
4、使用
- 1、下载
http://nchc.dl.sourceforge.net/project/openjms/openjms/openjms-0.7.7-beta-1/openjms-0.7.7-beta-1.zip
在网站上之看到只看到一个beta版本,有点失望,不过还是看看 - 2、安装
要求:java运行环境
(1)解压压缩包
(2)设置环境变量
java_home java运行环境,java_home=c:\Program File\java\jdk1.6.0_17
openjms_home 解压之后的openjms路径openjms_home=e:\Program Files\openjms(建议将0.7.0这种东西去掉,在java中.号比较特殊,在加载类的时候可能导致错误)
(3)配置数据库
1)加入数据库驱动(本例中使用mysql数据库),在%OPENJMS_HOME%\bin\setenv.bat中设置
rem Configures the JDBC driver
set CLASSPATH=%OPENJMS_HOME%/extlib/mysql-connector-java-5.1.5-bin.jar(注:我是将mysql的驱动放入到openjms目录中,新建了一个外部jar包目录extlib)
2)修改数据库配置文件,$OPENJMS_HOME/config/openjms.xml
<DatabaseConfiguration>
<RdbmsDatabaseConfiguration
driver="com.mysql.jdbc.Driver"
url="jdbc:mysql://127.0.0.1:3306/openjms"
user="root"
password="123456" />
</DatabaseConfiguration>
注释掉: set JAVA_OPTS=%JAVA_OPTS% -Dderby.system.home=%OPENJMS_HOME%\db??
3)创建数据表
bin/dbtool.bat -create -config %OPENJMS_HOME%\config\openjms.xml
如果上面的批处理无法创建数据库表,请手动创建,创建数据库的脚本在$OPENJMS_HOME/db/sql中create_mysql.sql,至此,基本安装结束,准备启动 - 3、启动openjms服务器端
bin/startup.bat 就可以启动了,如果一切正常,将会出现
Server accepting connections on tcp://127.0.0.1:3035/ 的类似字样
当然也在命令行中检验一下端口是否开启 netstat -an|find "3035" - 4、应用(测试)
4-1、第一种测试方法
(1)创建一个新的java project
(2)导入需要的jar包(详细的jar包关系依赖请查看文档docs/usersguide/jars.html)(直接把%OPENJMS_HOME%\lib\下的jar包全部拷入)
(3)利用%openjms_home%\examples\basic 中的例子测试一下
将Sender.java和Receiver.java copy到工程当中去,带参数queue1运行Sender可以看到发送成功,然后带参数queue1运行Receiver可以看到接收到了消息,至此验证完毕。(注:这里之所以都带参数queue1运行程序,是因为在默认的配置中(%openjms_home%\config\openjms.xml),配置了目的地queue1)
4-2、第二种测试方法
cd %openjms_home%\examples\basic
build.bat(执行)
这个是讲目录中的java文件编译为class文件
1)run.bat Sender queue1
2)run.bat Receiver queue1
这个是调用发送和接受方法进行消息的传递
如果整个过程没有报错,你会看到对应的结果 - 下面贴出我已经调试通过的代码:(点对点)
- QueueSend.java
1 package openjms; 2 /** 3 * Redistribution and use of this software and associated documentation 4 * ("Software"), with or without modification, are permitted provided 5 * that the following conditions are met: 6 * 7 * 1. Redistributions of source code must retain copyright 8 * statements and notices. Redistributions must also contain a 9 * copy of this document. 10 * 11 * 2. Redistributions in binary form must reproduce the 12 * above copyright notice, this list of conditions and the 13 * following disclaimer in the documentation and/or other 14 * materials provided with the distribution. 15 * 16 * 3. The name "Exolab" must not be used to endorse or promote 17 * products derived from this Software without prior written 18 * permission of Exoffice Technologies. For written permission, 19 * please contact jima@intalio.com. 20 * 21 * 4. Products derived from this Software may not be called "Exolab" 22 * nor may "Exolab" appear in their names without prior written 23 * permission of Exoffice Technologies. Exolab is a registered 24 * trademark of Exoffice Technologies. 25 * 26 * 5. Due credit should be given to the Exolab Project 27 * (http://www.exolab.org/). 28 * 29 * THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS 30 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT 31 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 32 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 33 * EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 34 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 35 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 36 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 37 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 38 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 39 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 40 * OF THE POSSIBILITY OF SUCH DAMAGE. 41 * 42 * Copyright 2004 (C) Exoffice Technologies Inc. All Rights Reserved. 43 * 44 * $Id: Sender.java,v 1.3 2005/11/18 03:28:01 tanderson Exp $ 45 */ 46 47 import java.util.Hashtable; 48 49 import javax.jms.Queue; 50 import javax.jms.QueueConnection; 51 import javax.jms.QueueConnectionFactory; 52 import javax.jms.QueueSender; 53 import javax.jms.QueueSession; 54 import javax.jms.Session; 55 import javax.jms.TextMessage; 56 import javax.naming.Context; 57 import javax.naming.InitialContext; 58 59 public class QueueSend { 60 public static void main(String[] args) { 61 try { 62 //取得JNDI上下文和连接 63 Hashtable properties = new Hashtable(); 64 properties.put( 65 Context.INITIAL_CONTEXT_FACTORY, 66 "org.exolab.jms.jndi.InitialContextFactory"); 67 //openJms默认的端口是1099 68 // properties.put(Context.PROVIDER_URL,"rmi://localhost:1099/"); 69 properties.put(Context.PROVIDER_URL,"tcp://localhost:3035/"); 70 Context context = new InitialContext(properties); 71 //获得JMS信息连接队列工厂 72 QueueConnectionFactory queueConnectionFactory = 73 (QueueConnectionFactory) context.lookup("JmsQueueConnectionFactory"); 74 //获得JMS信息连接队列 75 QueueConnection queueConnection = 76 queueConnectionFactory.createQueueConnection(); 77 //产生队列Session,设置事务为false,自动应答消息接收 78 QueueSession queueSession = 79 queueConnection.createQueueSession( 80 false, 81 Session.AUTO_ACKNOWLEDGE); 82 83 //获得默认内建在JMS里的队列之一:queue1 84 Queue queue = (Queue) context.lookup("queue2"); 85 //产生JMS队列发送器 86 QueueSender queueSender = 87 queueSession.createSender(queue); 88 //发送数据到JMS 89 UserBean ub = new UserBean(); 90 ub.setUsername("zhang"); 91 ub.setPassword("nopasdddddddddd"); 92 //当使用QueueReceiveAsynchronous的时候用这行,同时应把84行改为context.lookup(queue1) 93 // ObjectMessage message = queueSession.createObjectMessage(ub); 94 //当使用QueueReceiveAsynchronous2的时候用这行,同时应把84行改为context.lookup(queue2) 95 TextMessage message = queueSession.createTextMessage("123ttrr"); 96 queueSender.send(message); 97 System.out.println("信息写入JMS服务器队列"); 98 //以下做清除工作,代码略 99 // queueSender.close(); 100 // queueSession.close(); 101 //关闭connection后会自动关闭sender和session 102 queueConnection.close(); 103 } catch (Exception e) { 104 e.printStackTrace(); 105 }finally{ 106 System.exit(0); 107 } 108 } 109 }
QueueReceiveSynchronous.java
1 package openjms; 2 import java.util.Hashtable; 3 4 import javax.jms.Message; 5 import javax.jms.ObjectMessage; 6 import javax.jms.Queue; 7 import javax.jms.QueueConnection; 8 import javax.jms.QueueConnectionFactory; 9 import javax.jms.QueueReceiver; 10 import javax.jms.QueueSession; 11 import javax.jms.Session; 12 import javax.naming.Context; 13 import javax.naming.InitialContext; 14 public class QueueReceiveSynchronous { 15 public static void main(String[] args) { 16 try { 17 //取得JNDI上下文和连接 18 Hashtable properties = new Hashtable(); 19 properties.put( 20 Context.INITIAL_CONTEXT_FACTORY, 21 "org.exolab.jms.jndi.InitialContextFactory"); 22 // properties.put(Context.PROVIDER_URL,"rmi://localhost:1099/"); 23 properties.put(Context.PROVIDER_URL,"tcp://localhost:3035/"); 24 Context context = new InitialContext(properties); 25 26 //获得JMS信息连接队列工厂 27 QueueConnectionFactory queueConnectionFactory = 28 (QueueConnectionFactory) context.lookup( 29 "JmsQueueConnectionFactory"); 30 31 //获得JMS信息连接队列 32 QueueConnection queueConnection = 33 queueConnectionFactory.createQueueConnection(); 34 35 //启动接收队列线程 36 queueConnection.start(); 37 //产生队列Session,设置事务为false,自动应答消息接收 38 QueueSession queueSession = 39 queueConnection.createQueueSession( 40 false, 41 Session.AUTO_ACKNOWLEDGE); 42 //获得默认内建在JMS里的队列之一:queue1 43 Queue queue = (Queue) context.lookup("queue2"); 44 //产生JMS队列接收器 45 QueueReceiver queueReceiver = 46 queueSession.createReceiver(queue); 47 //通过同步的方法接收消息 48 Message message = queueReceiver.receive(); 49 UserBean ub = null; 50 if (message instanceof ObjectMessage){ 51 /*ub = (UserBean)((ObjectMessage)message).getObject(); 52 System.out.println("同步接收到:"); 53 System.out.println("username="+ub.getUsername()); 54 System.out.println("password="+ub.getPassword());*/ 55 System.out.println(((ObjectMessage) message).getObject()); 56 } 57 //以下做清除工作 58 message.clearBody(); 59 message.clearProperties(); 60 queueReceiver.close(); 61 queueSession.close(); 62 queueConnection.close(); 63 System.exit(0); 64 } catch (Exception e) { 65 e.printStackTrace(); 66 } 67 } 68 }
QueueReceiveAsynchronous.java
1 package openjms; 2 3 import java.util.Hashtable; 4 5 import javax.jms.JMSException; 6 import javax.jms.Message; 7 import javax.jms.MessageListener; 8 import javax.jms.ObjectMessage; 9 import javax.jms.Queue; 10 import javax.jms.QueueConnection; 11 import javax.jms.QueueConnectionFactory; 12 import javax.jms.QueueReceiver; 13 import javax.jms.QueueSession; 14 import javax.jms.Session; 15 import javax.naming.Context; 16 import javax.naming.InitialContext; 17 18 public class QueueReceiveAsynchronous implements MessageListener { 19 private UserBean ub = null; 20 QueueReceiveAsynchronous(){ 21 try { 22 //取得JNDI上下文和连接 23 Hashtable properties = new Hashtable(); 24 properties.put( 25 Context.INITIAL_CONTEXT_FACTORY, 26 "org.exolab.jms.jndi.InitialContextFactory"); 27 properties.put(Context.PROVIDER_URL, 28 "rmi://localhost:1099/"); 29 Context context = new InitialContext(properties); 30 //获得JMS信息连接队列工厂 31 QueueConnectionFactory queueConnectionFactory = 32 (QueueConnectionFactory) context.lookup( 33 "JmsQueueConnectionFactory"); 34 //获得JMS信息连接队列 35 QueueConnection queueConnection = 36 queueConnectionFactory.createQueueConnection(); 37 //产生队列Session,设置事务为false,自动应答消息接收 38 QueueSession queueSession = 39 queueConnection.createQueueSession( 40 false,Session.AUTO_ACKNOWLEDGE); 41 //获得默认内建在JMS里的队列之一:queue1 42 Queue queue = (Queue) context.lookup("queue1"); 43 //产生JMS队列接收器 44 QueueReceiver queueReceiver = 45 queueSession.createReceiver(queue); 46 queueReceiver.setMessageListener(this); 47 //启动接收队列线程 48 queueConnection.start(); 49 } catch (Exception e) { 50 e.printStackTrace(); 51 } 52 } 53 public static void main(String[] args) { 54 System.out.println("非同步消息的接收:"); 55 try { 56 QueueReceiveAsynchronous listener = 57 new QueueReceiveAsynchronous(); 58 Thread.sleep(1000); 59 } catch (InterruptedException e) { 60 e.printStackTrace(); 61 } 62 } 63 64 public void onMessage(Message message) { 65 if (message instanceof ObjectMessage){ 66 try { 67 ub = (UserBean)((ObjectMessage)message).getObject(); 68 } catch (JMSException e) { 69 e.printStackTrace(); 70 } 71 if(ub != null){ 72 System.out.println("username="+ub.getUsername()); 73 System.out.println("password="+ub.getPassword()); 74 ub = null; 75 } 76 } 77 } 78 }
QueueReceiveAsynchronous2.java
1 package openjms; 2 import java.util.Hashtable; 3 4 import javax.jms.JMSException; 5 import javax.jms.Message; 6 import javax.jms.MessageListener; 7 import javax.jms.Queue; 8 import javax.jms.QueueConnection; 9 import javax.jms.QueueConnectionFactory; 10 import javax.jms.QueueReceiver; 11 import javax.jms.QueueSession; 12 import javax.jms.Session; 13 import javax.jms.TextMessage; 14 import javax.naming.Context; 15 import javax.naming.InitialContext; 16 17 public class QueueReceiveAsynchronous2 implements MessageListener { 18 private String str = null; 19 QueueReceiveAsynchronous2(){ 20 try { 21 //取得JNDI上下文和连接 22 Hashtable properties = new Hashtable(); 23 properties.put( 24 Context.INITIAL_CONTEXT_FACTORY, 25 "org.exolab.jms.jndi.InitialContextFactory"); 26 properties.put(Context.PROVIDER_URL, 27 "rmi://localhost:1099/"); 28 Context context = new InitialContext(properties); 29 //获得JMS信息连接队列工厂 30 QueueConnectionFactory queueConnectionFactory = 31 (QueueConnectionFactory) context.lookup( 32 "JmsQueueConnectionFactory"); 33 //获得JMS信息连接队列 34 QueueConnection queueConnection = 35 queueConnectionFactory.createQueueConnection(); 36 //产生队列Session,设置事务为false,自动应答消息接收 37 QueueSession queueSession = 38 queueConnection.createQueueSession( 39 false,Session.AUTO_ACKNOWLEDGE); 40 //获得默认内建在JMS里的队列之一:queue1 41 Queue queue = (Queue) context.lookup("queue2"); 42 //产生JMS队列接收器 43 QueueReceiver queueReceiver = 44 queueSession.createReceiver(queue); 45 queueReceiver.setMessageListener(this); 46 //启动接收队列线程 47 queueConnection.start(); 48 } catch (Exception e) { 49 e.printStackTrace(); 50 } 51 } 52 public static void main(String[] args) { 53 System.out.println("非同步消息2的接收:"); 54 try { 55 QueueReceiveAsynchronous2 listener = 56 new QueueReceiveAsynchronous2(); 57 Thread.sleep(1000); 58 } catch (InterruptedException e) { 59 e.printStackTrace(); 60 } 61 } 62 63 public void onMessage(Message message) { 64 System.out.println("aa"); 65 if (message instanceof TextMessage){ 66 System.out.println("bb"); 67 try { 68 str = ((TextMessage)message).getText(); 69 System.out.println(str); 70 } catch (JMSException e) { 71 e.printStackTrace(); 72 } 73 } 74 } 75 }
UserBean.java
1 package openjms; 2 3 import java.io.Serializable; 4 5 public class UserBean implements Serializable { 6 7 private String username; 8 private String password; 9 public String getUsername() { 10 return username; 11 } 12 public void setUsername(String username) { 13 this.username = username; 14 } 15 public String getPassword() { 16 return password; 17 } 18 public void setPassword(String password) { 19 this.password = password; 20 } 21 22 }
下面我说一下这几个类都是如何使用的。(前提是OpenJMS服务已经开启,启动方法可以参考上面第3步)
同步方式:运行QueueSend.java,然后运行QueueReceiveSynchronous.java。就可以看到结果
异步方式:(传对象)运行QueueReceiveAsynchronous.java,然后运行QueueSend.java(修改84行为queue1,注释掉95行)。就可以看到结果了。
(传字符串)运行QueueReceiveAsynchronous2.java,然后运行QueueSend.java(修改84行为queue2,注释掉93行)。就可以看到结果了。
在这个过程中可以打开%OPENJMS_HOME%\bin\admin.bat(控制台)查看消息数目。