Проблемы с загрузкой классов в OSGI и Apache Commons-DBCP - PullRequest
2 голосов
/ 23 марта 2010

Я унаследовал некоторый код, который использует пулы соединений Apache commons-dbcp в комплекте OSGi. Этот код прекрасно работает с Eclipse / Equinox OSGi версии 3.4.3 (R34x_v20081215), commons-dbcp 1.2.2 и пакетами postgres jdbc3 8.3.603 от springsource.org.

Я хотел модернизироваться, возможно, это была моя первая ошибка!

Когда я использую новую версию Felix или Equinox OSGI Cores с новыми пакетами JDBC3 или JDBC4 postgresql вместе с последней версией commons-dbcp (1.4.1), у меня возникает проблема с загрузкой классов. Я провел многочисленные поиски и обнаружил, что код commons-dbcp должен иметь исправление DBCP-214 , но, похоже, оно все равно не работает.

Я пытался поместить org.postgresql в строку импорта-пакета commons-dbcp MANIFEST.MF, но это тоже не сработало.

Я написал простой тест в активаторе, который сначала выполняет базовые class.forName () и DriverManager.getConnection (), это работает нормально, но когда я добавляю BasicDataSource () и устанавливаю соединение с BasicDataSource.getConnection () Я получаю ClassNotFoundException. См. Пример кода ниже.

Заранее спасибо за любую помощь, предложения, ...

Sau!

// This one fails with an exception
public void dsTest() {
    BasicDataSource bds = new BasicDataSource();
    ClassLoader cl;

    try {
        logger.debug("ContextClassLoader: {}", 
        Thread.currentThread().getContextClassLoader().toString());
        cl = this.getClass().getClassLoader();
        logger.debug("ClassLoader: {}", cl); 

        if (bds.getDriverClassLoader() != null) {
            logger.debug(bds.getDriverClassLoader().toString());
        }
        // The failure is the same with and with the setDriverClassLoader() line
        bds.setDriverClassLoader(cl);
        bds.setDriverClassName("org.postgresql.Driver");
        bds.setUrl("jdbc:postgresql://127.0.0.1/dbname");
        bds.setUsername("user");
        bds.setPassword("pword");
        Class.forName("org.postgresql.Driver").newInstance();
        conn = bds.getConnection();
        Statement st = conn.createStatement();
        ResultSet rs = st.executeQuery("SELECT COUNT(*) FROM table");
        conn.close();
        logger.debug("Closed DataSource Test");
    } catch (Exception ex) {
        ex.printStackTrace();
        logger.debug("Exception: {} ", ex.getMessage());
    }
}

// This one works
public void managerTest() {
    ClassLoader cl;
    try {
        cl = this.getClass().getClassLoader();
        logger.debug("ClassLoader: {}", cl);
        Class.forName("org.postgresql.Driver").newInstance();
        String url = "jdbc:postgresql://127.0.0.1/dbname";
        conn = DriverManager.getConnection(url, "user", "pword");

        Statement st = conn.createStatement();
        ResultSet rs = st.executeQuery("SELECT COUNT(*) FROM table");
        conn.close();
        logger.debug("Closed Manger Test");
    } catch (Exception ex) {
        ex.printStackTrace();
        logger.debug("Exception: {} ", ex.getMessage());
    }
}

1 Ответ

3 голосов
/ 27 октября 2010

это связано с тем, что пакет commons-dbcp не может посмотреть фактический класс драйвера из-за загрузчика класса osgi Решением этой проблемы является присоединение фрагмента к классу commons-dbcp с помощью динамического импорта *. Фактические заголовки, которые вам нужны в вашем манифесте, следующие:

Fragment-Host: org.apache.commons.dbcp DynamicImport-Package: *

После этого указанный вами код работал. Надеюсь, это не слишком поздно.

...