WebOTX是NEC公司的Application Server产品.我使用的版本是5.3.它的Web Container是Tomcat4.0.在WebOTX中配置JNDI数据源曾经颇费周折.下面就简单介绍其中的一个方面. 一般来说,只要在服务器端进行正确的配置,从JNDI中拿到的对象是不会出现问题的.但是,如果服务器本身就是有缺失的,如它在启动的过程中少装载一个JAR包,或者说服务器自身环境配置就存在问题,那就有可能出现意想不到的情况.
在服务器中配置JNDI数据源(javax.sql.DataSource)时,不同的服务器中lookup得到的Object是不同的.在Tomcat5中得到的是org.apache.commons.dbcp.BasicDataSource类,在Jboss3.2中得到的是org.jboss.resource.adapter.jdbc.WrapperDataSource类,在WebOTX5.3中得到的是jp.co.nec.WebOTX.WODataSource类.所有的这些类都实现了javax.sql.DataSource接口,所以我们才可以Cast这个Object为javax.sql.DataSource.
但是,如果服务器启动时,它的类装载系统没有导入包含这些类的JAR包,那么,不同的服务器就会出不同的错误.
对于Tomcat,错误发生在实际动作时,即lookup方法被调用的地方.它会出一个ClassNotFoundException异常.
对于JBoss,错误发生在服务器启动时(错误的原因就是类缺失).也就是说,JBoss中的对象Bind动作是在服务器启动时完成的.如果在发生服务器启动错误的情况下仍然进行lookup动作,就会出现javax.naming.NameNotFoundException异常.
对于WebOTX,错误也是发生在实际动作时.但是它和Tomcat不同的是,它出一个ClassCastException异常.这个异常说明不是类装载器的问题,而是的确lookup到了一个Object,但这个Object不是javax.sql.DataSource接口.就像前面所说的,得不到DataSource的真正原因就是由于类路径(是指类装载器委托模型中的类,它并不等同于CLASSPATH,相反CLASSPATH只是其中的一部分)不全,这说明在WebOTX中lookup时抛出的ClassCastException异常掩盖了原始的异常信息.掩盖的根本原因是,原始的异常信息被WebOTX服务器处理了,并且处理后并没有把异常信息告诉它的客户程序.
Java异常处理的一个规则就是不要遮蔽异常.因为一旦出现这种情况,而客户程序又非常想知道错误原因,那么就可能丢失问题真正原因的线索.
这个错误也提供了一个WebOTX5.3不成熟的证据.
出现这种情况,就只能从lookup得到的Object来查找线索了.结果发现Object是javax.naming.Reference对象,这就说明了错误是由类路径不全造成的.但是又暴露了WebOTX的另外一个问题---类装载器.
一个设计良好的应用框架系统,是有必要建立自己的类装载系统的,而不能过分依赖系统CLASSPATH变量.例如,Tomcat有自己的类装载机制,JBoss也是.Eclipse则干脆不用系统CLASSPATH变量.具体信息请参照它们的文档.
如果过分依赖CLASSPATH,就会有一个副作用,就是造成自身系统的不稳定.因为CLASSPATH是开放的,无法确保其它应用对它的修改不会对自身系统产生负面影响.
WebOTX 就是一例.它的Web Container就是Tomcat,除了把一些JAR包放在了Tomcat认可的目录下外,它把有些JAR包就设置到了系统CLASSPATH变量下. 造成的问题就是,连启动它的Web Container都成了一件困难的事情.这又是一个证据.
|