寻找在动态加载Jar文件中使用Apache Felix并在Java中在运行时实例化类的基本示例

时间:2012-07-18 00:14:10

标签: jar osgi classloader apache-felix

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

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

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

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

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

感谢

我想我用Apache Felix 4来解决它。这是加载jar /类的最佳方法吗?或者是否有更好的更有效的方式。到目前为止,我的研究并没有指出一个解决方案。感谢。

    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();

2 个答案:

答案 0 :(得分:2)

如果我理解你的正确,那么你是在问一个如何在OSGi中动态加载jar的例子,是吗?

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

现在,如果你的动态jar只是一个库jar而你只想在系统中提供它的java包,那么你甚至可以通过只添加一个简单的清单文件而没有激活器。甚至还有一些工具可以自动为您进行转换 - 请查看BND

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

有关示例和演示,请参阅here

希望这会有所帮助。

答案 1 :(得分:1)

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

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

如果是这样,下载bndtools并查看OSGi服务,它们通常很适合该法案

好的,更新后。如果我理解你,那么Apache Felix和Apache Felix文件安装将会很好。 File Install监视目录并在框架中的该目录中安装任何bundle。从目录中删除该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,为客户端代码示例添加任意数量的描述符,然后运行为 - &gt; OSGi Run。然后,您可以下载Apache Felix文件安装,将其添加到运行选项卡,并创建一些其他项目,将jar(在生成的文件夹中连续生成)放入文件安装文件夹...瞧。没有比这简单得多: - )