我有三个项目,Web,EJB3,JPA实体。 EJB3和JPA-entities项目将作为jar文件导出到Web / WebContent / WEB-INF / lib中。 我还将MySQL驱动程序jar文件放在“WEB-INF / lib”中。
但是...
jboss找不到MySQL驱动程序... 以下是persistence.xml:
<persistence-unit name="HandShakeEntity">
<class>net.magidea.handshake.entity.User</class>
<class>net.magidea.handshake.entity.UserItem</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.connection.username" value="root" />
<property name="hibernate.connection.password" value="dj/4ej03" />
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/handshake" />
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
</properties>
</persistence-unit>
并记录:
13:09:26,070 ERROR [org.jboss.msc.service.fail] (ServerService Thread Pool -- 48) MSC000001: Failed to start service jboss.persistenceunit."HandShakeWeb.war#HandShakeEntity": org.jboss.msc.service.StartException in service jboss.persistenceunit."HandShakeWeb.war#HandShakeEntity": javax.persistence.PersistenceException: [PersistenceUnit: HandShakeEntity] Unable to build EntityManagerFactory
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1.run(PersistenceUnitServiceImpl.java:103) [jboss-as-jpa-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) [rt.jar:1.7.0_07]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) [rt.jar:1.7.0_07]
at java.lang.Thread.run(Thread.java:722) [rt.jar:1.7.0_07]
at org.jboss.threads.JBossThread.run(JBossThread.java:122) [jboss-threads-2.1.0.Final-redhat-1.jar:2.1.0.Final-redhat-1]
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: HandShakeEntity] Unable to build EntityManagerFactory
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:930)
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:904)
at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:92)
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl.createContainerEntityManagerFactory(PersistenceUnitServiceImpl.java:200) [jboss-as-jpa-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl.access$600(PersistenceUnitServiceImpl.java:57) [jboss-as-jpa-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1.run(PersistenceUnitServiceImpl.java:99) [jboss-as-jpa-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]
... 4 more
Caused by: org.hibernate.service.classloading.spi.ClassLoadingException: Specified JDBC Driver com.mysql.jdbc.Driver could not be loaded
at org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl.configure(DriverManagerConnectionProviderImpl.java:111)
at org.hibernate.service.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:75)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:159)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:131)
at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.buildJdbcConnectionAccess(JdbcServicesImpl.java:223)
at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:89)
at org.hibernate.service.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:75)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:159)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:131)
at org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:78)
at org.hibernate.cfg.Configuration.buildSettingsInternal(Configuration.java:2283)
at org.hibernate.cfg.Configuration.buildSettings(Configuration.java:2279)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1748)
at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:94)
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:920)
... 9 more
Caused by: org.hibernate.service.classloading.spi.ClassLoadingException: Unable to load class [com.mysql.jdbc.Driver]
at org.hibernate.service.classloading.internal.ClassLoaderServiceImpl.classForName(ClassLoaderServiceImpl.java:149)
at org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl.configure(DriverManagerConnectionProviderImpl.java:106)
... 23 more
Caused by: java.lang.ClassNotFoundException: Could not load requested class : com.mysql.jdbc.Driver
at org.hibernate.service.classloading.internal.ClassLoaderServiceImpl$AggregatedClassLoader.findClass(ClassLoaderServiceImpl.java:296)
at java.lang.ClassLoader.loadClass(ClassLoader.java:423) [rt.jar:1.7.0_07]
at java.lang.ClassLoader.loadClass(ClassLoader.java:356) [rt.jar:1.7.0_07]
at java.lang.Class.forName0(Native Method) [rt.jar:1.7.0_07]
at java.lang.Class.forName(Class.java:264) [rt.jar:1.7.0_07]
at org.hibernate.service.classloading.internal.ClassLoaderServiceImpl.classForName(ClassLoaderServiceImpl.java:146)
... 24 more
我找到了一个意外的解决方案。 如果我将MySQL驱动程序jar放入[JBoss EAP 6.1 Home] \ modules \ system \ layers \ base \ org \ hibernate \ main, 并更新module.xml以包含驱动程序jar,它工作正常,但我不知道为什么我的Web应用程序与hibernate模块有任何关系。
答案 0 :(得分:4)
这是因为类加载在JEE环境中的工作方式。您会看到,存在嵌套的类加载器,Web应用程序类加载器位于层次结构的末尾。这意味着虽然web-app类加载器可以看到由其父级加载的类,但它的父级无法看到子级加载的类(web-app CL)。
在JEE环境中,您拥有系统类加载器(一如既往),然后会有一个应用程序服务器类加载器(加载API - 例如javax.servlet.*
和特定于应用程序服务器的实现)。最后,每个EAR都有一个类加载器,然后是每个WAR的类加载器,如:
system CL
|
+- Application server CL (loads e.g. Hibernate as the JPA implementation)
|
+- EAR 1 CL
| |
| +- WAR 1_1 CL
| |
| +- WAR 1_2 CL
|
+- WAR 1 CL (In your case, this loads the MySQL driver)
(这是过于简单的,只是为了演示原则)上面树中的每个孩子都看到由其父母加载的类,但 NOT 类由其自己的孩子或同伴加载。
在你的情况下,MySQL驱动程序JAR放在WEB-INF/lib
中,即由web-app CL加载,但JPA实现(Hibernate)由父CL加载。此CL尝试查找驱动程序的类,并因上述原因而失败。这也是将驱动程序放在modules/
时工作的原因,因为这是父CL的类路径,即加载Hibernate的类。
在任何情况下,我认为解决方案是将驱动程序放在modules/
中,如this的“安装JDBC驱动程序”部分所述。如果您有充分的理由在应用程序中捆绑东西,那么您也必须捆绑JPA实现(即将Hibernate JAR放在EB-INF/lib
中)。