6

这是一个大问题。

我有一个结构良好但单一的代码库,它具有原始的模块化架构(所有模块都实现接口但共享相同的类路径)。我意识到这种方法的愚蠢以及当我在可能具有我的库的不同冲突版本的应用程序服务器上部署时它所代表的问题。

我现在依赖大约 30 个罐子,并且正在将它们捆绑起来。现在我的一些模块很容易声明版本依赖,例如我的网络组件。它们静态引用 JRE 和其他 BNDded 库中的类,但我的 JDBC 相关组件通过 Class.forName(...) 实例化,并且可以使用任意数量的驱动程序之一。

我按服务区将所有内容分解为 OSGi 包。

  • 我的核心类/接口。
  • 报告相关组件。
  • 数据库访问相关组件(通过 JDBC)。
  • ETC....

我希望我的代码仍然能够在没有 OSGi 的情况下通过具有我所有依赖项的单个 jar 文件使用,并且完全没有 OSGi(通过 JARJAR),并且还能够通过 OSGi 元数据和具有依赖项信息的粒度包实现模块化。

  • 如何配置我的包和我的代码,以便它可以动态地利用类路径上和/或 OSGi 容器环境(Felix/Equinox/等)中的任何驱动程序?

  • 是否有运行时方法来检测我是否在跨容器(Felix/Equinox/等)兼容的 OSGi 容器中运行?

  • 如果我在 OSGi 容器中,是否需要使用不同的类加载机制?

  • 我是否需要将 OSGi 类导入我的项目才能通过我的数据库模块加载一个在捆绑时间未知的 JDBC 驱动程序?

  • 我还有第二种获取驱动程序的方法(通过 JNDI,仅在应用服务器中运行时才真正适用),我是否需要更改我的 OSGi 感知应用服务器的 JNDI 访问代码?

4

3 回答 3

8
  • 在 OSGi 环境中使用任何驱动程序都需要您使用 DynamicImport-Package: * 语句,因此当您使用 Class.forName(..) 加载驱动程序时,您的包可以解析这些包。
  • 可能最简单的方法是尝试访问 org.osgi.framework 包中的类。这些至少应该始终存在于 OSGi 环境中(请参见下面的代码段)。有更复杂的机制,所以如果你需要更高级的东西,请告诉我。此外,请查看 OSGi R4.2 核心规范第 3.8.9 段,其中显示了一些查找类的 Bundle 和 BundleContext 的方法,因此间接有助于确定您是否在框架中。
  • 这取决于您在做什么,这里没有通用的“是”或“否”答案。OSGi 使用类加载器,并且这样做的方式对于标准 Java 应用程序来说不是“典型的”,但根据您正在做的事情,您可能不会注意到。
  • 不。
  • 看看最近发布的 OSGi 企业规范。他们有一章介绍 OSGi 中的 JNDI 集成,这可能允许您(大部分)保持代码不变。

一个简单的示例片段:

 public static boolean inOSGi() {
  try {
   Class.forName("org.osgi.framework.FrameworkUtil");
   return true;
  }
  catch (ClassNotFoundException e) {
   return false;
  }
 }

只要确保你把这段代码放在一个包中,包应该导入 org.osgi.framework (否则它永远找不到那个类)。

于 2010-04-29T15:21:07.197 回答
0

我在 Eclipse RCP 中为 OSGI 制作了 JDBC 驱动程序管理器,我将带您了解如何使用 OSGI。首先,忘记 DynamicImport-Package,使用 OSGI 的唯一好方法是安装/启动/停止包并按照设计的方式使用 OSGI 机制。

  1. 您拥有 JDBC 包,并创建另一个“驱动程序包”,其中包含 DriverClass 的初始化、连接逻辑并添加必要的公共库,例如 dbcp2 和 pool2。

  2. 将驱动程序包导出为 JAR/ZIP 并将其作为资源包含在您的 JDBC 包中。

  3. 让您的 JDBC 包在其工作区中解压缩驱动程序包。

    String workdir= Platform.getStateLocation(jdbc_bundle).toPortableString();
    
  4. 以编程方式添加驱动程序 jar 并相应地修改驱动程序包的 MANIFEST.MF 文件。

  5. 从工作区以编程方式加载驱动程序包

    getBundleContext().installBundle("file:/"+workdir);
    
  6. 以编程方式修改驱动程序列表时,根据需要使用 bundle.start()、stop()、uninstall()。

于 2016-07-22T07:21:22.853 回答
0

pax-jdbc 可用于通过声明方式委托数据源,即您可以在 ConfigAdmin 服务中创建配置条目,并且可以通过 JNDI 访问数据源。JDBC 驱动程序部署为捆绑包。(大部分都有 OSGi 版本)

例如:

配置条目 PID 是 org.ops4j.datasource-test

特性:

osgi.jdbc.driver.name=H2
databaseName=test
user=sa
password=
dataSourceName=testds-h2

该服务由给定的 dataSourceName 标识。因此,您可以使用 (&(objectClass=javax.sql.DataSource)(dataSourceName=test2)) 对其进行过滤。

您可以通过 JNDI 访问数据源:

osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=test2)
于 2016-07-28T00:03:15.487 回答