因为想体验一把Spring2.0基于aop名称空间的AOP和Hibernate3.2比EJB3.0的JPA还要细致强大的annotation等等新特征,特地跑到
SpringSide(一个基于Spring核心的强大而优雅的企业快速开发框架)去下载了完整的开发包。记得要先照它介绍的方式运行起来,只要双击个.bat文件程序,数据库(
HSQLDB),服务器(
Tomcat5.5)就全部署好了,范例就已经跑起来了,非常吸引人。但是我一般用的是
Resin3 ,所以我打算停了Tomcat跑起我的Resin,这时候一向听话的Resin居然开始撒娇了。
配好路径启动Resin,调试信息如下:
1Resin-3.0.19 (built Mon, 15 May 2006 04:50:47 PDT)
2Copyright(c) 1998-2006 Caucho Technology. All rights reserved.
3
4 Using Resin(R) Open Source under the GNU Public License (GPL).
5
6 See http://www.caucho.com for information on Resin Professional,
7 including caching, clustering, JNI acceleration, and OpenSSL integration.
8
9Starting Resin on Wed, 24 Jan 2007 21:25:59 +0800 (CST)
10
11[21:26:02.375] Server[] starting
12[21:26:02.375]
13[21:26:02.375] Windows XP 5.1 x86
14[21:26:02.375] Java 1.5.0_10-b03, 32, mixed mode, GBK, zh, Sun Microsystems Inc.
15[21:26:02.375] resin.home = D:\resin-3.0.19
16[21:26:02.375] server.root = null
17[21:26:02.375]
18[21:26:02.484] http listening to *:8080
19[21:26:02.546] hmux listening to localhost:6802
20[21:26:02.765] Host[] starting
21[21:26:03.890] com.caucho.config.LineConfigException: WEB-INF/web.xml:4: bad character fffd
22[21:26:04.781] WebApp[http://localhost:8080/resin-doc] starting
23[21:26:04.953] Resin started in 3000ms
注意红色的信息,读取web.xml异常了,我四级都没过的英语也看出来了是字符错误,相信大家也看出来了吧。凭着经验判定是文件编码的问题,用eclipse打开web.xml果然中文部分有乱码。一向都觉得Resin在编码的处理上,特别是中文编码上比Tomcat5要好很多。今天怎么会出现这种奇怪的问题,带着疑问继续往下看吧。我当时想还是先跑起来再说,老老实实的把编码都转一下吧。
告诉大家一个转文件编码最简单的办法,就是把文件用windows自带的记事本程序打开,选择菜单“文件”-“另存为”,然后在另存为的界面把文件类型选择为“所有文件”,编码选择为“UTF-8”,选择目标文件覆盖保存。
转了编码后发现注释中有两个显示不了的字符,反正是注释索性就删掉了。修改后再次启动Resin,果然正常了。但是又出现了更郁闷的问题。部分调试信息如下:
12007-01-24 22:44:02,125 ERROR [org.springframework.web.context.ContextLoader] - <Context initialization failed>
2org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from file [D:\projects\SSHelloWorld\webapp\WEB-INF\classes\spring\applicationContext.xml]; nested exception is java.lang.IllegalArgumentException: Bean name must not be empty
3Caused by:
4java.lang.IllegalArgumentException: Bean name must not be empty
5 at org.springframework.util.Assert.hasText(Assert.java:161)
6 at org.springframework.beans.factory.config.RuntimeBeanReference.<init>(RuntimeBeanReference.java:58)
7 at org.springframework.beans.factory.config.RuntimeBeanReference.<init>(RuntimeBeanReference.java:46)
8 at org.springframework.transaction.config.AnnotationDrivenBeanDefinitionParser.parseInternal(AnnotationDrivenBeanDefinitionParser.java:76)
9 at org.springframework.beans.factory.xml.AbstractBeanDefinitionParser.parse(AbstractBeanDefinitionParser.java:56)
10 at org.springframework.beans.factory.xml.NamespaceHandlerSupport.parse(NamespaceHandlerSupport.java:78)
11 at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1147)
12 at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1137)
13 at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:145)
14 at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:89)
15 at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registerBeanDefinitions(XmlBeanDefinitionReader.java:499)
16 at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:407)
17 at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:357)
18 at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:334)
19 at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:126)
20 at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:142)
21 at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:123)
22 at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:91)
23 at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:94)
24 at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:294)
25 at org.springframework.web.context.support.AbstractRefreshableWebApplicationContext.refresh(AbstractRefreshableWebApplicationContext.java:156)
26 at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:246)
27 at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:184)
28 at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:49)
29 at com.caucho.server.webapp.Application.start(Application.java:1597)
30 at com.caucho.server.deploy.DeployController.startImpl(DeployController.java:621)
31 at com.caucho.server.deploy.StartAutoRedeployAutoStrategy.startOnInit(StartAutoRedeployAutoStrategy.java:72)
32 at com.caucho.server.deploy.DeployController.startOnInit(DeployController.java:509)
33 at com.caucho.server.deploy.DeployContainer.start(DeployContainer.java:158)
34 at com.caucho.server.webapp.ApplicationContainer.start(ApplicationContainer.java:652)
35 at com.caucho.server.host.Host.start(Host.java:385)
36 at com.caucho.server.deploy.DeployController.startImpl(DeployController.java:621)
37 at com.caucho.server.deploy.StartAutoRedeployAutoStrategy.startOnInit(StartAutoRedeployAutoStrategy.java:72)
38 at com.caucho.server.deploy.DeployController.startOnInit(DeployController.java:509)
39 at com.caucho.server.deploy.DeployContainer.start(DeployContainer.java:158)
40 at com.caucho.server.host.HostContainer.start(HostContainer.java:501)
41 at com.caucho.server.resin.ServletServer.start(ServletServer.java:977)
42 at com.caucho.server.deploy.DeployController.startImpl(DeployController.java:621)
43 at com.caucho.server.deploy.AbstractDeployControllerStrategy.start(AbstractDeployControllerStrategy.java:56)
44 at com.caucho.server.deploy.DeployController.start(DeployController.java:517)
45 at com.caucho.server.resin.ResinServer.start(ResinServer.java:485)
46 at com.caucho.server.resin.Resin.init(Resin.java)
47 at com.caucho.server.resin.Resin.main(Resin.java:624)
一看错误是Bean name must not be empty,bean的名字不能为空?为什么啊,没听说过啊,不管是Spring的官方文档,范例还是看的书上教授的都没有听说这么一回事情啊。没天理啊,运行个HelloWorld也这么费力。。。马上抱起错误就去找Google,居然搜不到。。。(正因为GOOGLE搜索不到相关的解决,所以我特地写了这篇文章与大家分享)不会吧,难道大家都没碰到过,我的人品问题?Google也没办法找到的问题,我只好翻找Spring的源代码。查看org.springframework.util.Assert.hasText类,原来抛出java.lang.IllegalArgumentException异常不是按字面意思理解的bean名字不能为空,先汗自己!不过在这个类里面也没找到具体的原因。难道还要继续往前翻找源代码?虽然看大师们的作品是种享受,但是注定我运行HelloWorld就搞成这样?并且查源代码也不是一时能找的出问题的。
停止服务,启动服务,停止服务,启动服务。。。反复的反复,问题依然。换回Tomcat去,一切正常。。。彻底崩溃,难道resin上跑不起Spring?Spring容器可是JAVA原生的动态代理方式实现,完全应该具备JAVA的“一次编写到处运行”。我看到的文档和书籍也无一不盛赞它的Web服务器,应用服务器无关。我想一定是哪里配置有问题,我又把每个xml配置文件都翻了个遍,依然找不出问题。
我突然想起曾经看过的一篇关于JAVA XML的文章,好像JAVA默认的XML解析用的是Crimson,不如另一个XML解析实现Xerces ,莫非是Resin用的解析不行?抱着死马当活马医的态度配上了xerces。
配置xerces方法如下:
1.在VM级
首先在CLASSPATH下放置xerces相关的包,然后在JRE\lib\目录下建一个jaxp.properties的文件,用来声名替换解析器,jaxp.properties内容如下:
1javax.xml.parsers.DocumentBuilderFactory=org.apache.xerces.jaxp.DocumentBuilderFactoryImpl
2javax.xml.parsers.SAXParserFactory=org.apache.xerces.jaxp.SAXParserFactoryImpl
注意:必须建立此文件显示声明,如果只是引入了xerces的相关包,由于JDK的Class Loader的优先级关系,还是会很顽固的使用Crimson。
2.在web服务器级(Resin3.0.19为例)
把xerces相关包放入容器的CLASSPATH中(Resin主目录下的lib目录),然后在配置文件resin.conf(Resin主目录下的conf目录中resin.conf文件)中的server节点中加入如下XML代码:
1<system-property javax.xml.parsers.DocumentBuilderFactory="org.apache.xerces.jaxp.DocumentBuilderFactoryImpl"/>
2 <system-property javax.xml.parsers.SAXParserFactory="org.apache.xerces.jaxp.SAXParserFactoryImpl"/>
声明调用xerces实现XML解析。
JAVA XML相关内容推荐参阅:
http://www-900.ibm.com/developerWorks/cn/xml/x-injava/index.shtml
http://www-900.ibm.com/developerWorks/cn/xml/x-injava2/index.shtml
http://www-900.ibm.com/developerWorks/cn/xml/x-databdopt/part2/index.shtml
http://www-900.ibm.com/developerWorks/cn/xml/x-databdopt/part1/index.shtml
我在Resin中配置好xerces后,启动。WebApplicationContext初始化正常,Struts初始化正常,一切正常,终于看到了界面。
然后我又想刚才web.xml中的错误会不会也是因为没有用xerces的原因,把原来没修改的web.xml又拷了一个过来,启动依然报同样的错,仔细再看文件里面确实在最开始的注释中有两个错误的字符,不知道SpringSide的大侠们是故意的还是不小心弄错了。。。删除错误字符启动,成功!
总结如下:
1. web.xml中是以为确实存在错误的字符导致web容器无法初始化,修改文件后就正常了。
2. Resin读取Spring的配置文件必须显示采用xerces,否则无法初始化Spring容器。建议配置服务器级的xerces。
3. 平时开发和学习过程中应广泛涉猎,拓宽知识面。碰到问题大胆假设,联想,细心调试。最后再纠根问底,彻查明白。
4. 遇到问题不轻易放弃,多思考,多总结,多记录。
posted on 2007-01-25 00:29
cresposhi 阅读(5547)
评论(10) 编辑 收藏