Classpath的狐疑
昨天在家里整理我的宝物硬盘时,发明之前的一个基于JSP布局的电子生意业务平台的源码,并且尚有数据库,横竖也没事,于是就想弄一下,让它跑起来。接下来,下载安装Tomcat和SqlServer的JDBC驱动(JDK之前就安装过),颠末一系列的设置,通过测试JSP可以或许正常运行,JavaBean也可以或许正确运行,Servlet也可以或许正确运行,看样子情况应该没有问题。紧接着要害的部门就要来到了。我把SqlServer的JDBC驱动的三个JAR包放到了系统的classpath里,然后,启动Tomcat,而且火烧眉毛的在欣赏器地点栏里输入http://localhost:80/IC/,悄悄地期待着系统的呈现。系统终于跑起来了,但是看到的跟我的想象的纷歧样,界面上每每有对数据库的会见的处所都呈现了“Thisconnectionhasnotbeenestablishedyet.”,很显然问题出在和数据库的毗连上。
颠末阐明发明,系统对数据库的会见是透过一个JavaBean来实现的。于是,我把这个JavaBean的源码拷到了雷同于记事本一样的文本编辑器里,而且加了main要领,来测试这个类是否事情正常。编译获得class文件后,用javaxxx来执行,从输出来看,没有问题。但问题到底出在那边呢?于是,我又把这段代码拷贝到Eclipse的一个工程里,编译执行后,报的错跟会见JSP的错是一样的,进一步跟踪发明,在Class.forName(“com.microsoft.jdbc.SQLServerDriver”);时报类没有找到,也就是说没有找到类SQLServerDriver,再打开mssqlserver.jar一看,类SQLServerDriver赫然在立,路径也没有错。我显着在classpath里加载了三个JAR包啊,为什么在呼吁行方法可以找到,在Eclipse里反倒没有找到呢?太让人狐疑了!周末的好脸色完全被这个问题搅乱了,而且静静下定刻意,必然要办理尔后快。接下来,就是上论坛问人,尚有就是在QQ和MSN上找人问,同时,本身也在阐明大概的原因,举办实验。
遐想到事情中常常把用到的JAR包城市加到项目标类路径中,于是,我也把三个JAR包添加到项目标类路径中,然后从头编译执行,发明问题没有了,输出正常。此时,我就劈头断定问题出在Eclipse里执行类时加载的包跟系统的classpath指定的纷歧致,也就是说系统的classpath指定的类基础就没有加载到内存,所以就会报找不到类,而在呼吁行方法,加载的就是系统的classpath指定的包。问题固然明晰定位了,但详细是什么原因,我照旧无法表明。团结在JSP里,我如安在启动Tomcat时先把三个jar包加载到内存呢?我写了个批处理惩罚文件,内容是set classpath=E:\xxxxx\msbase.jar;E:\ xxxxx\mssqlserver.jar;E:\ xxxxx\msutil.jar;我在呼吁行方法下,先执行这个批处理惩罚,然后,在执行启动Tomcat的呼吁,厥后发明,依旧报错,说明这样加载jar包有问题。到这里,我险些都想放弃了,想不到居然被这个classpath搞得焦头乱额,郁闷啊!但要我放弃,还真是不平气!照旧休息一下,转头再来!
在客堂转了一下,弄了点对象吃了,感受有点困,于是就睡去了。一觉睡了两个小时,起来的时候天色已暗,于是,又回到计较机旁,想想奈何才气搞定它!于是,在大脑里搜索事情中跟classpath有关的一些问题,以及办理要领。依稀记得,在Jdk的jre\lib\ext里的jar包,java是本身会自动加载的,于是,我又把三个jar包拷到这里,从头启动tomcat,在欣赏器地点栏里输入会见解点,悄悄的期待今后,系统终于没有报之前的错误了,数据库毗连正常了,终于跑起来了。我重重的舒了口长气,不容易啊。
到这里系统跑起来了,但classpath并没有彻底搞大白,我只是绕开了这个问题。本日一上班,我就想问南哥,但思量到礼拜一上午各人城市较量忙,我忍住了。在中午快用饭的时候,我照旧问了这个问题。南哥的表明是,在呼吁行方法,java本身会加载系统的classpath里指定的包,而在Eclipse等开拓情况里,系统加载的是开拓情况的classpath。这个表明,跟我的尝试环境完全吻合,听起来也没有问题。为了进一步确认在两种场景下classpath加载内容有什么差异,南哥发起我用System.getProperties()看看到底有什么差别?当我较量两种环境下的输出时,困扰了我一天的classpath问题,彻底弄大白了:通过呼吁行方法,来java xxxx时,会加载系统的classpath里的包,其方法是java.class.path=””,同时还会通过sun.boot.class.path=””的方法来加载jdk下的jre\lib\下的jar包,对付ext目下的包的加载,应该是通过java.ext.dirs=W:\jdk\jre\lib\ext来举办的,但这里没有详细的包名;通过IDE情况来执行java措施时,会加载情况指定的jar包。
编后:
在呼吁行方法下,通过我先执行加载情况的批处理惩罚,后启动Tomcat和直接启动Tomcat获得的两份系统属性,比拟个中的java.class.path来看,两者完全一样,亦即在当前的利用场景下想通过批处理惩罚来加载jar包,是行不通的.进一步实验,在纯真的呼吁行方法下通过批处理惩罚来加载jar包,然后执行java xxxx,跟踪系统属性获得的java.class.path跟批处理惩罚要求加载的完全一致.另一方面,在tomcat的webapp下成立本身的应用譬喻Test,然后在Test的WEB-INF目次下,成立目次lib,把你的jar包放到这里,也可以让tomcat找到你要加载的类.文中在前面提到,把jar放到jre\lib\ext\下系统可以或许运行,说明也没有问题,在tomcat的利用场景下,发起回收放到WEB-INF的lib目次下的方法.这样处理惩罚,很显然的一个长处是加强了系统的可移植性.