5

我尝试根据一些示例实现我自己的类加载器。但是,我认为它没有按预期工作(无法重新加载 Jar 文件等。我看到很少有推荐使用 OSGI 或 Apache Felix 来处理 Jar 文件加载的参考资料。有没有加载 Jar 的示例,从 Jar 实例化一个类?

有关我要完成的工作的更多详细信息..我有一个基本上连续运行的 Java 命令行应用程序。我希望它能够在运行时动态引用 JAR 文件,并且在运行时实例中这些 jar 中的类。这些 jar 可能包含 1 个或多个支持类。这些 Jars 本质上是定制的工作单元,由持续运行的主应用程序的某些事件条件执行。.. 由于这是一个多客户端,我想让 jar 成为可插入类型的工作单元。

我目前的方向是为“客户端”提供一个代码接口,然后让他们将他们的类打包到一个 jar 文件中。然后应用程序将执行配置的(数据库)jar 路径并从 Jar 运行类。这适用于加载 jar 和类但是,我希望能够基本上热部署这些 jar。

总之,我想要一个包含支持函数的类的 JAR 文件。将在运行时从 Jar(来自主循环应用程序)引用的已定义类。在主应用程序运行时更改 JAR 文件的能力。

如果我要使用第三方库,我最好使用 Apache Felix。

谢谢

我想我是使用 Apache Felix 4 解决的。这是加载 jars/classes 的最佳方式吗?或者有没有更好更有效的方法。到目前为止,我的研究并没有指向一种解决方案。谢谢。

    FrameworkFactory ff = new FrameworkFactory ();
     Map<String,Object> config = new HashMap<String,Object>();
      config.put("org.osgi.framework.storage", "c:\\temp\\myclientBundles");
       config.put(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA,
   "packages needed,more packages needed");
  config.put(Constants.FRAMEWORK_STORAGE_CLEAN, "true");

  Framework fwk = ff.newFramework(config);
  fwk.start();


  BundleContext bc = fwk.getBundleContext();

  Bundle bundle =   bc.installBundle("file:C:\\my_client.jar");


      bundle.start();
      bundle.update();
      Class clazz = bundle.loadClass("client.work.process");
      Job pc = (Job) clazz.newInstance();
      pc.startWork(someConfigObject);
      bundle.stop();
      fwk.stop();
4

2 回答 2

2

如果我理解正确,您是在询问如何在 OSGi 中动态加载 jar 的示例,对吗?

在 OSGi 中,动态加载的模块称为捆绑包。因此,基本上解决您的问题的最常用方法是将您的 jar 放入 OSGi 捆绑包中。OSGi 包是一个普通的 Java jar,有一些增强 - 它有一个清单文件(一个 txt 文件),其中声明了对其他 Java 包的依赖关系;以及一个 Activator 类,它在包启动和停止时被调用。这个 Activator 是包的核心部分,它知道如何实例化包的其他部分。

现在,如果您的动态 jar 只是一个库 jar,并且您只想在系统中提供它的 java 包,您甚至可以不使用激活器,只需添加一个简单的清单文件。甚至还有一些工具可以为您自动进行转换——检查BND

然后,当您准备好捆绑包时,您可以使用 install 命令在任何 OSGi 框架上动态安装它。重新加载是通过调用更新命令等来完成的。生命周期定义得很好,我肯定会推荐使用它而不是重新发明轮子;)

有关一些示例和演示,请参见此处

希望这可以帮助。

于 2012-07-18T09:52:24.297 回答
2

如果现在,简单地说,我拒绝相信你的问题是加载一个类...... :-) 我认为你还有另一个问题,你认为加载一个类可以解决?

在大多数情况下,人们天真地开始加载类,问题在于可扩展性。他们有一个系统并希望有选择地使用新功能扩展它,我假设您有类似的问题,因为您想更新提供程序 jar?

如果是这样,请下载 bndtools 并查看 OSGi 服务,它们通常非常符合要求

好的,在你更新之后。如果我很了解您,那么 Apache Felix 和 Apache Felix File Install 将为您提供很好的服务。File Install 监视一个目录并在框架中的该目录中安装任何包。从目录中删除该 jar,将卸载该捆绑包。(我在 12 年前写了文件安装的原型!)

对于你的主要 JAR,让它看起来像:

@Component(immediate=true)
public void Main {  
    @Reference
    void setClient( Client client) { ... } // called whenever a client gets started
}

对于每个客户端 JAR:

@Component
public void ClientImpl implements Client {
  ... whatever
}

这几乎是您使用 bndtools 时必须编写的全部内容。只需创建一个组件项目,为主代码添加一个 Bundle Descriptor 并为客户端代码示例添加任意数量的描述符,然后 Run As -> OSGi Run。然后,您可以下载 Apache Felix 文件安装,将其添加到运行选项卡,并创建一些其他项目,将 jars(在生成的文件夹中连续制作)放入文件安装文件夹中......瞧。没有比这更简单的了:-)

于 2012-07-19T13:58:38.390 回答