Search code examples
osgibundlehsqldbapache-felix

HSQLDB bundle in felix org.hsqldb.jdbcDriver not found


I have some code, what loaded: 1) HSQLDB v. 2.2.8 bundle 2) Bundle with service:

   package ihtika2.i_internalfunctions.service;

import com.google.code.ihtika.Vars.Ini;
import java.awt.Desktop;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.sql.DriverManager;

/**
 *
 * @author Arthur
 */
public class InternalFunctions implements InternalFunctionsInterface {

    // launch browser
    public void launchBrowser(String uriStr) {
        Desktop desktop;
        if (Desktop.isDesktopSupported()) {
            desktop = Desktop.getDesktop();
            if (desktop.isSupported(Desktop.Action.BROWSE)) {
                // launch browser
                URI uri;
                try {
                    uri = new URI("http://" + uriStr);
                    desktop.browse(uri);
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                } catch (URISyntaxException use) {
                    use.printStackTrace();
                }
            }
        }
    }

    public void initDB() {
        try {
            Class.forName("org.hsqldb.jdbcDriver");
            Ini.conn = DriverManager.getConnection("jdbc:hsqldb:file:Db/pages");
            Ini.stmt = Ini.conn.createStatement();
            Ini.rs = null;

            Ini.rs = Ini.stmt.executeQuery("select count(1) as qwe from "
                    + " information_schema.system_tables "
                    + "where table_schem = 'PUBLIC'"
                    + "and table_name = 'PAGES';");
            Ini.rs.next();
            if (Ini.rs.getInt("qwe") == 0) {
                Ini.stmt.executeUpdate("CREATE SEQUENCE SEQU");
                Ini.stmt.executeUpdate("CREATE CACHED TABLE PAGES (id bigint "
                        + "GENERATED BY DEFAULT AS SEQUENCE SEQU PRIMARY KEY, "
                        + "url varchar(7777), lastUpdateDate varchar(7777)) ");
                Ini.stmt.executeUpdate("CREATE CACHED TABLE LINKDATA (id int, "
                        + "nazvanie varchar(777), linkURL varchar(777), razmer varchar(777)) ");
                Ini.stmt.executeUpdate("CREATE INDEX linkDataID ON LINKDATA (id)");
                Ini.stmt.executeUpdate("CREATE INDEX pagesURL ON PAGES (url)");
            }
        } catch (Exception ex) {
            Ini.logger.fatal("Error on DB init", ex);
        }
    }
}

3) Some bundle, what calls bundle number 2.

 try {
        ServiceReference[] refs = context.getServiceReferences(
                InternalFunctionsInterface.class.getName(), "(Funct=IFuncts)");
        if (refs == null) {
            System.out.println("Not Found IFuncts on init");
        } else {
            InternalFunctions = (InternalFunctionsInterface) context.getService(refs[0]);
        }
    } catch (Exception ex) {
        Ini.logger.fatal("Error on IFuncts init", ex);
    }

    InternalFunctions.initDB();

On executing I get error in logs:

 [FATAL] 2012-08-02 20:18 root (InternalFunctions.java:initDB:61)
Error on DB init
java.lang.ClassNotFoundException: org.hsqldb.jdbcDriver not found by ihtika2.I_InternalFunctions [7]
    at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1460)
    at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:72)
    at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1843)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:186)
    at ihtika2.i_internalfunctions.service.InternalFunctions.initDB(InternalFunctions.java:40)
    at ihtika2.mainform.IC_MainForm.<init>(IC_MainForm.java:66)
    at ihtika2.mainform.IC_MainForm$4.run(IC_MainForm.java:225)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:701)
    at java.awt.EventQueue.access$000(EventQueue.java:102)
    at java.awt.EventQueue$3.run(EventQueue.java:662)
    at java.awt.EventQueue$3.run(EventQueue.java:660)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:671)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:244)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:163)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:151)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:147)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:139)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:97)

Please, advice - how to use HSQLDB bundle in other bundle?

Answered by me: The solution is using

DriverManager.registerDriver(new JDBCDriver());
Ini.conn = DriverManager.getConnection("jdbc:hsqldb:file:Db/pages");

insted of using

Class.forName("org.hsqldb.jdbcDriver");
Ini.conn = DriverManager.getConnection("jdbc:hsqldb:file:Db/pages");

Solution

  • Unfortunately this is a very OSGi unfriendly solution. You might want to take a look at H2. H2 implements the OSGi spec, it provides a org.osgi.service.jdbc.DataSourceFactory service. You might also want to raise a bug at the hsqldb project and ask for OSGi support, it is trivially to implement for them.