我有一个作为OSGi包集合运行的应用程序。我使用嵌入Felix框架的非常小的包装器启动它。这个包装器的必要性让我感到烦恼,因为它依赖于Felix(而应用程序本身也可以在Equinox中运行得很好),所以我想摆脱它,并使用默认的Felix发射器。
包装器唯一真正做的就是将命令行参数传递给已启动的OSGi框架,以便可以对它们做出反应。请注意,它实际上并不解析参数,只是将String []推送到我的应用程序中。
是否有标准方式(或至少是Felix标准方式)从捆绑中访问命令行参数,以便我可以取消自定义启动器?
答案 0 :(得分:7)
如果你使用bnd(工具),你可以使用它的启动器。它将命令行参数注册为服务属性'launcher.arguments'。
将它与bnd package命令结合使用时效果非常好。此命令采用bnd项目或bndrun文件描述运行环境(包,属性,框架),并转换为独立的主jar。所以你在bndtools中进行开发和调试,当你开心的时候把它变成一个可执行的jar。例如:
@Component
public class MyApp {
String args;
@Activate
void activate() {
System.out.println("Args: " + 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
答案 1 :(得分:2)
迟到的答案,但也许有人觉得它很有用。
我遇到了同样的问题。我的应用程序在OSGi中运行,但我需要遵守的外部接口,这意味着要读取命令行参数。
关键是在新的OSGi规范4.2中定义的内容,即Framework Launching。您可以在生命周期图部分的草案规范(在www.osgi.org上的草案下找到)中阅读相关内容。
这是从独立的Java应用程序启动OSGi框架(支持OSGi 4.2的任何实现)的标准方法。好的一点是,只要在CLASSPATH中找到它,就不需要知道启动哪个实现(Felix,Equinox,...)。
这样,您的启动器应用程序读取命令行参数,实例化并启动OSGi框架并将参数传递给您的包(以您想要的任何方式)。您在启动器应用程序中获得的是框架的上下文,您可以从该框架与捆绑软件进行通信。
截至Equinox 3.5M6(我认为,至少M6),这是支持的。最新版本的Apache Felix也支持这一点。
答案 2 :(得分:1)
可能不是。我认为标准的Felix启动程序会执行一些命令行验证,并且只接受bundle cache dir作为参数。不止一个论点和发射器退出。
您可以使用系统属性在命令行中传递信息,我认为它不仅适用于felix,还适用于其他osgi容器,但它可能会使您的应用程序不是非常用户友好。
答案 3 :(得分:1)
我知道您只搜索了Felix。然后,这种仅限Equinox的解决方案可能没用。我把它放在这里,因为其他人可能偶然发现了这个问题并且运行了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>