0

MySQLをApacheFelixに統合します。まず、bndtoolsを使用してMySQLバンドルとc3p0バンドルを生成します。次に、それらすべてをApacheFelix環境に追加します。以下のように接続プールのクラスを作成します。

    パブリックファイナルクラスC3P0Manager{

        プライベート静的C3P0Managerインスタンス。
        プールされたプライベートデータソース。

        プライベートC3P0Manager(){
            //もちろん、すべてのプロパティを構成ファイルに入れることをお勧めします。
            //読みやすいように、ここにリストします。

            ComboPooledDataSource cpds = new ComboPooledDataSource();
            cpds.setDriverClass( "com.mysql.jdbc.Driver"));
            cpds.setJdbcUrl( "jdbc:mysql:// localhost / my-database?autoReconnect = true&characterSetResults = UTF-8&characterEncoding = UTF-8&useUnicode = yes");
            cpds.setUser( "user");
            cpds.setPassword( "password");
            cpds.setInitialPoolSize(3);
            cpds.setMaxPoolSize(15);
            cpds.setMaxIdleTime(1800);
            cpds.setAutoCommitOnClose(true);
            pooled(cpds);
        }

        public static C3P0Manager instance()は例外をスローします{
            if(instance == null){
                インスタンス=新しいC3P0Manager();
            }
            インスタンスを返します。
        }

        public DataSource getPooled()はSQLException{をスローします
            プールされたリターン。
        }
    }

JUnitテストを実行すると正常に動作します。しかし、Apache Felixバンドルで実行すると、例外メッセージが表示されて失敗しました。Activatorクラスでの使用法:

    Class.forName( "com.mysql.jdbc.Driver");
    プールされたデータソース=C3P0Manager.instance()。getPooled();
    接続con=pooled.getConnection();
    PreparedStatement stmt = null;
    ResultSet rs = null;
    int合計;

    試す {
        stmt = con.prepareStatement( "SELECT count(*)FROM users"、Statement.NO_GENERATED_KEYS);
        rs = stmt.executeQuery();
        if(rs.next()){
            合計=rs.getInt(1);
        }
    } catch(例外e){
        e.printStackTrace();
    } ついに {
        試す {
            rs.close();
            stmt.close();
        } catch(Exception ex){
            ex.printStackTrace();
        }
    }
    System.out.println( "total =" + total);

エラーメッセージ:

    java.sql.SQLException:基礎となるデータベースから接続を取得できませんでした!
        com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:106)で
        com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:529)で
        com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:128)で
    ..。
    原因:com.mchange.v2.resourcepool.CannotAcquireResourceException:ResourcePoolは、プライマリファクトリまたはソースからリソースを取得できませんでした。
        com.mchange.v2.resourcepool.BasicResourcePool.awaitAvailable(BasicResourcePool.java:1319)で
        com.mchange.v2.resourcepool.BasicResourcePool.prelimCheckoutResource(BasicResourcePool.java:557)で
        com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:477)で
        com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:525)で
    ..。

MySQLは(c3p0なしで)使用するだけで機能します:

    Class.forName( "com.mysql.jdbc.Driver");
    接続con=DriverManager.getConnection( "jdbc:mysql:// localhost / my-database?autoReconnect = true&characterSetResults = UTF-8&characterEncoding = UTF-8&useUnicode = yes"、 "user"、 "password");
    ステートメントstatement=connect.createStatement();
    ResultSet resultSet = statement.executeQuery( "SELECT count(*)FROM users");

したがって、問題はc3p0が原因だと思います。私を助けてください。ありがとう。

4

3 に答える 3

1

私はc3p0ソースを変更し、新しいc3p0バンドルバージョンを再度ビルドするのが面倒です:)。そこで、代わりにApacheDBCPバンドルを試してみます。

org.apache.servicemix.bundles.commons-pool-1.5.4
org.apache.servicemix.bundles.commons-dbcp-1.4.0
(dbcp needs pool to work)

MySQLデータベースをCRUDしても問題ありません。

誰かがそれらのバンドルを使用したい場合は、ここにあります:

http://mvnrepository.com/artifact/org.apache.servicemix.bundles/org.apache.servicemix.bundles.commons-pool
http://mvnrepository.com/artifact/org.apache.servicemix.bundles/org.apache.servicemix.bundles.commons-dbcp

時間があるときに、誰かがすでにバンドルを作成している場合は、bonecpを調べます。または、c3p0を変更して使用します。

于 2012-07-28T03:36:02.063 に答える
0

ログを確認してください。上に示した例外の前に、c3p0は、データベースから接続を取得するための少なくとも1回の失敗した試行の詳細を示すスタックトレースをログに記録していました。ロギングレベルをFINEに設定した場合(特定のロガーが必要な場合は、com.mchange.v2.resourcepool.BasicResourcePoolを使用)、失敗した各試行がログに記録されます。ログレベルを従来のINFO(またはWARN)のままにすると、失敗した試行の「ラウンド」で最後の失敗した試行のみが表示されます(デフォルトでは、1秒の再試行遅延で30回の失敗した試行)。INFOでログを記録している場合は、これらの例外をログですでに見つけることができるはずです。

于 2012-07-27T17:17:34.357 に答える
0

OSGiでこのように(Java EEパターンを使用して)作業すると、多くのJava EEパターンが反モジュラーであり、クラスパスからの深い可視性が必要になるため、多くの悲惨な状況に陥ります。OSGiは強力なモジュール性を備えているため、これはあまりうまく機能せず、Context Classloaderのようなハックや、最終的には通常は機能しないその他のエラーが発生しやすいものが必要になります。OSGi µservicesは、このタイプの問題をモジュール式ではるかにエレガントに処理するために発明されました。

OSGi-JDBC仕様(第125章)は、µserviceの世界でJDBCを使用する方法を指定しています。ドライバーバンドルは、org.osgi.service.jdbc.DataSourceFactoryサービスを登録することになっています。このサービスを使用すると、プールされたデータソースを簡単に作成できます。私は経験から、H2データベースがこれを箱から出して行うことを知っています(H2の人に感謝します!素晴らしい製品です)。幸い、Ops4jには、 MySql用のアダプターを提供するプロジェクトがあります。MySqlはOSGiバンドルとして標準で利用できないため、ここを参照してください。

したがって、MySqlドライバーとPAX JDBC MySqlアダプターをインストールした後、真にモジュール化された方法でDataSourceを使用できるようになります。

@Component
public class DataSourceDemo {
   DataSource ds;

   @Activate
   void start() {
       Connection con = ds.getConnection();
       PreparedStatement stmt = con.prepareStatement("SELECT count(*) FROM users", Statement.NO_GENERATED_KEYS);
       ResultSet rs = stmt.executeQuery();
       if (rs.next()) {
        System.out.println(rs.getInt(1));
       }
   }

   @Reference
   void setDataSourceFactory( DataSourceFactory dsf ) throws Exception {
     ds = dsf.createDataSource();
   }
}

これにより、コード、シングルトン、静的(グローバル変数)、および動的クラスの読み込みからMySqlの依存関係も削除されることに注意してください。もちろん、MySQLに依存するSQLを生成する場合は、これを明示的にすることができます。@Reference次のように使用します。

 @Reference(target="(osgi.jdbc.driver.name=mysql)")

または、アプリのデプロイヤーが構成管理者でこれを設定できるようにすることをお勧めします。DataSourceFactory.targetプロパティを「(osgi.jdbc.driver.name = mysql)」に設定するだけで、サービスを動的に配線できます。

于 2013-07-29T07:16:30.030 に答える