一、引言
客户选择的是Oracle的application server————OC4J。以前没用过,由于项目很紧,我们没有太多时间去研究,只能是碰到什么问题解决什么问题。
首先碰到一个最头疼的问题,Struts无法加载。这个问题花了将近一天半的时间才找到解决方案。刚开始在客户的Unix服务器上,利用web进行部署。能部署成功,但是无法访问,于是用SecureCRT 5.1登录,把日志调出来分析,发现报下面这个错误:
二、【报错信息】
ERROR - Digester.getParser:
org.xml.sax.SAXNotRecognizedException: http://apache.org/xml/features/validation
/dynamic
at oracle.xml.jaxp.JXSAXParserFactory.setFeature(JXSAXParserFactory.java
:128)
at org.apache.commons.digester.parser.XercesParser.configureXerces(Xerce
sParser.java:185)
at org.apache.commons.digester.parser.XercesParser.newSAXParser(XercesPa
rser.java:138)
at org.apache.commons.digester.ParserFeatureSetterFactory.newSAXParser(P
arserFeatureSetterFactory.java:73)
at org.apache.commons.digester.Digester.getParser(Digester.java:682)
at org.apache.commons.digester.Digester.getXMLReader(Digester.java:891)
at org.apache.commons.digester.Digester.parse(Digester.java:1572)
at org.apache.struts.action.ActionServlet.parseModuleConfigFile(ActionSe
rvlet.java:738)
at org.apache.struts.action.ActionServlet.initModuleConfig(ActionServlet
.java:687)
at org.apache.struts.action.ActionServlet.init(ActionServlet.java:333)
at javax.servlet.GenericServlet.init(GenericServlet.java:256)
at com.evermind.server.http.HttpApplication.loadServlet(HttpApplication.
java:2371)
at com.evermind.server.http.HttpApplication.findServlet(HttpApplication.
java:4824)
at com.evermind.server.http.HttpApplication.findServlet(HttpApplication.
java:4748)
at com.evermind.server.http.HttpApplication.initPreloadServlets(HttpAppl
ication.java:4936)
at com.evermind.server.http.HttpApplication.initDynamic(HttpApplication.
java:1145)
at com.evermind.server.http.HttpApplication.<init>(HttpApplication.java:
741)
at com.evermind.server.ApplicationStateRunning.getHttpApplication(Applic
ationStateRunning.java:414)
at com.evermind.server.Application.getHttpApplication(Application.java:5
70)
at com.evermind.server.http.HttpSite$HttpApplicationRunTimeReference.cre
ateHttpApplicationFromReference(HttpSite.java:1987)
at com.evermind.server.http.HttpSite$HttpApplicationRunTimeReference.<in
it>(HttpSite.java:1906)
at com.evermind.server.http.HttpSite.initApplications(HttpSite.java:643)
at com.evermind.server.http.HttpSite.setConfig(HttpSite.java:290)
at com.evermind.server.http.HttpServer.setSites(HttpServer.java:270)
at com.evermind.server.http.HttpServer.setConfig(HttpServer.java:177)
at com.evermind.server.ApplicationServer.initializeHttp(ApplicationServe
r.java:2493)
at com.evermind.server.ApplicationServer.setConfig(ApplicationServer.jav
a:1042)
at com.evermind.server.ApplicationServerLauncher.run(ApplicationServerLa
uncher.java:131)
at java.lang.Thread.run(Thread.java:595)
ERROR - Unable to initialize Struts ActionServlet due to an unexpected exception
or error thrown, so marking the servlet as unavailable. Most likely, this is d
ue to an incorrect or missing library dependency.
java.lang.NullPointerException
at org.apache.commons.digester.Digester.getXMLReader(Digester.java:891)
at org.apache.commons.digester.Digester.parse(Digester.java:1572)
at org.apache.struts.action.ActionServlet.parseModuleConfigFile(ActionSe
rvlet.java:738)
at org.apache.struts.action.ActionServlet.initModuleConfig(ActionServlet
.java:687)
at org.apache.struts.action.ActionServlet.init(ActionServlet.java:333)
at javax.servlet.GenericServlet.init(GenericServlet.java:256)
at com.evermind.server.http.HttpApplication.loadServlet(HttpApplication.
java:2371)
at com.evermind.server.http.HttpApplication.findServlet(HttpApplication.
java:4824)
at com.evermind.server.http.HttpApplication.findServlet(HttpApplication.
java:4748)
at com.evermind.server.http.HttpApplication.initPreloadServlets(HttpAppl
ication.java:4936)
at com.evermind.server.http.HttpApplication.initDynamic(HttpApplication.
java:1145)
at com.evermind.server.http.HttpApplication.<init>(HttpApplication.java:
741)
at com.evermind.server.ApplicationStateRunning.getHttpApplication(Applic
ationStateRunning.java:414)
at com.evermind.server.Application.getHttpApplication(Application.java:5
70)
at com.evermind.server.http.HttpSite$HttpApplicationRunTimeReference.cre
ateHttpApplicationFromReference(HttpSite.java:1987)
at com.evermind.server.http.HttpSite$HttpApplicationRunTimeReference.<in
it>(HttpSite.java:1906)
at com.evermind.server.http.HttpSite.initApplications(HttpSite.java:643)
at com.evermind.server.http.HttpSite.setConfig(HttpSite.java:290)
at com.evermind.server.http.HttpServer.setSites(HttpServer.java:270)
at com.evermind.server.http.HttpServer.setConfig(HttpServer.java:177)
at com.evermind.server.ApplicationServer.initializeHttp(ApplicationServe
r.java:2493)
at com.evermind.server.ApplicationServer.setConfig(ApplicationServer.jav
a:1042)
at com.evermind.server.ApplicationServerLauncher.run(ApplicationServerLa
uncher.java:131)
at java.lang.Thread.run(Thread.java:595)
在网上找了N篇文章后(类似的文章极少,居然还有要收费的——晕),终于在一篇日文文章中找到一个解决方法,于是总结出下面一个完整的解决方案,希望给别人能带来点帮助。
三、【解决方案】
1、在项目的WEB-INF下面添加一个“orion-web.xml”的文件,里面的内容如下:
<?xml version="1.0"?>
<orion-web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://xmlns.oracle.com/oracleas/schema/orion-web-10_0.xsd"
deployment-version="10.1.3.1.0" deployment-time="1198656226301"
jsp-cache-directory="./persistence" jsp-cache-tlds="standard"
temporary-directory="./temp" context-root="accs"
schema-major-version="10" schema-minor-version="0">
<web-app-class-loader search-local-classes-first="true"
include-war-manifest-class-path="true" />
<web-app></web-app>
</orion-web-app>
【注】
1)、蓝色字体是最核心的部分。
2)、本OC4J的版本是Version 10.1.3.3.0。
3)、其他的版本只要添加蓝色部分即可。
其实orion-web.xml这个文件在每个应用中都有的,它在部署的时候自动生成。只不过有的文件中蓝色字体部分会被注释掉。该文件的位置就在application-deploy目录下,搜索一下就能找到)
2、把application-deploy下面对应项目的目录都删除。
3、然后重新启动中间件OC4J。
四、【问题分析】
1、OC4J自己提供系统的XML解析,不建议使用第三方的XML解析
OC4J已经自带了Oracle XML解析器。Oracle XML解析器与JAXP 1.1标准完全兼容,可服务于需要JAXP功能的应用程序场合。这种方式不需要下载、安装、配置其他的XML解析器。
Oracle XML解析器(xmlparserv2.jar)默认装载于OC4J的系统级库,通过包含oc4j.jar的Manifest.mf文件实现。这种机制可让Oracle XML解析器适用于所有普通的发布和打包的情况。
通过修改OC4J的配置文件来运行其他XML解析器或JDBC库是不被支持的。
【另一种解决方案】:把xerces放入其系统级类路径中
如果你一定要坚持使用像xerces这样的第三方XML解析器,那么当OC4J启动时,xerces.jar文件必须被装载于OC4J系统级类路径中。
可以使用JRE的Xbootclasspath标记来达到这一目的:
java -Xbootclasspath/a:d:\xerces\xerces.jar -jar oc4j.jar
-----------------------------------------------
正是因为OC4J提供了自己系统级别的XML解析,所以当我在jdk的jre的lib包下添加“jaxp.properties”这个文件时导致OC4J直接当掉,无法启动。
附:该文件中的内容:
javax.xml.parsers.SAXParserFactory=org.apache.xerces.jaxp.SAXParserFactoryImpl
javax.xml.parsers.DocumentBuilderFactory=org.apache.xerces.jaxp.DocumentBuilderFactoryImpl
------------------------------------------------
2、在加载系统应用时,优先加载项目自身的jar包
<web-app-class-loader search-local-classes-first="true"
include-war-manifest-class-path="true" />
解决完这个问题,真是开心啊。
============================================
补充:(2007-12-28)
今天又搜到一篇好文章,提供了另一种思路,英文好的可以看看
http://download.oracle.com/docs/cd/B12314_01/web.904/b10321/jkosfram.htm