我有一个Spring mvc应用程序,我正在IBM WebSphere Application Server Liberty Profile上部署,该应用程序应该访问本地托管的mysql数据库服务器。我在sever.xml文件中添加了如下数据源配置
<dataSource id="springdb" jndiName="jdbc/springdb">
<jdbcDriver javax.sql.XADataSource="com.mysql.cj.jdbc.Driver" libraryRef="mysqlJDBCLib"/>
<properties databaseName="spring_db" password="**********" portNumber="3306" serverName="localhost" user="root"/>
</dataSource>
<library id="mysqlJDBCLib">
<fileset dir="/opt/IBM/WebSphere/Liberty_16.0.0.4/usr/shared/resources/mysql" includes="mysql-connector-java-6.0.6.jar"/>
</library>
我得到以下堆栈跟踪
Caused by: java.lang.RuntimeException: java.sql.SQLNonTransientException: DSRA4000E: A valid JDBC driver implementation class was not found for the jdbcDriver dataSource[springdb]/jdbcDriver[default-0] using the library mysqlJDBCLib. [/opt/IBM/WebSphere/Liberty_16.0.0.4/usr/shared/resources/mysql/mysql-connector-java-6.0.6.jar]
at com.ibm.ws.resource.internal.ResourceFactoryTrackerData$1.getService(ResourceFactoryTrackerData.java:123)
... 77 more
Caused by: java.sql.SQLNonTransientException: DSRA4000E: A valid JDBC driver implementation class was not found for the jdbcDriver dataSource[springdb]/jdbcDriver[default-0] using the library mysqlJDBCLib. [/opt/IBM/WebSphere/Liberty_16.0.0.4/usr/shared/resources/mysql/mysql-connector-java-6.0.6.jar]
at com.ibm.ws.jdbc.internal.JDBCDriverService.classNotFound(JDBCDriverService.java:196)
... 77 more
Caused by: java.lang.ClassNotFoundException: com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource
at com.ibm.ws.classloading.internal.AppClassLoader.findClassCommonLibraryClassLoaders(AppClassLoader.java:499)
... 77 more
我试过以下
用com.mysql.jdbc.Driver替换com.mysql.cj.jdbc.Driver并且字符串出现同样的错误
用javax.sql.DataSource替换javax.sql.XADataSource但仍然出现同样的错误
用javax.sql.MysqlConnectionPoolDataSource替换javax.sql.XADataSource,同样的错误
将mysql连接器jar从mysql-connector-java-6.0.6.jar切换到mysql-connector-java-5.1.45-bin.jar,仍然是同样的错误(两个jar都在那里指定的文件路径)
答案 0 :(得分:6)
有关数据源配置的背景信息:
对于所有数据源(id="DefaultDataSource"
除外),以下列优先级选择DataSource的类型:
type
元素上配置的<dataSource>
类(如果已配置)(根据Configuring relational database connectivity in Liberty)
如果没有为类型定义类,则将检查下一个最低优先级。
默认情况下,Liberty将扫描以使用以下优先级来查找数据源实现类名称:
<jdbcDriver>
元素<properties.DRIVER_TYPE>
元素的默认类。请注意,只有一些JDBC驱动程序具有自己的元素类型。对于没有自己的属性元素(例如MySQL)的JDBC驱动程序,请使用通用<properties>
元素 您的配置无效的原因
您已将<jdbcDriver>
元素配置为&#34;将此特定类用于XADataSource&#34;&#34;但是,您配置的<dataSource>
元素不是试图创建XADataSource
。使用上面提到的优先级顺序,它将首先尝试创建ConnectionPoolDataSource
(Liberty已在内部映射到com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource
。
解决问题:
<dataSource .. type="javax.sql.XADataSource">
,以便Liberty尝试创建XADataSource
而不是ConnectionPoolDataSource
。然后,当它尝试创建XADataSource
时,它会查看您在<jdbcDriver>
元素上配置的类名。javax.sql.XADataSource
属性(com.mysql.cj.jdbc.MysqlXADataSource
)的XADataSource类名,而不是java.sql.Driver实现类名。所以你的最终配置如下:
<dataSource id="springdb" jndiName="jdbc/springdb" type="javax.sql.XADataSource">
<jdbcDriver javax.sql.XADataSource="com.mysql.cj.jdbc.MysqlXADataSource" libraryRef="mysqlJDBCLib"/>
<properties databaseName="spring_db" password="**********" portNumber="3306" serverName="localhost" user="root"/>
</dataSource>
<library id="mysqlJDBCLib">
<fileset dir="/opt/IBM/WebSphere/Liberty_16.0.0.4/usr/shared/resources/mysql" includes="mysql-connector-java-6.0.6.jar"/>
</library>
答案 1 :(得分:3)
如果您未在type
config元素中指定dataSource
属性,Liberty将尝试根据驱动程序jar文件名推断要加载的数据源类。在您的示例中,它基于以前的mySQL驱动程序错误地推断实现类名称。似乎mySQL已经改变了DataSource,ConnectionPoolDataSource和XADataSource的实现的包名。我会为此打开一个git问题。在此期间,您只需使用type
配置元素的dataSource
属性指定要创建的数据源类型,然后使用jdbcDriver
更新您的javax.sql.DataSource="com.mysql.cj.jdbc.MysqlDataSource"
配置元素即可到正确的mysql驱动程序类。相反,如果您需要conn池或XA数据源,只需更新type
dataSource
属性以识别类型并使用驱动程序类impl更新jdbcDriver
。