【问题标题】:Execute OSGI console commands programmatically以编程方式执行 OSGI 控制台命令
【发布时间】:2019-06-18 15:57:45
【问题描述】:

有人可以提供一个关于如何以编程方式执行 OSGI 控制台命令的工作示例吗?

我正在通过代码加载 OSGI,并且我想执行 OSGI 控制台命令(我通过不同的系统接收命令)。这就是我正在做的一个简单测试:

ServiceLoader<FrameworkFactory> frameworkFactoryService = ServiceLoader.load(FrameworkFactory.class);
FrameworkFactory frameworkFactory = frameworkFactoryService.iterator().next();

Map<String, String> config = new HashMap<String,String>();
config.put("org.osgi.framework.storage", "../workspace/.config");
config.put("org.osgi.framework.storage.clean", "onFirstInit");

framework = frameworkFactory.newFramework(config);

framework.init();
framework.start();  

// install required bundles
String bundleLocation = "org.eclipse.equinox.common_3.8.0.20181108-1144.jar";
Bundle bundle = framework.getBundleContext().installBundle(bundleLocation);

bundleLocation = "org.eclipse.update.configurator_3.4.2.M20090103-1001-RCP20181108-1144.jar";
bundle = framework.getBundleContext().installBundle(bundleLocation);
bundle.start();

bundleLocation = "org.apache.felix.gogo.runtime_0.10.0.v201209301036.jar";
bundle = framework.getBundleContext().installBundle(bundleLocation);
bundle.start();

bundleLocation = "org.apache.felix.gogo.command_0.10.0.v201209301215.jar";
bundle = framework.getBundleContext().installBundle(bundleLocation);
bundle.start();

bundleLocation = "org.apache.felix.gogo.shell_0.10.0.v201212101605.jar";
bundle = framework.getBundleContext().installBundle(bundleLocation);
bundle.start();

bundleLocation = "org.eclipse.equinox.console_1.1.200.v20150929-1405.jar";
bundle = framework.getBundleContext().installBundle(bundleLocation);
bundle.start();

CommandProcessorImpl commandProcessor = new CommandProcessorImpl();
CommandSession commandSession = commandProcessor.createSession(System.in, System.out, System.err);

commandSession.execute("ss");

一切都正确加载,如果我以编程方式遍历所有捆绑包,我可以看到一切都已加载并启动。不幸的是,我在“执行”行上收到异常“找不到命令:ss”。我究竟做错了什么?谁有一个简单的工作示例?

【问题讨论】:

    标签: osgi apache-felix gogo-shell


    【解决方案1】:

    您正在自己启动CommandProcessImpl。您应该获得 CommandProcessor 服务。您创建的实例与框架没有连接,因此找不到任何注册为服务的命令。

     BundleContext context = framework.getBundleContext();
     ServiceReference<CommandProcessor> cpr = 
         context.getServiceReference(CommandProcessor.class);
     CommandProcessor cp = context.getService(cpr);
    
     CommandSession session = cp.createSession(System.in, System.out, System.err);
    
     session.execute("lsb");
    

    显然此代码不受保护。获取服务参考然后获取服务真的很糟糕,因为服务可以来来去去。

    bnd 有一个远程代理 (biz.aQute.bnd.remote),您可以轻松地从外部进程调用它。它还有一个 bndremote 程序,您可以在任何机器上运行,然后您可以在该机器上下载框架 + 包。这可能比自己构建更容易?

    【讨论】:

    • 谢谢。这是一个很好的指导。正如这篇文章所建议的,我错过了框架和 CommandProcessor 之间的连接。我还必须使用反射,因为我的代码在 OSGI 环境之外运行,并且在运行时必须使用包内包中的类。我也会看看bnd。
    • 如果你想要命令,通过框架注册一个服务。它会被捡起来的。你想做的很多事情已经在许多不同的环境中完成了很多次。除非这是一个爱好项目,否则不要重新发明轮子,更糟糕的是,在这个容易出错的领域犯下许多错误。启动器很复杂!
    猜你喜欢
    • 1970-01-01
    • 2013-10-05
    • 2013-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-28
    • 2013-01-26
    相关资源
    最近更新 更多