Java 如何编写OSGI命令行应用程序
我现在正在尝试OSGI,并决定使用一个稍微非典型的OSGI用例。我想在命令行应用程序中使用它。我想要一个Java 如何编写OSGI命令行应用程序,java,osgi,embedded-osgi,Java,Osgi,Embedded Osgi,我现在正在尝试OSGI,并决定使用一个稍微非典型的OSGI用例。我想在命令行应用程序中使用它。我想要一个main(…)方法,它接受一些标志和参数,执行一些操作并再次关闭。我不想启动ApacheKaraf(或类似的)并在OSGI控制台中运行命令(尽管这可能成为可选功能) 为什么OSGI首先用于命令行应用程序?应用程序应该使用同一库的不同版本(即)。当然,这只是因为它很糟糕 我应该在包内还是包外使用服务?你会怎么做?会出现什么问题?回答我自己的问题():我目前认为最好 启动(清洁) 启动容器 导出A
main(…)
方法,它接受一些标志和参数,执行一些操作并再次关闭。我不想启动ApacheKaraf(或类似的)并在OSGI控制台中运行命令(尽管这可能成为可选功能)
为什么OSGI首先用于命令行应用程序?应用程序应该使用同一库的不同版本(即)。当然,这只是因为它很糟糕
我应该在包内还是包外使用服务?你会怎么做?会出现什么问题?回答我自己的问题():我目前认为最好
org.osgi.framework.system.packages.extra
)启动所有捆绑包后,可以安全地假设所需的服务可用。这也避免了将配置传递给OSGI,而OSGI实际上只是服务调用的参数。当您使用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是完整的,它包含所有包、框架、启动器和运行它的属性。没有外部依赖关系
诀窍是获取主线程(其中调用了static main)。您唯一需要做的就是使用属性main.thread=true
注册一个可运行的服务。然后,启动程序将调用此服务上的run(),然后退出(您可以随时保持运行)
要获取命令行参数,可以使用launcher.arguments
属性获取对象服务。此属性将包含您的命令参数。或使用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");
}
}
@Component(immediate=true,property=“main.thread=true”)
公共类主实现可运行{
字符串[]args;
公共无效运行(){…}
@引用(target=“(launcher.arguments=*)”)
void setArgs(对象服务、地图道具){
this.args=(String[])props.get(“launcher.arguments”);
}
}
最好的方法是使用bndtools,因为它可以轻松地测试/调试代码。那么您可能想要使用bndrun文件
另外,在最新的bnd中,您可以使用Callable而不是Runnable。然后,返回值是进程的退出代码。但是,这可能还没有出现在bndtools中。谢谢您的回答。听起来确实很容易。您知道maven bundle plugin是否公开了
package
命令吗?您所说的Object.class
是什么意思?应该简单地删除它,使其成为常规setter,对吗?我认为它应该是一个对象参数。不幸的是,您不能仅仅删除它,即使它只是您感兴趣的Map参数。包commnand仅在(bnd)工具中可用。这是一个有趣的问题,如果您想让包使用可发现的命令行选项(这是我们的用例),这就更难了。唉,我们的最终解决方案相当重,我还没有时间将其提炼成其他人可以使用的东西…