JDBC/OSGi以及如何动态加载驱动程序而不明确说明bundle中的依赖项?

Chr*_*ris 6 java osgi modularity jdbc

这是一个很大的问题.

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

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

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

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

我希望我的代码能够在没有OSGi的情况下通过单个jar文件使用我的所有依赖项并且根本没有OSGi(通过JARJAR),也可以通过OSGi元数据和带有依赖性信息的粒度包进行模块化.

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

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

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

  • 我是否需要将OSGi类导入到我的项目中,以便能够通过我的数据库模块加载at-bundle-time-unknown JDBC驱动程序?

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

Mar*_*ans 7

  • 在OSGi环境中使用任何驱动程序都需要使用DynamicImport-Package:*语句,以便在使用Class.forName(..)加载驱动程序时,bundle可以解析这些包.
  • 可能最简单的方法是尝试访问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;
  }
 }
Run Code Online (Sandbox Code Playgroud)

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