简体   繁体   English

从 OSGi 包访问命令行参数

[英]accessing command-line arguments from OSGi bundle

I have an application that runs as a collection of OSGi bundles.我有一个作为 OSGi 包集合运行的应用程序。 I start it using a very small wrapper that embeds the Felix framework.我使用一个嵌入 Felix 框架的非常小的包装器来启动它。 The necessity of that wrapper irks me a little, as does the fact that it depends on Felix (whereas the application itself could run just as well in, say, Equinox), so I want to get rid of it, and use the default Felix launcher.这个包装器的必要性让我有点恼火,因为它依赖于 Felix(而应用程序本身也可以在 Equinox 中运行),所以我想摆脱它,并使用默认的 Felix发射器。

The only thing that the wrapper really does is passing the command line arguments into the launched OSGi framework, so that a bundle there can react upon them.包装器真正做的唯一一件事就是将命令行参数传递到启动的 OSGi 框架中,以便那里的包可以对它们做出反应。 Note that it does not actually parse the arguments, just pushes the String[] into my application.请注意,它实际上并不解析参数,只是将 String[] 推送到我的应用程序中。

Is there a standard way (or at least a Felix-standard way) to access command line parameters from a bundle, so that I can do away with the custom launcher?是否有标准方式(或至少是 Felix 标准方式)来访问捆绑包中的命令行参数,以便我可以取消自定义启动器?

If you use bnd(tools) you can use its launcher.如果你使用 bnd(tools) 你可以使用它的启动器。 It registers the command line arguments as a service property 'launcher.arguments'.它将命令行参数注册为服务属性“launcher.arguments”。

This works extremely well when you combine it with the bnd package command.当您将它与 bnd package 命令结合使用时,这非常有效。 This command takes a bnd project or a bndrun file describing the running environment (bundles, properties, framework) and turns into into a standalone main jar.这个命令需要一个 bnd 项目或一个描述运行环境(包、属性、框架)的 bndrun 文件,并变成一个独立的主 jar。 So you develop and debug in bndtools and when you're happy you turn it into a single executable jar.因此,您在 bndtools 中进行开发和调试,当您感到满意时,您可以将其转换为单个可执行 jar。 Example:例子:

@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");
   }
}

To turn into an executable:变成可执行文件:

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

Late answer but perhaps someone finds it useful.迟到的答案,但也许有人觉得它有用。

I was having quite the same issue.我遇到了完全相同的问题。 My application runs in OSGi but I have external interfaces that I need to comply with which implies reading the command line arguments.我的应用程序在 OSGi 中运行,但我有需要遵守的外部接口,这意味着读取命令行参数。

The key to this is something defined in the new OSGi specification 4.2, namely Framework Launching.关键是在新的 OSGi 规范 4.2 中定义的东西,即框架启动。 You can read about it in the Draft spec (found under Draft on www.osgi.org) in the Life Cycle Layer section.您可以在生命周期层部分的草案规范(在 www.osgi.org 上的草案下找到)中了解它。

It's a standard way of launching an OSGi framework (any implementation that supports OSGi 4.2) from a stand-alone java application.这是从独立 Java 应用程序启动 OSGi 框架(任何支持 OSGi 4.2 的实现)的标准方式。 The nifty thing is that you don't need to know which implementation you start (Felix, Equinox, ...) as long as it is found in the CLASSPATH.有趣的是,只要在 CLASSPATH 中找到它,您就不需要知道您启动的是哪个实现(Felix、Equinox 等)。

This way, the your launcher application reads command line arguments, instantiates and starts an OSGi framework and pass the arguments to your bundle (any way you want).这样,您的启动器应用程序读取命令行参数,实例化并启动 OSGi 框架并将参数传递给您的包(任何您想要的方式)。 What you get in the launcher application is a Context to the framework from which you can communicate with your bundles.您在启动器应用程序中获得的是框架的上下文,您可以从中与您的包进行通信。

As of Equinox 3.5M6 (I think, well at least M6) this is supported.从 Equinox 3.5M6(我认为,至少是 M6)开始支持。 The latest version of Apache Felix does also support this. Apache Felix 的最新版本也支持这一点。

I am aware that you searched for Felix only.我知道您只搜索了 Felix。 Then, this Equinox-only solution might not be useful.那么,这个仅限 Equinox 的解决方案可能没有用。 I leave it here, because someone else might stumble over this question and has Equinox running.我把它留在这里,因为其他人可能会被这个问题绊倒并且让 Equinox 运行。

From any bundle and any framework, it might be difficult.从任何捆绑包和任何框架来看,这可能很困难。 If you use the org.eclipse.core.runtime.applications extension point, is should be easy.如果您使用 org.eclipse.core.runtime.applications 扩展点,应该很容易。 Precondition: You do NOT pass -console as Parameter.前提条件:您不要将 -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
    }
}

Reference in plugin.xml plugin.xml 中的引用

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

Probably not.可能不是。 I think the standard Felix launcher does some command line validation and only accepts the bundle cache dir as an argument.我认为标准的 Felix 启动器会进行一些命令行验证,并且只接受捆绑缓存目录作为参数。 More than one argument and the launcher quits.不止一个参数,启动器退出。

You may use system properties to pass information in the command line, and I think it works not only in felix but also in other osgi containers, but it probably makes your application not very user friendly.您可以使用系统属性在命令行中传递信息,我认为它不仅适用于 felix,还适用于其他 osgi 容器,但它可能会使您的应用程序对用户不太友好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM