项目迁移到Linux WebLogic遇到的问题与解决

部门的产品之前都是在tomcat中开发的,上线也是使用tomcat,但现在这个客户要求高,要在wls上部署,过程中就遇到不少问题了。在这里一一记录。

1、Log4j

这是第一件头疼的事,实际上这和项目在wls上的部署方式有关。只是当前是用war包的,所以才碰到。最开初web.xml中的配置是

       <context-param>
        <param-name>log4jConfigLocation</param-name>
        <param-value>WEB-INF/classes/log4j.properties</param-value>
    </context-param>

    <context-param>
        <param-name>log4jRefreshInterval</param-name>
        <param-value>60000</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
    </listener>

使用Spring的Listener,配置个log4jConfigLocation指明位置,这在tomcat是行得通的。然后就这样不动地打成了war包,通过控制台一步步安装了war,启动时提示

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]

哦,what is this,不能在war文件未展开时设置web app的根系统配置。找了一下资料,要加上这两个东西

    <context-param>  
	    <param-name>log4jExposeWebAppRoot</param-name>  
		<param-value>false</param-value>  
	</context-param> 
    
 
     <context-param>
		<param-name>webAppRootKey</param-name>
		<param-value>Bizcenter.root</param-value>
     </context-param>

以上几个配置的意思如下:

1.      Log4jConfigLocation:Log4j配置文件的位置

2.      Log4jRefreshInterval:检测Log4j配置文件是否改变的时间间隔

3.      Log4jExposeWebAppRoot:应用是否可以通过System.getProperties(“webAppRootKey”)得到当前应用名。

实际上,这些配置都是为了Log4jConfigListener用的,在该Listener内部会从web.xml中获取以前配置来初始化。但是呢,WebLogic自身也包含对Log4j的支持,在打包部署(.war)的时候,会和Spring的org.springframework.web.util.Log4jConfigListener有冲突,具体又会引来什么问题暂时也忘了。网上说还可以改成Log4jConfigServlet,以servlet方式来init。不过呢,org.springframework.web.util.Log4jConfigServlet在Spring v4.0+ 已经去掉了,那个Listener还在。如果不用Listener方式的话,那以上的几个配置都是没用的。

折腾了许久,不想用配置方式来搞了,log4j也提供了手动初始化。

a.键值对格式,需要使用PropertyConfigurator.configureAndWatch(path或prop
erties, delay)
加载。

b.XML格式,需要使用DOMConfigurator.configureAndWatch(path, delay)加载。

a方式适合log4j.properties,config是个多态方法,第一个参数可接受路径或properties,第二个是定时刷新配置文件的,和log4jReFleshInterval一个道理,也有简化的configure方法。

在tocmat中,path一般是这么获取的:getServletContext().getRealPath("/") +  "/WEB-INF/classes/log4j.properties"。因为tomcat是解压了war包的,所以得到的路径类似于D:\tomcat\webapps\demo\WEB-INF\classes\log4j.properties没错。如果在wls中,不解压war包,getServletContext().getRealPath("/")得到的是null。看看这个方法怎么说

public String getRealPath(String path)
……
The real path returned will be in a form appropriate to the computer and operating system on which the servlet Container is running, including the
proper path separators. This method returns null if the servlet container cannot translate the virtual path to a real path for any reason 
(such as when the content is being made available from a .war archive).


对一个打包的应用来说,是没有RealPath的概念的,调用getRealPath只会简单地返回null。其实,也很好理解,一个文件被打包入了.war文件,就不存在目录结构了(虽然包中仍然存在目录结构,但这不等同于文件系统中的目录结构)。所以,对war包中的资源是无法得到RealPath的。这样也就无从通过文件IO进行读取了。怎么办?可以通过读入InputStream,构造一个Properties,通过configure(Properties properties)方法同样可以完成配置。

// 当war包未解压时,获取的是war包中的WEB-INF/classes/log4j.properties,而不是_wl_cls_gen.jar中的。
// 所以配置文件不必一定要放在classes中,可以是WEB-INF/conf/等		
Properties p = new Properties();
InputStream is = getServletContext().getResourceAsStream("WEB-INF/classes/log4j.properties");
p = new Properties();
try {
	 p.load(is); 
} catch (Exception e) {
	logger.error("加载log4j.xml出错", e);
	e.printStackTrace();
}
TimeSizeRollingFileAppender.setLogRootPath(getAppPath() + "log");
PropertyConfigurator.configure(p); 


这种方式,对于war应用可以成功运行,但如果现在不通过war部署,直接通过目录结构部署应用会不会又出现找不到资源的错误呢?请来看看ServletContext.getResourceAsStream的API文档,

Returns a URL to the resource that is mapped to a specified path. The path must begi

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值