捆绑服务组合:org.sqlite.JDBC 未找到

Posted

技术标签:

【中文标题】捆绑服务组合:org.sqlite.JDBC 未找到【英文标题】:Bundle on service mix: org.sqlite.JDBC not found 【发布时间】:2018-08-27 16:56:44 【问题描述】:

我有使用 SQLite 数据库的应用程序。 我把它打包成一个包,我可以看到服务组合上的服务。 当我向 Post 或 Get 服务发送请求时,我收到此错误:

java.lang.ClassNotFoundException: org.sqlite.JDBC 未找到

我在 servicemix 上安装了 SQLite JDBC 驱动程序,但仍然出错。

这是我的 POM:

<modelVersion>4.0.0</modelVersion>

<groupId>asd</groupId>
<artifactId>name</artifactId>
<version>0.0.1-SNAPSHOT</version>

<packaging>bundle</packaging>
<name>Name</name>
<description>Bundle Desc</description>

<dependencies>
    <dependency>
        <groupId>org.xerial</groupId>
        <artifactId>sqlite-jdbc</artifactId>
        <version>3.15.1</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-core</artifactId>
        <version>3.1.5</version>
    </dependency>
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-transports-http</artifactId>
        <version>3.1.5</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.felix</groupId>
            <artifactId>maven-bundle-plugin</artifactId>
            <version>3.3.0</version>
            <extensions>true</extensions>
            <configuration>
                <instructions>
                    <Bundle-SymbolicName>$project.artifactId</Bundle-SymbolicName>
                    <Bundle-Description>$project.description</Bundle-Description>
                    <Import-Package>
                        javax.jws,
                        javax.wsdl,
                        javax.xml.namespace,
                        org.apache.cxf.helpers,
                        org.osgi.service.blueprint,
                        org.xerial.sqlite-jdbc,
                        *
                    </Import-Package>
                    <Export-Package>
                        my.services.package,
                        org.xerial.sqlite-jdbc
                    </Export-Package>
                </instructions>
            </configuration>
        </plugin>
    </plugins>
</build>

我试图把这个 org.xerial.sqlite-jdbc 只作为一个导出包和只作为一个导入包但没有成功。

这是 SQLite 连接的 java 代码:

private void getConnection() throws ClassNotFoundException, SQLException 
    Class.forName("org.sqlite.JDBC");
    con = DriverManager.getConnection("jdbc:sqlite:SQLiteTest1.db");
    initialise();

应用程序在本地运行,但在 servicemix 上不运行。

【问题讨论】:

访问sqlite的java代码是什么? 我编辑了这个问题。谢谢! 【参考方案1】:

您的 java 代码不适合 OSGi。默认情况下,在 OSGi 中,每个类都由它所在的包的类加载器加载。

所以你自己的类是由你的包的类加载器加载的。由于您有 org.sqlite 的 Import-Package 语句,因此您的代码可以访问 sqlite 驱动程序类。

问题在于 DriverManager 会自行加载类。 DriverManager 由系统包(felix 框架包)提供。这个捆绑包当然没有 sqllite 的 Import-Package。所以它不能加载这个类。

不过有一个简单的解决方法。 DriverManager 允许您设置线程上下文类加载器。您可以将此类加载器设置为您自己的包的类加载器。这样 DriverManager 可以看到 sqllite 类。不过,这只是一种解决方法。

在 OSGi 中,避免问题的最佳方法是不直接加载任何类。在 jdbc 的情况下,这可以通过使用 DataSource 类而不是 DriverManager 来完成。见this post。

另一个选择是使用 pax-jdbc。它允许从配置创建 DataSource 服务。通过这种方式,您可以使您的包独立于实际的 DB 驱动程序,并且仍然避免手动加载类。 See this example.

【讨论】:

感谢您的评论,我已修复它,但现在它可以在内存中使用。有没有其他方法可以创建一个 db.file 而不是在内存中。例如 ds.setUrl("jdbc:sqlite::memory:");是: ds.setUrl("jdbc:sqlite::memory:SQLiteTest1.db");我试过这个,但我遇到了错误。 应该可以的。这样的问题可能与 OSGi 无关。也许一些 sqlite 论坛可以提供帮助。【参考方案2】:

你可以这样试试:

private void getConnection() throws ClassNotFoundException, SQLException 
  SQLiteDataSource ds = new SQLiteDataSource();
  ds.setUrl("jdbc:sqlite:SQLiteTest1.db");
  try 
   con = ds.getConnection();
   System.out.println("Connected.");
   catch (Exception e) 
   e.printStackTrace();
  
  initialise();
 

根据@Christian Schneider 的说法,这可以通过使用 DataSource 来完成。

【讨论】:

以上是关于捆绑服务组合:org.sqlite.JDBC 未找到的主要内容,如果未能解决你的问题,请参考以下文章

Java SQLite org.sqlite.JDBC 类路径损坏?

流行错误-apache netbeans 11.2中的org.sqlite.JDBC [重复]

ant sql 任务使用 org.sqlite.JDBC 驱动程序抛出“没有可用的 ResultSet”

jmeter通过org.sqlite.JDBC驱动连接db数据库

采坑预警:Exception in thread “main“ java.lang.ClassNotFoundException: org.sqlite.JDBC

采坑预警:Exception in thread “main“ java.lang.ClassNotFoundException: org.sqlite.JDBC