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

sfu*_*ger 5 java osgi embedded-osgi

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

为什么OSGI首先用于命令行应用程序?该应用程序应该使用相同库的不同版本(即弹性搜索).而且仅仅因为它当然是坏事.

我应该在捆绑中还是在外面消费服务?如何做到这一点?可能会出现什么问题?

Pet*_*ens 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
Run Code Online (Sandbox Code Playgroud)

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

诀窍是获取主线程(其中调用静态main).您唯一需要做的就是使用属性注册Runnable服务main.thread=true.然后启动器将在此服务上调用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");
     }
 }
Run Code Online (Sandbox Code Playgroud)

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

PS在最新的bnd中,您可以使用Callable <Integer>而不是Runnable.然后返回值是进程的退出代码.然而,这可能还没有出现在bndtools中.