【问题标题】:How to stop an OSGI Application from command line如何从命令行停止 OSGI 应用程序
【发布时间】:2015-08-25 18:10:07
【问题描述】:

我确实有一个正在运行的 osgi(Equinox 容器)应用程序。它将通过 bash 脚本启动。 See felix gogo shell

java -jar ... _osgi.jar -console 1234 &

这一切都很好,我也可以通过

telnet localhost 1234
<osgi>stop 0

但我正在寻找的是如何将其嵌入到 bash 脚本中以停止 osgi 应用程序。

我已经试过了

echo stop 0 | telnet localhost 1234

但这不起作用。因此,如果有人知道如何将其放入 bash 脚本中,请告诉我。

【问题讨论】:

  • 你没有忘记命令的回显吗?回声停止 0 |远程登录 localhost 1234
  • 我编辑了答案,但这不是它不起作用的原因。

标签: java bash osgi shutdown


【解决方案1】:

远程登录到 Gogo shell 似乎是一个非常脆弱的解决方案。为什么不编写您的应用程序来支持标准 POSIX 信号处理?然后你可以简单地用kill -s TERM &lt;pid&gt; 杀死它。

例如,以下捆绑激活器安装了一个关闭挂钩,可以彻底关闭框架,相当于stop 0

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.launch.Framework;

public class ShutdownHookActivator implements BundleActivator {

    @Override
    public void start(final BundleContext context) {
        Thread hook = new Thread() {
            @Override
            public void run() {
                System.out.println("Shutdown hook invoked, stopping OSGi Framework.");
                try {
                    Framework systemBundle = context.getBundle(0).adapt(Framework.class);
                    systemBundle.stop();
                    System.out.println("Waiting up to 2s for OSGi shutdown to complete...");
                    systemBundle.waitForStop(2000);
                } catch (Exception e) {
                    System.err.println("Failed to cleanly shutdown OSGi Framework: " + e.getMessage());
                    e.printStackTrace();
                }
            }
        };
        System.out.println("Installing shutdown hook.");
        Runtime.getRuntime().addShutdownHook(hook);
    }

    @Override
    public void stop(BundleContext context) throws Exception {
    }

}

注意:如果您可以控制启动 OSGi 框架的启动器代码,您可能应该在那里安装关闭挂钩,而不是从单独的包中安装。

更新

在 bash 中,$! 变量计算为最后执行的后台命令的 PID。您可以将其保存到您自己的变量中以供以后参考,例如:

# Launch app:
java -jar ... &
MY_PID=$!

# Later when you want to stop your app:
kill $MY_PID

【讨论】:

  • 好的,这是一个不错的解决方案。但是有一个问题,我如何让 将其添加到 bash 脚本中。是的,也许这是另一个问题。
  • @Christian 在 bash 中,变量 $! 计算为最后执行的后台命令的 PID。启动 java -jar ... &amp; 后立即将其保存到您自己的变量中。
  • context.getBundle(0) 到 Framework 的转换不能保证工作。该规范不要求系统包的 Bundle 对象是一个 instanceof Framework。参见规范中的 4.2.1:“框架对象可以看作是系统包,虽然框架对象和系统包不必相同,但允许实现在不同的对象中实现它们。”因此,您的示例应避免强制转换为 Framework。
  • 我更新了示例代码以使系统包适应框架。
【解决方案2】:

例如,如果除了 telnet 之外没有其他方法来关闭应用程序,您可以使用 expect。

http://www.tamas.io/automatic-scp-using-expect-and-bash/

【讨论】:

  • 我同意 Neil 的观点,对于一个简单的问题,这是一个脆弱而复杂的解决方案。每个操作系统都有方法告诉进程退出,通过实现一个关闭钩子,你的 Java/OSGi 程序可以响应并干净地关闭。
猜你喜欢
  • 1970-01-01
  • 2012-06-20
  • 2013-07-18
  • 2012-05-18
  • 2013-06-17
  • 1970-01-01
  • 2012-02-03
  • 1970-01-01
相关资源
最近更新 更多