JBoss 6中整合EJB3与Struts2

文章转自: http://zhouke-nwpu.iteye.com/blog/1058318

 

 

 

 

下面是鄙人做JBoss 6整合EJB3与Struts2时遇到的一些问题,解决之后决定把它整理出来,或许能帮到某位正在为此问题困惑的同仁,若有疏漏或错误请直接扔砖。
    最近在做一个Java平台下的项目,考虑到后期业务逻辑可能非常复杂,为了今后能充分利用JBoss应用服务器所提供的服务,因此决定采用EJB3实现业务逻辑,而又想充分利用Struts2作为WEB框架所带来的简洁性,因此决定采用EJB3整合Struts2,但之前的尝试发现Struts2无法在JBoss6中部署,此问题一直未能解决,于是选择了一种折中的方案,JBoss中部署EJB模块,Tomcat中部署表现层模块,由Spring为Struts2提供ObjectFactory,并负责通过JNDI查找并注入EJB远程业务对象。
    原型开发完毕之后,发现性能不佳,原因也显而易见,引入了分布式——RMI,于是决定只使用JBoss6作为应用服务器,去掉Tomcat。但Struts2无法在JBoss6中部署,直接用Servlet开发WEB层又过于繁琐,于是痛下决心,看看究竟什么原因让Struts2无法与JBoss6并存,看着部署时的各种堆栈异常发呆,迟迟找不到解决方案,于是拿出最后的杀手锏——Google一番,相关资料很少,煞费苦心之后终于找到了一些参考,还是国外的——英语,勉强看吧,原来是Struts2中的Xwork包不能在JBoss6中部署,原因是由于JBoss6中增加了一种新的Jar文件前缀vfs,而XWork仅能兼容JBoss5之前的版本,只需对XWork一个类中的代码稍加修改,一切OK。
    该项目采用Maven做项目管理,考虑到项目构建的跨平台性,决定将XWork源码修改后作为自己项目的一个子模块发布,修改相当简单,只需对com.opensymphony.xwork2.util.URLUtil类稍作修改即可,以下是XWork发布包中该类的部分源代码:

Java代码 复制代码   收藏代码
  1. /*  
  2.  * Copyright (c) 2002-2003 by OpenSymphony  
  3.  * All rights reserved.  
  4.  */   
  5. package  com.opensymphony.xwork2.util;   
  6.   
  7. import  java.util.regex.Pattern;   
  8. import  java.util.regex.Matcher;   
  9. import  java.net.URL;   
  10. import  java.net.MalformedURLException;   
  11.   
  12. /**  
  13.  * Helper class to extract file paths from different urls  
  14.  */   
  15. public   class  URLUtil {   
  16.   
  17.      /**  
  18.      * Prefix for Jar files in JBoss Virtual File System  
  19.      */   
  20.      public   static   final  String JBOSS5_VFSZIP =  "vfszip" ;   
  21.      public   static   final  String JBOSS5_VFSMEMORY =  "vfsmemory" ;   
  22.   
  23.          /**  
  24.      * Check if given URL is pointing to JBoss 5 VFS resource  
  25.      * @param fileUrl  
  26.      * @return  
  27.      */   
  28.      public   static   boolean  isJBoss5Url(URL fileUrl) {   
  29.          final  String protocol = fileUrl.getProtocol();   
  30.          return  JBOSS5_VFSZIP.equals(protocol) || JBOSS5_VFSMEMORY.equals(fileUrl.getProtocol());   
  31.     }   
  32.   
  33. }  
/*
 * Copyright (c) 2002-2003 by OpenSymphony
 * All rights reserved.
 */
package com.opensymphony.xwork2.util;

import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.net.URL;
import java.net.MalformedURLException;

/**
 * Helper class to extract file paths from different urls
 */
public class URLUtil {

    /**
     * Prefix for Jar files in JBoss Virtual File System
     */
    public static final String JBOSS5_VFSZIP = "vfszip";
    public static final String JBOSS5_VFSMEMORY = "vfsmemory";

        /**
     * Check if given URL is pointing to JBoss 5 VFS resource
     * @param fileUrl
     * @return
     */
    public static boolean isJBoss5Url(URL fileUrl) {
        final String protocol = fileUrl.getProtocol();
        return JBOSS5_VFSZIP.equals(protocol) || JBOSS5_VFSMEMORY.equals(fileUrl.getProtocol());
    }

}


以下是修改后的源文件,仅需添加一个新的静态字符串常量"vfs"并对isJBoss5Url方法稍作修改即可:

