从 OSGi 包访问命令行参数

Posted

技术标签:

【中文标题】从 OSGi 包访问命令行参数【英文标题】:accessing command-line arguments from OSGi bundle 【发布时间】:2010-09-30 21:13:14 【问题描述】:

我有一个作为 OSGi 包集合运行的应用程序。我使用嵌入 Felix 框架的非常小的包装器来启动它。这个包装器的必要性让我有点恼火,因为它依赖于 Felix(而应用程序本身也可以在 Equinox 中运行),所以我想摆脱它,并使用默认的 Felix启动器。

包装器真正做的唯一一件事就是将命令行参数传递到启动的 OSGi 框架中,以便那里的包可以对它们做出反应。请注意,它实际上并不解析参数,只是将 String[] 推送到我的应用程序中。

是否有一种标准方式(或至少是 Felix 标准方式)来访问捆绑包中的命令行参数,以便我可以取消自定义启动器?

【问题讨论】:

结果如何?您最终是否通过 -D JVM 参数选择了框架启动选项?如果是这样,是否可以发布有关您的解决方案的一些信息?谢谢。 【参考方案1】:

如果你使用 bnd(tools),你可以使用它的启动器。它将命令行参数注册为服务属性“launcher.arguments”。

将它与 bnd package 命令结合使用时效果非常好。此命令采用描述运行环境(包、属性、框架)的 bnd 项目或 bndrun 文件并变成独立的主 jar。因此,您在 bndtools 中进行开发和调试,当您满意时,您可以将其转换为单个可执行 jar。示例:

@Component
public class MyApp 
   String[] args;

   @Activate
   void activate()  
      System.out.println("Args: " + Arrays.toString(args));
   

   @Reference(target="(launcher.arguments=*)")
   void args( Object object, Map<String,Object> map) 
       args = (String[]) map.get("launcher.arguments");
   

变成可执行文件:

bnd package myapp.bnd
java -jar myapp.jar -a somearg *.file

【讨论】:

这很好用,但我认为 map.get("launcher.arguments") 应该转换为 String[]【参考方案2】:

我知道您只搜索了 Felix。那么,这个 Equinox-only 解决方案可能没有用。我把它留在这里,因为其他人可能会偶然发现这个问题并让 Equinox 运行。

从任何捆绑包和任何框架中,这都可能很困难。如果您使用 org.eclipse.core.runtime.applications 扩展点,应该很容易。前提条件:您不要将 -console 作为参数传递。

public class Application implements IApplication 

    @Override
    public Object start(IApplicationContext context) throws Exception 
        String[] args = (String[])context.getArguments().get("application.args");
        // args.length == 0 if no arguments have been passed
    

plugin.xml 中的引用

 <plugin>
    <extension
          id="myApp"
          point="org.eclipse.core.runtime.applications">
        <application>
          <run class="package.Application" />
        </application>  
    </extension>
 </plugin>

【讨论】:

【参考方案3】:

迟到的答案,但也许有人觉得它有用。

我遇到了同样的问题。我的应用程序在 OSGi 中运行,但我有需要遵守的外部接口,这意味着读取命令行参数。

关键是在新的 OSGi 规范 4.2 中定义的东西,即框架启动。您可以在生命周期层部分的草稿规范(在 www.osgi.org 上的草稿下找到)中阅读有关它的内容。

这是从独立的 Java 应用程序启动 OSGi 框架(任何支持 OSGi 4.2 的实现)的标准方式。有趣的是,只要在 CLASSPATH 中找到它,您就不需要知道启动的是哪个实现(Felix、Equinox、...)。

这样,您的启动器应用程序读取命令行参数、实例化并启动 OSGi 框架并将参数传递给您的包(任何您想要的方式)。您在启动器应用程序中获得的是框架的上下文,您可以从该框架与您的包进行通信。

从 Equinox 3.5M6(我认为至少是 M6)开始支持此功能。最新版本的 Apache Felix 也支持这一点。

【讨论】:

我愿意为这个答案中的一些链接提供一百万美元 OSGI 框架的启动已经很好地描述了,我同意,但不是“将参数传递给你的包”。【参考方案4】:

可能不会。我认为标准的 Felix 启动器会进行一些命令行验证,并且只接受捆绑缓存目录作为参数。不止一个参数,启动器退出。

您可以使用系统属性在命令行中传递信息,我认为它不仅适用于 felix,还适用于其他 osgi 容器,但它可能会使您的应用程序对用户不太友好。

【讨论】:

以上是关于从 OSGi 包访问命令行参数的主要内容,如果未能解决你的问题,请参考以下文章

如何从正在处理的项目文件中访问 msbuild 命令行参数?

从 Scala Play 控制器访问命令行参数

命令行参数(flag包)

Go语言获取命令行参数

jar包命令行密码参数

golang命令行参数解析