这个搞了我两天的问题算的上我至今遇到的最蛋疼的问题了,似乎网上有人也遇到过,但是他们的情况都与我不一样,问题的根源是
mysql.jdbc包的版本不对.先贴上异常:
Exception in thread "main" org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:244)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:208)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:189)
at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:51)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:94)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:217)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:189)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.handleTypes(MetadataBuildingProcess.java:352)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:111)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.build(MetadataBuildingProcess.java:83)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:418)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:87)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:692)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:724)
at cn.itheima.test.MyTestForHibernate.main(MyTestForHibernate.java:23)
Caused by: org.hibernate.boot.registry.classloading.spi.ClassLoadingException: HHH010003: JDBC Driver class not found: com.mysql.jdbc.Driver
at org.hibernate.c3p0.internal.C3P0ConnectionProvider.configure(C3P0ConnectionProvider.java:131)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:94)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:217)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:189)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.buildJdbcConnectionAccess(JdbcEnvironmentInitiator.java:145)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:66)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:88)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:234)
... 14 more
Caused by: org.hibernate.boot.registry.classloading.spi.ClassLoadingException: Unable to load class [com.mysql.jdbc.Driver]
at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.classForName(ClassLoaderServiceImpl.java:232)
at org.hibernate.c3p0.internal.C3P0ConnectionProvider.configure(C3P0ConnectionProvider.java:128)
... 22 more
Caused by: java.lang.NoClassDefFoundError: org/aspectj/lang/Signature
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:274)
at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.classForName(ClassLoaderServiceImpl.java:226)
... 23 more
Caused by: java.lang.ClassNotFoundException: org.aspectj.lang.Signature
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
... 26 more
再说说解决问题的思路,首先观察异常栈,初一看是找不到org.aspectj.lang.Signature,通过加入这个类,这个异常消失了,但是程序还是不能走,最后又报空指针异常,最开始我从空指针异常出发去寻找问题,发现是大海捞针.我又回到问题的原点去思考,为什么加载com.mysql.jdbc.Driver会用到aspectj,看上去很奇怪.于是我开始在异常栈的每一个方法入口加断点.发现在加载com.mysql.jdbc.Driver的Class.forName()在接受到"com.mysql.jdbc.Driver",true,和一个classloader这三个参数后发生了异常,进入此方法真正起到作用的一个叫forName0()的native 方法,由于是本地方法,所以很难找到代码,找到估计也很难看懂.于是写测试程序,在对三个参数都进行控制变量的试验后发现在把第二个参数由true改为false后,问题消失.所以基本可以确定是在类加载器加载完后,对类的初始化的时候引用了不在build path 中的 org.aspectj.lang.Signature导致错误.引入一个aspectj的包确实能治标,但是不能治本,这就说明问题的本源出现在com.mysql.jdbc.Driver的兼容性上(其他未知的原因?),通过将mysql-connector-java包由5.0.8换成5.1.7.问题全部消失.由于在maven的中央仓库中找不到5.0.8的源码,我也实在没力气再去探索5.0.8的包的问题了.
这件事情还有一个蛋疼的剧情,那就是在我导入别人电脑上能跑的demo代码后发现还是不行,结果发现不知道什么时候无意中在tomcat的lib文件夹中放入了一个5.0.8的mysql-connector-java包.结果由于tomcat的库build的order在web库之前,导致,在发生包冲突的时候总是引入5.0.8的版本的jar包.通过设置buildpath中的order and export也能解决问题.
总结:此次虽然花了点时间,但是还是有收获的:
1.在解决问题的过程中,对debug,异常,类加载,class文件格式等的基础知识巩固加强了,基础真的很重要.基础不好的永远是在等别人给他指路,自己是瞎子,找不到方向.2.第三方jar包的依赖有时候蛮蛋疼的,所有的第三方代码都会提出对JDK的要求,但是他们自己之间的不协调就很难知晓,如果不去仔细的看他们的文档,甚至查看代码,想要独立搭建系统估计很困难,这可能是框架式开发中的一个大难题了.4.框架和常用工具的文档和代码有空还是要看看,只有真正明白他们的工作原理和细节,处理一些问题才能得心应手.4.有的时候debug的思路比技巧还要重要,一定要多思考和实验.