Posts Tagged ‘jboss’

王者归来之Seam ?!

December 18th, 2008

王者归来之Seam??!!!

前言:
seam :  以前在项目开发的过程中,你需要引入很多框架(比如:hibernate, jsf , 工作流引擎….) ,  JBOSS说,你们自己做整合,不专业,我来帮你们做了这个工作吧,我来整合,肯定比你们自己整合要好。于此,JBOSS招兵买马,把hibernate的核心团队,JSF规范制定核心团队,EJB3规范制定核心团队等等,都找来当咨询顾问,共讨整合之事,如此诞生了一个新宝宝,取名为SEAM

使用Seam已经有1个多月的时间了,对Seam有一些简单的了解,谈谈我对Seam的一点感想吧。Seam的目标就是把各种优秀的开源系统,J2EE规范,都通过seam这个框架整合起来,从而简化开发工作,提高开发效率。我想这是seam的目标。

seam亮点:

1  JSF和EJB3.0规范实现与整合是亮点之一。

seam实现了SUN公司JSF规范做了不错的工作,在开发JSF应用时,简化了一些JSF。 Seam框架试图简化JSF的开发比如JSF的异常处理,XML配置,JSF组件的调用等等,在开发的时候让JSF和后端的业务逻辑组件(business service bean)达到紧凑,易用的效果。

2 Seam 很有意思的组件管理

我没有去看seam的源代码,但是从seam的介绍文档里有一些简要的介绍,如果有说得不对的地方,仅为交流。
Seam有2种方式来管理组件,一种为了跟JSF,JSP, servlet 等接口,seam 在web.xml 里添加了一个SeamListener,把JSF所需要的组件实例缓存到ServletContext或者HttpSession中,当请求完成或者Session失效时销毁组件实例.

另一种方式是Seam业务组件,这个组件的生命周期管理,类似EJB3规范里规定的方式,Seam业务组件的生命周期管理是否就是EJB3组件规范的实现,还是有自己的管理方式,这些方面的问题,将在以后再去深入了解。
总之,有了对组件的生命周期管理,您不需要去关心事务,并发,同步等问题。我一直都觉得EJB3的组件生命周期管理,比Spring的实现要舒服很多(Spring的组件生命周期管理,还要实现Spring 的InitializingBean,DisposableBean 这2个类,EJB3的组件就是一个很干净的POJO)。

3 Hibernate,Seam中集成的经典JPA

EJB3的JPA规范,作为EJB3的重要组成部分,Seam中对此规范的实现,整合了Hibernate3. 在使用的过程中,好像针对Hibernate3做了一些优化,让您在开发过程中,使用hibernate3更加简单一些了。

EJB2的持久化方案,在过去的几年,被hibernate3之前的版本彻底打败,EJB3开始, 这2家冤家对头,居然走到了一起。在ejb3的JPA规范发布不久,Hibernate就开始支持这一规范, 以前的相互指责,现在变成相互吹捧。

(题外话:其实我在做项目的过程中是很不喜欢hibernate的,不是因为他能提高效率的话,早就抛弃它了。我更喜欢ibatis一些,都是手工写的SQL代码做成映射关系,效率提高很多,可惜他现在对ejb3规范还不支持。虽然开发的时候会多写一点代码,那可是值得的)

Seam真的是王者归来,我见未必。让我们跳出SEAM看seam。

不要看seam的介绍文档说得多好听,好比一个人自己说自己多厉害一样,没用,还是要人家去评价才行。 在你使用seam之前,请仔细评估自己的需求,是否需要使用他。

1,你的项目是否需要使用EJB?

SEAM 在文档里有说明,SEAM也可以开发类似struts+spring+hibernate一样的轻量级架构的系统,但是那是胡说八道。我可以负责任的告诉 你,seam是一个很重的架构,他大多数的技术体系都是偏重于EJB,用他开发SSH类似的系统,只会误事误工。

2, JSF是否适合你的项目?

JSF 是SUN公司主推的一种表示层解决方案。可惜生不逢时,用JSF做企业应用,有Flex,Silverlight等技术比他强。 用JSF做WEB网页方向的应用,JSF更是滑稽可笑。也许有人说,JSF跟Seam有什么关系?但是我告诉你,seam核心目标之一就是整合JSF做表 示层开发,是他整合目标的重要组成部分。如果你打算应用seam,那么表示层的开发就一定绕不过JSF这一关。尽管seam说,他不用JSF也可以,但是 不用JSF,用什么!! 没有其它好的选择了。

3,开发效率低

呵呵,seam说我的开发效率很高嘛,但那是他自己说的嘛,seam开发环境只能在Jboss里运行才有良好的表现,Jboss在开发,调试,部署还是非常麻烦,和tomcat比效率低很多。

4,学习成本

seam引入了很多相关的其它框架包,假设你有良好的JAVA基础,一个未使用过seam的开发团队,熟悉seam起码也要3周以上的时间,这是我见过的学习成本最高的框架,他整合的框架很多,技术面很广.

5,大型系统的解决方案,seam还是无法提供

一个大型的系统,核心的关键点是:负载均衡,集中缓存处理,并行计算, 分布式存取等, seam面对这些问题,一样显得力不从心,这些问题还是需要架构师自己动手解决。而且seam中有一个web beans的技术(我在想,他使用这个是否考虑到整合JSF才这么做呢!),给负载均衡, session的处理还不及其它框架灵活。

Seam是否是归来的王者? 让我们拭目以待!

文章内容只是个人之见,肤浅之处,意在交流。

  • Share/Bookmark

