Spring+Hibernate+Struts的web应用程序开放过程一般在tomcat中运行。但实际应用一般会要求部署在WebLogic中。在移植过程中总结出以下问题:
1、 JDK和Servlet版本问题
WebLogic 8.1 sp4以前(包括sp4)只支持JDK1.4,建议使用JDK1.4进行编译代码,有时JDK1.5编译的程序无法运行。
由于WebLogic 8.1不支持J2EE1.4,不要使用Servlet2.4和JSP2.0进行编码。
2、 Struts 加载问题
在TOMCAT中,加载Struts的顺序是通过servlet加载,排在Listener加载之后。如果在Struts中使用Plugin,会在TOMCAT启动的最后加载,所以在Plugin中可以使用Spring中的Bean。
移植到WebLogic后,Struts会在容器启动的时候全部加载,包括Plugin。这样就出现了在Plugin加载的时候,不能得到Spring管理的Bean,也就是说Struts Plugin在WebLogic里不能使用Spring管理的Bean。所以如果需要启动时加载部分代码,建议使用Servlet init()方法。
Spring为通过Web启动的程序提供了一个工具,该工具可以从Context中直接得到WebApplicationContext,其工具的方法签名如下:
org.springframework.web.context.support.WebApplicationContextUtils. getWebApplicationContext(ServletContext);
3、 Include问题
在BEA WebLogic中不允许在一个文件中出现一次以上类似<%@ page contentType="text/html; charset=GBK"%>的代码,所以使用include file时,请将被include的文件中类似代码删除。
在TOMCAT时允许上述代码出现多回,并且使用include file时,被include的文件中,不包含上述代码,编译后客户端显示为乱码。BEA为此解释为TOMCAT不符合J2EE规范。
为了增加代码的通用性和可移植性,建议使用<jsp:include>方式。
<jsp:include>将被include的jsp代码视为独立存在的文件,所以可以在不同文件内使用多个<%@ page contentType="text/html; charset=GBK"%>。<jsp:include>直接传参由<jsp:param>标签完成,在被include页面可以通过request得到传入的值,也可以通过request.setAttribute()、request.getAttribute()进行内外文件参数传递。
4、 打包后Log4j支持问题
打包成.war部署到WebLogic后,出现如下问题:
Error: weblogic.management.DeploymentException: Cannot set web app root system property when WAR file is not expanded - with nested exception:
[java.lang.IllegalStateException: Cannot set web app root system property when WAR file is not expanded]
问题解决:通常您不需要亲自编写servlet或者listener,比如直接利用log4j的com.apache.jakarta.log4j.Log4jInit类,Spring的org.springframework.web.util.Log4jConfigServlet和org.springframework.web.util.ServletContextListener方式配置,找到.Log4jConfigServlet和ServletContextListener的源码,他们都在适当的地方(callback method)调用了Log4jWebConfigurer.initLogging(getServletContext());定位到这个方法,第一句就是:WebUtils.setWebAppRootSystemProperty(servletContext);再定位到该方法,方法很短:
public static void setWebAppRootSystemProperty(ServletContext servletContext) throws IllegalStateException {
String param = servletContext.getInitParameter(WEB_APP_ROOT_KEY_PARAM);
String key = (param != null ? param : DEFAULT_WEB_APP_ROOT_KEY);
String oldValue = System.getProperty(key);
if (oldValue != null) {
throw new IllegalStateException("WARNING: Web app root system property already set: " + key + " = " + oldValue + " - Choose unique webAppRootKey values in your web.xml files!");
}
String root = servletContext.getRealPath("/");
if (root == null) {
throw new IllegalStateException("Cannot set web app root system property when WAR file is not expanded");
}
System.setProperty(key, root);
servletContext.log("Set web app root system property: " + key + " = " + root);
}
系统需要读取webAppRootKey这个参数,所以在部署到WebLogic里的时候,在web.xml中手动添加如下代码:
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>webapp.root</param-value>
</context-param>
WebLogic自身也包含对Log4j的支持,在打包部署(.war)的时候,会和Spring的org.springframework.web.util.Log4jConfigListener有冲突(拷贝到WebLogic散放部署不会出错)。所以改用Servlet加载。(不通过应用加载Log4j好像也可以使用,但未进行完整测试,下面代码修改后,系统会报Log4j加载重复错误,不影响应用启动。)
web.xml中删除下面代码:
<listener id="log4jConfigListener">
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
将Listener加载改为通过Servlet加载,再在web.xml增加:
<servlet>
<servlet-name>log4jConfigListener</servlet-name>
<servlet-class>org.springframework.web.util.Log4jConfigServlet</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
5、 Hibernate3、Axis部署问题
Hibernate3中hibernate.query.factory_class的默认值为org.hibernate.hql.ast.ASTQueryTranslatorFactory,在WebLogic下系统运行时会抛出org.hibernate.QueryException: ClassNotFoundException: org.hibernate.hql.ast.HqlToken异常。
这个问题网上说的很多,解决方法也各式各样,其实很简单,Weblogic系统默认加载EJB-QL parser,存在重名类,所以使用时会出现ClassNotFoundException。一般网上的修改方式都是修改startWebLogic运行的脚本,将antlr-2.7.5H3.jar文件优先加载。但这样的方法会带来一些其他问题,所以不推荐使用。最好的方法是,在WEB-INF目录下建一个weblogic.xml文件,文件中写入如下代码:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE weblogic-web-app PUBLIC "-//BEA Systems, Inc.//DTD Web Application 8.1//EN" "http://www.bea.com/servers/wls810/dtd/weblogic810-web-jar.dtd">
<weblogic-web-app>
<container-descriptor>
<prefer-web-inf-classes>true</prefer-web-inf-classes>
</container-descriptor>
</weblogic-web-app>
说明:prefer-web-inf-classes=true是WebLogic's classloader在有重名类时,优先加载Web应用中WEB-INF内的类。
Axis部署同理。
注意:
1、如果有包在通过修改startWebLogic启动脚本优先加载后,web应用中有重复的包,并且将prefer-web-inf-classes=true,BEA WebLogic编译JSP时会报错。(直接设置true就可以,无需再修改脚本;如果已经修改过脚本,需要还原。)
2、在apache中提供两种方式部署Axis包,一种为prefer-web-inf-classes=true,另外一种将saaj.jar一个包在webservices.jar之前优先加载。经实际验证,只将saaj.jar一个包优先加载并不能解决全部问题,如果不使用前一种方法,请将axis全部的包加载在webservices.jar之前。
6、 BEA WebLogic Crashes问题
在实际部署到Unix下的BEA时,我遇到过两回WebLogic Crash问题,都是通过BEA Support解决的,下面分享一下两回Crash的过程、解决方法及经验。
服务器环境:HP Unix 11.23;HP JDK1.4.2_10;WebLogic8.1 SP5
l 发布Web Service接口,远程程序调用两回后BEA WebLogic Crash
在Tomcat上测试正常的Web Service接口,移植到BEA 后,第一回调用该接口一切正常,第二次调用时,系统直接报错,WebLogic进程从系统中消失。系统日志留下如下信息:
#
# An unexpected error has been detected by HotSpot Virtual Machine:
#
# SIGSEGV (11) at pc=7ac22fc0, pid=25038, tid=112
#
# Java VM: Java HotSpot(TM) Server VM (1.4.2 1.4.2.10-060112-19:42-IA64N IA64 mixed mode)
# Problematic frame:
# j org.apache.axis.message.MessageElement.addTextNode(Ljava/lang/String;)Ljavax/xml/soap/SOAPElement;+5
#
# An error report file with more information is saved as hs_err_pid25038.log
Current pc:-
pc: 0x200000007ac22fc0
Context Branch Registers:-
br0: 0x200000007ac02d80
br1: 0x200000007ac228d0
br2: 0x0
br3: 0x0
br4: 0x0
br5: 0x0
br6: 0x200000007ac209a0
br7: 0x60000000c3fb8220
Context bspstore = 0x20000000604825a0
Context bsp = 0x20000000604825a0
number of stacked grs = 25
bsp of signalling frame = 0x20000000604824d8
predicate registers = 0x400000000000c123
General Register contents at error:-
gr 1: 0x200000007eeaa628
gr 2: 0x0
gr 3: 0x400000000009f121
gr 4: 0xb07940
gr 5: 0x20000000605007d0
gr 6: 0x604e4000
gr 7: 0x604bb000
gr 8: 0x66ae71c0
gr 9: 0x74f70eb8
gr 10: 0x200000006ba29e10
gr 11: 0x64
gr 12: 0x20000000605007b0
gr 13: 0xb620d0
gr 14: 0x5
gr 15: 0x70800002
gr 16: 0x750294f0
gr 17: 0x730af0a0
gr 18: 0x2000000072c0157c
gr 19: 0x200000007505af88
gr 20: 0x0
gr 21: 0xbf
gr 22: 0x5c
gr 23: 0x2000000060500838
gr 24: 0x2000000060500834
gr 25: 0x2000000060500830
gr 26: 0x20000000750ae9a0
gr 27: 0x2000000074fe5465
gr 28: 0x0
gr 29: 0x200000006ba28a64
gr 30: 0x0
gr 31: 0x2000000072c08170
Stacked General Registers contents at error:-
gr 32 = 0x2000000074fe3028
gr 33 = 0x2000000060482430
gr 34 = 0x200000007ac02d80
gr 35 = 0x20000000605007d8
gr 36 = 0x20000000605007e8
gr 37 = 0x2000000074fe309d
gr 38 = 0x20000000750adda0
gr 39 = 0x0
gr 40 = 0x20000000605007d8
gr 41 = 0xc000000000000a99
gr 42 = 0x20000000605007b0
gr 43 = 0x2000000060500888
gr 44 = 0x2000000072feba10
gr 45 = 0x2000000060482180
gr 46 = 0x200000007ac74e60
gr 47 = 0x2000000060500824
gr 48 = 0x2000000060500838
gr 49 = 0x200000007eedc810
gr 50 = 0x200000007eedb410
gr 51 = 0x200000007eedc410
gr 52 = 0x200000007eedbc10
gr 53 = 0x20000000e7c2aa6c
gr 54 = 0x730af0a0
gr 55 = 0x200000007ac02d80
gr 56 = 0x20000000605007d0
Unflushed Caller Register Summary at error:-
number of unflushed caller registers= 0
#
# Please report this error to HP customer support.
#
./startWebLogic.sh[71]: 25038 Abort(coredump)
并且生成一个名为hs_err_pid25038.log的日志文件。日志文件内容如下:
#
# An unexpected error has been detected by HotSpot Virtual Machine:
#
# SIGSEGV (11) at pc=7ac22fc0, pid=25038, tid=112
#
# Java VM: Java HotSpot(TM) Server VM (1.4.2 1.4.2.10-060112-19:42-IA64N IA64 mixed mode)
# Problematic frame:
# j org.apache.axis.message.MessageElement.addTextNode(Ljava/lang/String;)Ljavax/xml/soap/SOAPElement;+5
#
7. Axis远程调用.net Web Service接口,出现java.lang.NoSuchMethodError: javax.xml.namespace.QName.getPrefix()Ljava/lang/String;错误,将包含该类的包优先加载,调用.net Web Service接口时系统Crash
我所用的应用系统需要调用远程.net平台的Web Service接口,该程序在Tomcat和Windows 下BEA WebLogic 8.1 SP5下进行测试,全部正常使用,但移植到HPUX上,每次调用接口时都会找不到javax.xml.namespace.QName.getPrefix()方法。查明该方法存在于jaxrpc.jar文件中,而webservices.jar存在名为javax.xml.namespace.QName的重名类。在startWebLogic.sh文件中修改,手动将jaxpc.jar排在webservices.jar之前加载,重启系统后,调用.net Web Service时出现Crash。
BEA Support给的解释是classloader冲突,确切的冲突原因不明,Windows下没有问题的话考虑升级JVM,或者使用Application内的Class优先加载。
最后通过问题4的解决方式解决。(详细原理请参见http://e-docs.bea.com/wls/docs81/programming/classloading.html)
个人感觉在UNIX下BEA不是很稳定,如果类似出Crash问题,最好请BEA Support解决。BEA Support定位问题需要出现问题的原因、出错生成的日志文件,并且配合他修改一些参数获得更多的日志文件,这些日志文件都在启动的Domain目录下。当购买BEA服务后,不建议过多花费时间在解决这类问题上(网上基本没有太多资料)。 9. 还有this.getServletContext()要改为this.getServletConfig().getServletContext()
分享到:
相关推荐
Struts+Spring+Hibernate实现上传下载 本文将围绕SSH文件上传下载的主题,向您详细讲述如何开发基于SSH的Web程序。SSH各框架的均为当前最新版本: •Struts 1.2 •Spring 1.2.5 •Hibernate 3.0 本文...
同时,Spring框架的设计尽量不干涉应用程序的内部结构,从而提高了应用程序的可移植性和灵活性。 - **控制反转 (IoC)**:Spring通过IoC(Inversion of Control)实现了依赖注入(Dependency Injection),这是一种...
6. Struts和Spring自动填充表单参数到Bean的原理? Struts使用ActionForm,Spring MVC使用ModelMapper或直接注入控制器方法,它们都将HTTP请求参数映射到对应的Bean字段。 7. 描述Spring + Hibernate的架构图及...
2.7. 移植到Spring 2.0 2.7.1. 一些变化 2.7.1.1. Jar包 2.7.1.2. XML配置 2.7.1.3. Deprecated的类和方法 2.7.1.4. Apache OJB 2.7.1.5. iBatis 2.8. 更新的样例应用 2.9. 改进的文档 I. 核心技术 3. 控制反转容器 ...
2.7. 移植到Spring 2.0 2.7.1. 一些变化 2.8. 更新的样例应用 2.9. 改进的文档 I. 核心技术 3. 控制反转容器 3.1. 简介 3.2. 容器和bean的基本原理 3.2.1. 容器 3.2.2. 实例化容器 3.2.3. 多种bean 3.2.4....
2.6.4. 将Spring 应用程序上下文部署为JCA adapter 2.6.5. 计划任务 2.6.6. 对Java 5 (Tiger) 支持 2.7. 移植到Spring 2.5 2.7.1. 改变 2.8. 更新的样例应用 2.9. 改进的文档 I. 核心技术 3. IoC(控制反转)...
2.6.4. 将Spring 应用程序上下文部署为JCA adapter 2.6.5. 计划任务 2.6.6. 对Java 5 (Tiger) 支持 2.7. 移植到Spring 2.5 2.7.1. 改变 2.8. 更新的样例应用 2.9. 改进的文档 I. 核心技术 3. IoC(控制反转)...
2.7. 移植到Spring 2.0 2.7.1. 一些变化 2.8. 更新的样例应用 2.9. 改进的文档 I. 核心技术 3. 控制反转容器 3.1. 简介 3.2. 容器和bean的基本原理 3.2.1. 容器 3.2.2. 实例化容器 3.2.3. 多种bean 3.2.4....
- **项目实战**:综合运用Struts、Spring、Hibernate技术开发协同办公系统。 - **综合/熟练运用SSH开发技术**:整合三种技术栈完成项目的开发。 6. **AJAX** - **Ajax技术核心内容**:学习Ajax的工作原理。 - *...
8. **STRUTS与Spring**:Struts是早期的MVC框架,而Spring提供了更全面的解决方案,包括依赖注入、AOP(面向切面编程)和声明式事务管理。Spring Framework还包含了一个Web MVC框架,可以替代Struts。 9. **WS(Web...
- **项目案例**:如“天朗办公自动化系统”,这是一个典型的Java Web项目案例,采用Struts + Hibernate + Spring技术栈,展示了如何利用这些技术实现MVC架构的应用程序。 - **项目结构**: - **View层**:使用JSP等...
在分布式多层架构上,Java 显得更为强大,能够轻松实现复杂的多层网络架构,并有成熟的框架如 Struts、Spring 和 Hibernate 支持。Struts 是一个基于 MVC 设计模式的框架,简化了 JSP Model2 体系结构,使开发者能够...
随着Java 2 Platform (J2EE)的推出,Java在企业级应用开发中占据了主导地位,催生了Spring、Struts、Hibernate等流行的开源框架,以及WebLogic、WebSphere、JBoss等企业级应用服务器。 总的来说,Java程序设计不仅...
10. **Docker**:Docker提供了一种轻量级的虚拟化方式,使得应用程序及其依赖环境可以被封装到容器中,便于部署和移植。 以上这些开源项目在J2EE开发中起着至关重要的作用,它们各自解决了开发中的特定问题,同时也...
简历中还提及了框架和设计模式的应用,例如Struts、Spring、Hibernate等。Struts是一个用来开发Web应用的MVC框架,Spring则提供了全方位的编程和配置模型,Hibernate是一个对象关系映射(ORM)工具,它把对象模型...
这可能包括Spring MVC、Struts 2、Hibernate等流行的框架。 第16章可能围绕“MVC(Model-View-Controller)设计模式”展开,这是Web应用程序开发中的经典架构模式。Model负责业务逻辑,View负责数据展示,...
随着J2EE的发展,出现了许多框架,如Spring、Hibernate、MyBatis等,它们进一步简化了开发流程。Spring框架不仅包括MVC,还提供了依赖注入、AOP(面向切面编程)等特性,极大地提高了开发效率。Hibernate则是一个ORM...
【Java进销存SSH框架】是一个专为中小型企业的物流管理设计的系统,它采用的是Spring、Struts和Hibernate三大主流Java开发框架的集成,也就是常说的SSH框架。这个框架组合在Java Web应用开发中非常常见,因其高效、...
2. **设计框架**:J2EE中的设计框架如Spring、Struts、Hibernate等,是提高开发效率和代码质量的重要工具。Spring框架是核心,提供了依赖注入、面向切面编程、事务管理等功能;Struts处理MVC(模型-视图-控制器)...
开发成一系列可重用组件,比如MVC框架Struts、Spring和Hibernate等,它们帮助开发者更好地组织代码,提高系统的解耦性和可维护性。 在J2EE系统开发中,初学者需要掌握以下几个关键知识点: 1. **Java和J2EE的区别*...