如何编写OSGI命令行应用程序

时间:2013-07-19 09:44:13

标签: java osgi embedded-osgi

我目前正在尝试使用OSGI并决定采用稍微不典型的OSGI用例。我想在命令行应用程序中使用它。我想要一个main(..)方法,它接受一些标志和参数,做一些事情并再次关闭。我不想要的是启动Apache Karaf(或类似的)并在OSGI控制台中运行命令(这可能会成为一个可选功能)。

为什么OSGI首先应用于命令行应用程序?应用程序应该使用同一个库的不同版本(elasticsearch)。而且仅仅因为它当然是坏事。

我应该在捆绑服务中还是在服务范围内使用服务?如何做到这一点?可能会出现什么问题?

2 个答案:

答案 0 :(得分:6)

使用bnd时,有一种非常简单的方法可以编写命令行应用程序。 bnd具有使用package命令创建可执行jar的功能:

 $ bnd run xyz.bnd
 .... whatever your app does
 $ bnd package xyz.bnd
 $ ls
   xyz.jar  xyz.bnd .....
 $ java -jar xyz.jar ...
 .... whatever your app does

请注意,此jar已完成,它包含所有bundle,框架,启动程序以及运行它的属性。没有外部依赖。

诀窍是获取主线程(其中调用静态main)。您唯一需要做的就是使用属性main.thread=true注册Runnable服务。然后启动程序将在此服务上调用run()然后退出(只要您愿意,您就可以继续运行)。

要获取命令行参数,可以使用launcher.arguments属性获取Object服务。此属性将具有您的命令参数。或者使用DS组件执行此操作:

 @Component(immediate=true, property="main.thread=true")
 public class Main implements Runnable {
     String[] args;

     public void run(){ ... }

     @Reference(target="(launcher.arguments=*)")
     void setArgs(Object service, Map<String,Object> props) {
        this.args = (String[]) props.get("launcher.arguments");
     }
 }

执行此操作的最佳方法是使用bndtools,因为它可以轻松地测试/调试代码。您可能想要使用bndrun文件。

P.S。在最新的bnd中,您可以使用Callable&lt; Integer&gt;而不是Runnable。然后返回值是进程的退出代码。但是,这可能还没有出现在bndtools中。

答案 1 :(得分:1)

回答我自己的问题(Q&A style):我目前认为最好

  1. 开始OSGI embedded(干净)
  2. 启动容器
  3. 导出API包(org.osgi.framework.system.packages.extra
  4. 安装并启动所需的捆绑包
  5. consume services outside of OSGI
  6. 关闭容器
  7. 退出应用
  8. 在启动所有捆绑包之后,可以安全地假设所需的服务可用。这也避免了将配置传递到OSGI中,而OSGI实际上只是服务调用的参数。