如何让jboss下的消息驱动bean消费远程JMS消息

December 10th, 2008

用消息驱动bean来处理本地的JMS消息太容易不过了,但是如何处理远程的消息呢?翻遍了Java EE手册和API也找不到。原来各种应用服务器都有各自的实现。那么如何让jboss下的消息驱动bean消费远程JMS消息呢?把下面的代码复制到一个文件里,并重名为以-service.xml结尾的文件,放到jboss的deploy目录,就可以在本地得到一个从远程获取消息的JMS provider。

    <mbean code="org.jboss.jms.jndi.JMSProviderLoader"
name="jboss.mq:service=JMSProviderLoader,name=RemoteJMSProvider,server=remotehost">
        <attribute name="ProviderName">RemoteJMSProvider</attribute>
        <attribute name="ProviderAdapterClass">org.jboss.jms.jndi.JNDIProviderAdapter</attribute>
        <!-- The connection factory -->
        <attribute name="FactoryRef">UIL2XAConnectionFactory</attribute>
        <!-- The queue connection factory -->
        <attribute name="QueueFactoryRef">UIL2XAConnectionFactory</attribute>
        <!-- The topic factory -->
        <attribute name="TopicFactoryRef">UIL2XAConnectionFactory</attribute>
        <!-- Connect to JNDI on the host "the-remote-host-name" port 1099-->
        <attribute name="Properties">
            java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
            java.naming.factory.url.pkgs=org.jnp.interfaces
            java.naming.provider.url=the-remote-host-name:1099
        </attribute>
    </mbean>



注意,你要把上面的 the-remote-host-name 改成你的。部署完成后,确认在jboss的JndiViewer里能不能看到 java:/RemoteJMSProvider 。然后再MDB类上加上:

    @MessageDriven(activateConfig = {
        @ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Queue"),
        @ActivationConfigProperty(propertyName="destination", propertyValue="queue/testQueue"),
        @ActivationConfigProperty(propertyName="providerAdapterJNDI", propertyValue="java:/RemoteJMSProvider")
    })
    public class MDB implements MessageListener {
        ...
    }



providerAdapterJNDI属性使这个MDB从刚才部署好的JMS provider那里读取消息。

  • Share/Bookmark

jboss集群的Barrier mbean是个好东西

December 9th, 2008

在jboss集群时,有一种服务被称为高可用单例服务,意思是指在集群中同时肯定有且只会有一个节点提供这个服务。换句话说这种服务只会在一个节点上启动,并且当这个节点不可用时,集群中会有另一个节点代替它,它是一个具有故障恢复能力的单例服务。要实现这种服务,最简单的方法就是把部署单元,如war, ear, jar,等放到jboss/server/all/deploy-hasingleton/ 目录下。但是放在这个目录下的应用是不能热部署,也不具有farm deploy功能的。还好jboss里有一个很特殊的mbean叫 jboss.ha:service=HASingletonDeployer,type=Barrier,利用它可以很容易的实现高可用单例服务。这个bean很特殊,只有在集群的master节点上它才会被启动,而一旦master节点不再是master,它又会停止。所以一个普通的部署单元,只要依赖上了barrier,就会具有高可用单例服务的能力。下面举一个例子。

现在要实现一个高可用的消息驱动bean,监听远程机器上的消息topic/a。如果只在集群中的一个节点上部署这个MDB,一旦这个节点不可用,消息处理就停止了。为了提高可用性,可以在每个节点上部署这个MDB,但这时同一个消息会被每个MDB收到和处理,这不是我们想要的,因为同一个消息应该只被一个 MDB处理。这个时候只要让这个MDB对barrier依赖,再把它部署在所有节点上,那么就只有主节点上的MDB会运行,并且当主节点完蛋时,其他节点变成主节点时,那个节点上的MDB会自动运行。这样我们就实现了高可用单例消息驱动bean服务。

要让mbean对barrier依赖,只要在它的部署文件里填上一行,例如:

    <server>
        <mbean name="xx" code="xx.xx.xxx">
            <depends>jboss.ha:service=HASingletonDeployer,type=Barrier</depends>
        </mbean>
    </server>

对于war,jar,ear,可以在jboss.xml里添加,具体见jboss文档。对于ejb3,加上下面的annotation就好了:

@org.jboss.annotation.ejb.Depends("jboss.ha:service=HASingletonDeployer,type=Barrier")
  • Share/Bookmark

jboss下通过本地接口访问ejb3遇到的问题

September 8th, 2008

在jboss下,如果包含ejb的jar,和要通过local接口访问ejb的war不被打包成一个ear来部署,会遇到问题。如果你的war中包含了ejb3的local接口的class,那么war在通过jndi取得ejb的引用试图将其转化成接口类型时会抛ClassCastException。而如果war中不包含local接口的class,则会抛class not found的异常。这都是由讨厌的classloader问题导致的。每个放到jboss的deploy目录里的部署单元都有自己的独立的classloader树,这两棵树在jvm的classloader里是平级的。如果war和ejb jar里都包含了某个ejb的local接口的class时,那么同一个类就分别存在于两棵classloader树中。通过jndi取得的引用的类型是ejb jar中的local接口的类型,将其转化成war里的那个local接口类型时就出错了,因为它们不是同一个类。而classloader是不能访问同级的其他的classloader下的类的,所以如果war里不包含接口的class,有会因找不到class而出错。

这种时候就是使用ear的时候,位于同一个ear里ejb jar的classloader是war的classloader的父classloader。这样,只需要部署一份接口类,war也能访问到它,因为子classloader能访问父classloader载入的类。

  • Share/Bookmark