osgi DBCP class.forName

来源:互联网 发布:cms安防监控客户端 编辑:程序博客网 时间:2024/06/09 18:19

Commons DBCP在OSGI环境中Cannot load JDBC driver class 'com.mysql.jdbc.Driver' 问题解决


在blueprint.xml中配置mysql的datasource,如下所示:

 <!-- MySQL DataSource -->
    <bean id="dataSourceMySQL" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/cbmsys" />
        <property name="username" value="root" />
        <property name="password" value="password" />
    </bean>
    
    <!-- Expose DataSource as JNDI reference -->
    <service id="cbmsysdb" ref="dataSourceMySQL" interface="javax.sql.DataSource">
        <service-properties>
            <entry key="osgi.jndi.service.name" value="jdbc/cbmsysdb" />
        </service-properties>
    </service>


    在OSGI环境运行后,系统报告 Cannot load JDBC driver class 'com.mysql.jdbc.Driver' , 而该Bundle已经增加了对com.mysql.jdbc的import,而且mysql jdbc connector也正常加载,出现该异常实在让人困惑。
    后来通过资料查询发现,在OSGI环境下使用Commons DBCP创建DataSource时发生此错误的不在少数,问题在于DBCP在实例化com.mysql.jdbc.Driver时采用了class.forName,检查我所采用的Commons DBCP 1.4 Jar包中的MANIFEST.MF中的Import-package,如下所示:

 

Import-Package: javax.naming,javax.naming.spi,javax.sql,javax.transaction,javax.transaction.xa,org.apache.commons.dbcp;version="1.4",org.apache.commons.dbcp.cpdsadapter;version="1.4",org.apache.commons.dbcp.datasources;version="1.4",org.apache.commons.dbcp.managed;version="1.4",org.apache.commons.jocl;version="1.4",org.apache.commons.pool,org.apache.commons.pool.impl,org.xml.sax,org.xml.sax.helpers


我们发现其中并没有"com.mysql.jdbc",所以在加载mysql时会报告ClassNotFoundException。其实这也是理所当然的,因为作为DBCP,如何在build时就知道我们会使用哪种数据库的驱动呢?而要解决此问题,有两种方法:
1)直接修改DBCP的Manifest.mf,在Import-Package中增加"com.mysql.jdbc",如果你用oracle,可以加入oracle的jdbc driver名称。这种方法有些暴力,比较直接。
2)另一种方法是不采用class.forName,在blueprint中修改DataSource的配置,如下:

<bean id="mysqlDataSource" class="com.mysql.jdbc.jdbc2.optional.
          MysqlConnectionPoolDataSource"><property name="createDatabaseIfNotExist" value="true"/><property name="url" value="${jdbc.url}"/><property name="user" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></bean><!-- Commons-DBCP --><bean id="dataSource" class="org.apache.commons.dbcp.datasources.
            SharedPoolDataSource" lazy-init="false" destroy-method="close"><property name="connectionPoolDataSource" ref="mysqlDataSource"/><property name="maxActive" value="20"/><property name="maxIdle" value="3"/></bean><!-- c3p0 --> <!-- not tested yet, but should work same way<bean id="dataSource2" class="com.mchange.v2.c3p0.ComboPooledDataSource"
                lazy-init="false"><property name="connectionPoolDataSource" ref="mysqlDataSource"/><property name="maxPoolSize" value="15"/><property name="minPoolSize" value="3"/></bean>--><!-- export the existing datasource bean into OSGi --><osgi:service id="classificationDataSource" ref="dataSource"><osgi:interfaces><value>javax.sql.DataSource</value></osgi:interfaces></osgi:service>


在bundle中增加import  "com.mysql.jdbc. jdbc2.optional",先创建“com.mysql.jdbc.jdbc2.optional.          MysqlConnectionPoolDataSource”,然后在dbcp中配置"connectionPoolDataSource"属性进行初始化即可。


0 0