`
scoffor
  • 浏览: 16905 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

JMS入门介绍,再推荐一本书

    博客分类:
  • JMS
阅读更多

在著名的观察者模式中使用的就是基于消息机制,本人觉得《Java消息服务(第2版)》很好,好像老美总是很喜欢动物哈,这次又是一个长尾巴麻雀,嘻嘻,正准备好好的看这本书。

好了,再做个入门介绍吧:

搭建环境
如果机器上没有装jdk,一般安装一下。我装的是jdk1.6;

从sun官网下载jms-1_1-fr-apidocs.zip,解压可见jms1.1目录;

从sun官网jms-1_0_2-upd-sampleprograms.zip,解压到samples目录;

从jboss官网下载jboss-5.0.0.GA.zip,解压可见jboss-5.0.0.GA目录;

 

启动jboss,如果能访问到http://localhost:8080,说明jboss已经起来了。

进入cmd命令窗口,设置classpath:

 

Set classpath=.;D:\Program Files\Java\jdk1.6.0\lib; D:\ebook\java\JMS\jms1.1\lib\javax.jms.jar;D:\ebook\java\JMS\jms1.1\lib\jms.jar;D:\software\jboss-5.0.0.GA\client\jnp-client.jar; D:\software\jboss-5.0.0.GA\client\jbossall-client.jar

 
 jnp-client.jar和jnp-client.jar在jboss的client目录下;javax.jms.jar和jms.jar在jms1.1的lib目录下。请根据自己的安装路径设置classpath。

 

开始运行
进入samples目录下,可以看到如下文件,先读一下README:

 编译所有的文件。

 

Javac *.java

 
 运行SenderToQueue

Java  SenderToQueue SQ

 

1.  报错,问题一:

Couldn't build an initial context   :   javax.naming.NoInitialContextException:   Cannot   instantiate   class:   org.jnp.interfaces.NamingContextFactory   [Root   exception   is   java.lang.ClassNotFoundException:   org.jnp.interfaces.NamingContextFactory] 

 
 查看发现应该在SampleUtilities.java 的方法jndiLookup中加入一段代码:

//增加InitialContext的绑定设置。

System.setProperty(Context.INITIAL_CONTEXT_FACTORY,

                        "org.jnp.interfaces.NamingContextFactory");

System.setProperty(Context.URL_PKG_PREFIXES,

                                "org.jboss.naming");

System.setProperty(Context.PROVIDER_URL, "localhost:1099");

 

jndiContext = new InitialContext();

 

2.  重新编译运行,报错,问题二:

 

javax.naming.NameNotFoundException: QueueConnectionFactory not bound

javax.naming.NameNotFoundException: TopicConnectionFactory not bound

 
查看jboss console,http://localhost:8080/jmx-console/ 发现jboss.messaging.connectionfactory 的jndi名字是ConnectoryFactory.所以把QueueConnectionFactory和TopicConnectionFactory的名字都改成ConnectoryFactory。

 

 

3.  重新编译运行,报错,问题三:

JNDI lookup failed: javax.naming.NameNotFoundException: SQ not bound

Connection problem: javax.naming.NameNotFoundException: SQ not bound

 

查看jboss console的jboss.messaging.destination,发现缺省情况下只有DLQ和ExpiryQueue两个Queue。
 



 

 

如果要自定义Queue 或者Topic,可以destinations-service.xml文件中直接配置。该文件位于

jboss-5.0.0.GA\server\default\deploy\messaging\destinations-service.xml。

如下是加一个testTopic的例子。

 

<!—Add the testTopic.-->

<mbean code="org.jboss.jms.server.destination.TopicService" 

      name="jboss.messaging.destination:service=Topic,name=testTopic" 

      xmbean-dd="xmdesc/Topic-xmbean.xml"> 

      <annotation>

@org.jboss.system.deployers.managed.ManagementObjectClass(code=org.jboss.jms.server.destination.TopicServiceMO)

</annotation> 

      <depends optional-attribute-name="ServerPeer">

jboss.messaging:service=ServerPeer

</depends> 

      <depends>jboss.messaging:service=PostOffice</depends> 

   </mbean>

  

查看jboss console的jboss.messaging.destination,可以看到自己加的A、B、C、D、E、controlQueue和testTopic都在列表中了。



 

 

 点击查看名为DLQ的Queue,可以看到它的JNDI名字为/queue/DLQ.在jboss中所有的queue的JNDI名字都是/queue/**, topic的JNDI名字都是/topic/**,在代码中写对queue或者topic的JNDI名字,就能找到啦。

 

 

 

至此,编译运行成功。

 

解决问题参考的资料
1.  JNDI配置原理详解(转载别人的昂····)

 

最近写书,写到JNDI,到处查资料,发现所有的中文资料都对JNDI解释一通,配置代码也是copy的,调了半天也没调通,最后到SUN的网站参考了一下他的JNDI tutorial,终于基本上彻底明白了

和多数java服务一样,SUN对JNDI也只提供接口,使用JNDI只需要用到JNDI接口而不必关心具体实现:

private static Object jndiLookup() throws Exception {
  InitialContext ctx = new InitialContext();
  return ctx.lookup("java:comp/env/systemStartTime");
}

上述代码在J2EE服务器环境下工作得很好,但是在main()中就会报一个NoInitialContextException,许多文章会说你创建InitialContext的时候还要传一个Hashtable或者Properties,像这样:

Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
env.put(Context.PROVIDER_URL,"t3://localhost:7001");
InitialContext ctx = new InitialContext(env);

这个在WebLogic环境下是对的,但是换到JBoss呢?再用JBoss的例子?

其实之所以有NoInitialContextException是因为无法从System.properties中获得必要的JNDI参数,在服务器环境下,服务器启动时就把这些参数放到System.properties中了,于是直接new InitialContext()就搞定了,不要搞env那么麻烦,搞了env你的代码还无法移植,弄不好管理员设置服务器用的不是标准端口还照样抛异常。

但是在单机环境下,可没有JNDI服务在运行,那就手动启动一个JNDI服务。我在JDK 5的rt.jar中一共找到了4种SUN自带的JNDI实现:

LDAP,CORBA,RMI,DNS。

这4种JNDI要正常运行还需要底层的相应服务。一般我们没有LDAP或CORBA服务器,也就无法启动这两种JNDI服务,DNS用于查域名的,以后再研究,唯一可以在main()中启动的就是基于RMI的JNDI服务。

现在我们就在main()中启动基于RMI的JNDI服务并且绑一个Date对象到JNDI上:

LocateRegistry.createRegistry(1099);
System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
System.setProperty(Context.PROVIDER_URL, "rmi://localhost:1099");
InitialContext ctx = new InitialContext();
class RemoteDate extends Date implements Remote {};
ctx.bind("java:comp/env/systemStartTime", new RemoteDate());
ctx.close();

注意,我直接把JNDI的相关参数放入了System.properties中,这样,后面的代码如果要查JNDI,直接new InitialContext()就可以了,否则,你又得写Hashtable env = ...

在RMI中绑JNDI的限制是,绑定的对象必须是Remote类型,所以就自己扩展一个。

其实JNDI还有两个Context.SECURITY_PRINCIPAL和Context.SECURITY_CREDENTIAL,如果访问JNDI需要用户名和口令,这两个也要提供,不过一般用不上。

在后面的代码中查询就简单了:

InitialContext ctx = new InitialContext();
Date startTime = (Date) ctx.lookup("java:comp/env/systemStartTime");

 

2.  JNDI调用时,各种应用服务器InitialContext的写法(也是在人家地里挖来的····)

 

调用ejb时,如果客户端和ejb不在同一个jvm,就要设置InitialContext,不同的应用服务器InitialContext写法也不同.

Context.INITIAL_CONTEXT_FACTORY:指定到目录服务的连接工厂
Context.PROVIDER_URL:目录服务提供者URL.

 

//jboss:
Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory"
Context.URL_PKG_PREFIXES, "org.jboss.naming"
Context.PROVIDER_URL, "localhost:1099"

 

//weblogic:

Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory"

Context.PROVIDER_URL, "t3://localhost:7001"

 

//apusic(金蝶):

Context.INITIAL_CONTEXT_FACTORY, "com.apusic.jndi.InitialContextFactory"

Context.PROVIDER_URL, "rmi://localhost:6888"

 

//WebSphere:

Context.INITIAL_CONTEXT_FACTORY, "com.ibm.websphere.naming.WsnInitialContextFactory"

Context.PROVIDER_URL, "iiop://localhost:900"

 

//J2EE  SDK(J2EE  RI):

Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.cosnaming.CNCtxFactory"

Context.PROVIDER_URL, "iiop://127.0.0.1:1050"

 

//SilverStream:

Context.INITIAL_CONTEXT_FACTORY, "com.sssw.rt.jndi.AgInitCtxFactory"

Context.PROVIDER_URL, "sssw://localhost:80"

 

//OC4J:

Context.INITIAL_CONTEXT_FACTORY, "com.evermind.server.rmi.RMIInitialContextFactory"

Context.PROVIDER_URL, "ormi://127.0.0.1/"

 

//WAS5:

Context.INITIAL_CONTEXT_FACTORY, "com.ibm.websphere.naming.WsnInitialContextFactory"

Context.PROVIDER_URL, "iiop://localhost:2809"

 

常用JNDI服务提供者连接工厂:
Filesystem:  Com.sun.jndi.fscontext.FSContextFactory

或者com.sun.jndi.fscontext.RefFSContextFactory
LDAPv3:    Com.sun.jndi.ldap.LdapCtxFactory
NDS:       com.novell.naming.service.nds.NdsInitialContextFactory
NIS:       com.sun.jndi.nis.NISCtxFactory
RMI registry: com.sun.jndi.rmi.registry.RegistryContextFactory
IBM LDAP服务提供者:   com.ibm.jndi.LDAPCtxFactory
BEA 名字服务提供者:    weblogic.jndi.WLInitialContextFactory
JBOSS名字服务提供者:  org.jnp.interfaces.NamingContextFactory

 

 

  • 大小: 5 KB
  • 大小: 27 KB
  • 大小: 25.1 KB
  • 大小: 22.9 KB
  • 大小: 7.8 KB
分享到:
评论

相关推荐

    JMS-ActiveMQ入门实例

    本实例将带领初学者了解如何使用JMS和ActiveMQ构建一个简单的消息传递系统。首先,我们需要安装以下软件包: 1. **tokyocabinet-1.4.45.tar.gz**: 这是一个高效的键值存储库,通常用于数据缓存和日志记录。在...

    JMS入门

    【JMS入门】这篇文章主要介绍了Java消息服务(Java Message Service,简称JMS)的基本概念和如何使用开源的JMS服务器OpenJMS进行实践操作。JMS是一种标准接口,用于应用程序之间的异步通信,特别是在分布式环境中,...

    JMS入门Demo

    可以拿来对接收到的信息再做响应.. ⑶MessageListenerAdapter,将消息委托交给一个普通的java类来处理.. 转化器阶段 : 实现MessageConverter接口来转换JMS对象与java对象.. 其实在使用MessageListenerAdapter时...

    activemq与spring整合发送jms消息入门实例

    本教程将深入探讨如何将这两个强大的工具结合在一起,以创建一个简单的发送JMS消息的入门实例。 首先,我们需要理解ActiveMQ的基本概念。ActiveMQ是Apache软件基金会开发的一个开源消息代理,它实现了JMS规范,提供...

    SUN JMS MQ 全书

    通过上述知识点的总结,我们可以看出《SUN JMS MQ 全书》不仅是一本详细的管理指南,也是一份全面的技术参考文档,覆盖了从快速入门到高级管理任务的所有内容。这对于那些需要深入了解和掌握SUN Java System Message...

    tomcat spring jms 异步消息传递入门实例

    本教程将带你逐步了解如何利用Tomcat、Spring和JMS(Java Message Service)构建一个简单的异步消息传递入门实例。 首先,让我们来理解一下核心组件: 1. **Tomcat**:这是一个流行的开源Java Servlet容器,用于...

    JMS--J2EE培训材料

    本文档旨在详细介绍JMS的基本结构、开发实例,帮助读者从入门到精通。 #### 二、JMS的基本结构 JMS提供了两个主要的消息域:点对点(PTP)和发布/订阅(Pub/Sub)。 1. **点对点(PTP)**:在此模式下,消息发送给特定的...

    J2EE入门级指导书

    《J2EE入门级指导书》作为一本权威的教程,不仅介绍了J2EE的基本概念和技术细节,还包含了大量实用的示例和最佳实践,对于希望深入了解J2EE的开发者来说,是一本不可或缺的学习资料。通过系统地学习本书,开发者可以...

    2本CORBA教程,一本入门,一本提升

    学习这两本书,不仅可以掌握CORBA的基础知识,还能提升对分布式系统设计和实施的理解,对于希望在IT行业中涉及分布式计算领域的专业人士来说,是非常有价值的资源。通过实践书中的例子和项目,能够加深对CORBA的理解...

    由浅入深学习、掌握JMS

    首先,**《利用JMS建立消息传递系统》** 这份文档会介绍如何使用JMS来构建一个消息传递系统的基本步骤。这包括创建消息生产者、消费者,以及设置消息代理(如ActiveMQ或RabbitMQ)等关键环节。读者将学会如何定义...

    WebService&SOA&ESB入门介绍(手把手xfire开发WS入门实例)

    Web Service是一种基于开放标准的互操作机制,允许不同应用程序和平台通过互联网进行通信。这种通信是基于XML(eXtensible Markup Language)的,确保数据能够在各种编程语言和操作系统之间无缝传递。 【SOAP】 ...

    WAS 6.1 快速入门

    【WebSphere Application Server 6.1 快速入门】 WebSphere Application Server(WAS)是IBM推出的一款企业级应用服务器,版本6.1是其在2000年代中期的一个重要发布。WAS 6.1 提供了一个强大的平台,用于开发、部署...

    Spring入门 PDF

    《Spring入门 PDF》这本书不仅介绍了Spring框架的基础知识,还深入探讨了其核心概念和设计理念,对于初学者来说是一本不可多得的好书。通过学习本书,读者不仅可以掌握Spring框架的基本用法,还能深刻理解其背后的...

    RTI DDS 入门说明文档

    本文档旨在为用户提供一个全面的指南,介绍如何使用RTI Connext DDS(Data Distribution Service)进行开发与部署。RTI Connext DDS是一种高性能、可扩展的数据分发服务,适用于构建实时分布式系统。文档详细地介绍...

    Mule3.4入门学习

    本文将对Mule3.4进行入门学习,涵盖Mule环境搭建、Webservice的发布、JMS消息通信、ftp、File应用、协议转换等知识点。 一、Mule环境搭建 Mule环境的搭建需要JDK的支持,包括下载、安装、配置JDK。首先,需要下载...

    J2EE入门经典教程

    本教程旨在为初学者提供一个全面了解 J2EE 的起点,帮助学习者掌握核心概念和技术,从而在 Java Web 开发领域奠定坚实基础。 **1. J2EE 架构概述** J2EE 平台由一系列的可互操作的组件构成,包括服务器、API、服务...

    一个EJB项目入门例程

    **EJB(Enterprise JavaBeans)**是Java EE(Enterprise Edition)平台的核心组成部分,它提供了一种规范化的组件模型,用于构建可部署在企业级服务器上的分布式应用程序。EJB项目是学习Java后端开发的重要环节,它...

    《EJB 3.0从入门到精通》

    《EJB 3.0从入门到精通》是一本针对企业级Java开发者的教程,它深入浅出地介绍了EJB(Enterprise JavaBeans)3.0规范。EJB是Java EE(Java Platform, Enterprise Edition)平台的核心组件之一,主要用于构建可扩展、...

Global site tag (gtag.js) - Google Analytics