Java代码 复制代码   收藏代码
  1. /*  
  2.  * Copyright (c) 2002-2003 by OpenSymphony  
  3.  * All rights reserved.  
  4.  */   
  5. package  com.opensymphony.xwork2.util;   
  6.   
  7. import  java.util.regex.Pattern;   
  8. import  java.util.regex.Matcher;   
  9. import  java.net.URL;   
  10. import  java.net.MalformedURLException;   
  11.   
  12. /**  
  13.  * Helper class to extract file paths from different urls  
  14.  */   
  15. public   class  URLUtil {   
  16.   
  17.      /**  
  18.      * Prefix for Jar files in JBoss Virtual File System  
  19.      */   
  20.      public   static   final  String JBOSS6_VFS =  "vfs" ;   
  21.      public   static   final  String JBOSS5_VFSZIP =  "vfszip" ;   
  22.      public   static   final  String JBOSS5_VFSMEMORY =  "vfsmemory" ;   
  23.   
  24.      /**  
  25.      * Check if given URL is pointing to JBoss 5 VFS resource  
  26.      * @param fileUrl  
  27.      * @return  
  28.      */   
  29.      public   static   boolean  isJBoss5Url(URL fileUrl) {   
  30.          final  String protocol = fileUrl.getProtocol();   
  31.          return  JBOSS6_VFS.equals(protocol) || JBOSS5_VFSZIP.equals(protocol) || JBOSS5_VFSMEMORY.equals(fileUrl.getProtocol());   
  32.     }   
  33.   
  34. }  
/*
 * Copyright (c) 2002-2003 by OpenSymphony
 * All rights reserved.
 */
package com.opensymphony.xwork2.util;

import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.net.URL;
import java.net.MalformedURLException;

/**
 * Helper class to extract file paths from different urls
 */
public class URLUtil {

    /**
     * Prefix for Jar files in JBoss Virtual File System
     */
	public static final String JBOSS6_VFS = "vfs";
    public static final String JBOSS5_VFSZIP = "vfszip";
    public static final String JBOSS5_VFSMEMORY = "vfsmemory";

    /**
     * Check if given URL is pointing to JBoss 5 VFS resource
     * @param fileUrl
     * @return
     */
    public static boolean isJBoss5Url(URL fileUrl) {
        final String protocol = fileUrl.getProtocol();
        return JBOSS6_VFS.equals(protocol) || JBOSS5_VFSZIP.equals(protocol) || JBOSS5_VFSMEMORY.equals(fileUrl.getProtocol());
    }

}


    OK,就这么简单,为了便于在以后的项目中重用,特意把XWork发布包的POM文件做了一番修改,将修改后的XWork作为自己项目的一个模块来使用,POM文件代码就不列出了,构建该项目时使用的是Maven3,如果哪位同仁遇到了同样的问题,而且在用Maven做项目管理,那么该模块可以直接添加到你的项目中,整个模块作为Maven项目上传在附件中:
    好了,终于可以在JBoss 6中部署Struts2,但是,Spring现在用来做什么呢?JNDI查找?依赖注入?既然是在同一个容器中,那么能不能直接把EJB注入Struts中的Action呢,
只知道EJB能被注入Servlet等受管资源中,试一试再说。首先彻底将Spring移除,哇,项目发布包小了不少,给力,呵呵~~,然后直接在Struts2 Action中采用注解注入EJB,修改完成之后,部署运行,果不出所料,NullPointerException~~~,看来是不行,Google一下,找到了一个插件——strus2-ejb3-plugin,该插件是个Google开源项目,项目首页是
http://code.google.com/p/struts2-ejb3-plugin/ ,大家可以看看怎么使用。相当简单,几乎是零配置,默认的配置就可以搞定,只需要把这个插件添加在你的类路径中。我的项目是打包成EAR包,如application.ear,那么仅需要在类路径下添加struts2-ejb3-plugin.properties,内容如下所示:

Java代码 复制代码   收藏代码
  1. #struts-ejb3-plugin.properties   
  2.   
  3. # ear file path, leave empty  if  not applicable   
  4. earFileBaseName=application  
#struts-ejb3-plugin.properties

# ear file path, leave empty if not applicable
earFileBaseName=application


除此之外,在你的类路径下添加jndi.properties文件,如下所示:

Java代码 复制代码   收藏代码
  1. java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory   
  2. java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces   
  3. java.naming.provider.url=jnp: //localhost:1099   
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=jnp://localhost:1099


    重新构建部署项目,一切OK,尽情享受EJB3与Struts2的整合吧,enjoy it!
    哦,不对,还有一点小小的缺陷,既然我的项目是用Maven作项目管理的,而这个插件项目并未使用Maven,搜索过几个主要的仓库之后,都没有该构件,如果直接把该插件放在类路径中,那岂不是失去了Maven的长处?OK,这个好办,既然是开源的,那就自己用Maven构建它,和上面的XWork模块一样,将它作为自己项目的一部分,让Maven来为你做这些吧。该构件也作为Maven项目一并上传至附件中。遇到同样问题的同仁可以直接使用它,不用浪费自己宝贵的时间了。OK,就这么多,经过调整之后,性能有了明显的改善,以后若采用同样的架构,便可一劳永逸。
    第一次在JavaEye上发文章,以前一直看各位大侠的文章来帮助自己解决问题,提高自己,实在不好意思写什么,因为自己很菜。昨天解决了这个困扰自己已久的问题,有点小激动,于是乎把这些问题整理出来,兴许能帮到哪位同仁!!!

 

你可能感兴趣的:(struts2)