简体   繁体   English

如何正确启动和关闭OSGi容器?

[英]How to start and shutdown an OSGi container properly?

I have made a bundle which has an Activator file that basically launches other bundles by their correct order. 我制作了一个包含激活程序文件的捆绑软件,该文件基本上会按其正确顺序启动其他捆绑软件。 I needed this because the framework would start some bundles before their dependencies have finished starting. 我需要这样做是因为框架会在依赖项完成启动之前启动一些捆绑软件。 For example my bundles depending on my log service would start before it, so log messages would not be stored for those bundles. 例如,取决于我的日志服务的捆绑软件将在其之前启动,因此不会为这些捆绑软件存储日志消息。 With this Activator I can choose who starts first, since there is no clear way to do it in felix . 有了Activator,我可以选择谁先开始,因为在felix中没有明确的方法。

The code for this is here: 此代码在这里:

package lumina.launcher;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;

public final class Launcher implements BundleActivator {

    private BundleContext context;

    private final String relativePath = "./bundle/";

    private final void print(String msg) {
        // System.out.println(msg);
    }

    private Bundle install(String path) throws BundleException {
        Bundle bundle = this.context.installBundle("file:/" + path);
        print("\tInstalling: " + bundle.getSymbolicName());
        return bundle;
    }

    private boolean isJar(String fileName) {
        final String[] tokens = fileName.split("\\.");
        return tokens.length != 0 && "jar".equals(tokens[tokens.length - 1]);
    }

    private String[] listFilesForFolder(final File folder)
            throws BundleException {
        final List<String> bundles = new ArrayList<String>();
        for (final File fileEntry : folder.listFiles()) {
            if (fileEntry.isDirectory()) {
                listFilesForFolder(fileEntry);
            } else {
                if (isJar(fileEntry.getName())) {
                    bundles.add(fileEntry.getAbsolutePath().replace(
                            File.separatorChar, '/'));
                }
            }
        }
        return bundles.toArray(new String[0]);
    }

    @Override
    public void start(BundleContext context) throws Exception {
        this.context = context;
        installStart("third-party");
        installStart("shared-components");
        installStart("lumina");
        installStart("webconsole");
        System.out
                .println("-> You can access Felix WebConsole at http://localhost:8080/system/console");
        Thread.sleep(2000);
        installStart("plugins");
    }

    private final void installStart(String path) throws BundleException {
        print("Installing " + path);
        final String[] targetBundles = listFilesForFolder(new File(relativePath
                + path));
        final Bundle[] bundles = new Bundle[targetBundles.length];
        for (int i = 0; i < targetBundles.length; i++) {
            bundles[i] = install(targetBundles[i]);
        }
        print("\tStarting installed bundles...");
        for (Bundle b : bundles)
            b.start();
    }

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

}

And this is how I organized my bundles in felix's bundle/ folder. 这就是我如何在felix的bundle /文件夹中组织捆绑软件的方式。

C:\felix\BUNDLE
│   .gitignore
│   lumina.launcher-1.0.0-SNAPSHOT.jar
│
├───lumina
│       .gitignore
│       lumina.api-0.0.4-SNAPSHOT.jar
│
├───plugins
│       .gitignore
│       lumina.assembler-0.0.1-SNAPSHOT.jar
│       lumina.extensions.drivers.ip-0.0.1-SNAPSHOT.jar
│       lumina.rest-0.0.4-SNAPSHOT.jar
│       shared.extensions.base.logger-1.0.2-SNAPSHOT.jar
│       smartcampuskndriver.gateway-0.0.1-SNAPSHOT.jar
│       smartcampusmetersip.gateway-0.0.1-SNAPSHOT.jar
│
├───shared-components
│       codebase-2.0.0.jar
│       shared.osgi.services-1.3.0-SNAPSHOT.jar
│       shared.osgi.services.logger-1.0.0-SNAPSHOT.jar
│       shared.properties.api-5.2.1-SNAPSHOT.jar
│
├───third-party
│       com.googlecode.json-simple_1.1.0.jar
│       org.apache.felix.bundlerepository-2.0.2.jar
│       org.apache.servicemix.bundles.joda-time-2.3_1.jar
│       org.apache.servicemix.bundles.junit-4.11_1.jar
│       org.osgi.compendium-1.4.0.jar
│       org.osgi.core-1.4.0.jar
│       org.restlet.ext.json_2.1.0.M1.jar
│       org.restlet.jse.org.restlet.lib.org.json_2.0.0.jar
│       org.restlet_2.1.0.M1.jar
│       OSGiJMX.jar
│
├───unused
│       org.apache.felix.gogo.command-0.14.0.jar
│       org.apache.felix.gogo.runtime-0.12.1.jar
│       org.apache.felix.gogo.shell-0.10.0.jar
│
└───webconsole
        org.apache.felix.http.api-2.3.2.jar
        org.apache.felix.http.jetty-2.3.2.jar
        org.apache.felix.http.servlet-api-1.0.1.jar
        org.apache.felix.webconsole-4.2.4-all.jar

Note that lumina.launcher-1.0.0-SNAPSHOT.jar is where my Activator is and is the only bundle auto-started by felix. 请注意, lumina.launcher-1.0.0-SNAPSHOT.jar是我的激活器所在的位置,并且是felix自动启动的唯一软件包。

This works fine by the way, dunno if there is a smarter way to do this. 顺便说一句,这很好用,如果有更聪明的方法可以做到这一点。 So the idea of the above code is to start all bundles from each directory by the following order: third-party, shared-components, lumina, webconsole and plugins. 因此,以上代码的想法是按照以下顺序启动每个目录中的所有捆绑软件:第三方,共享组件,lumina,Webconsole和插件。

On the other hand, when I hit ^C in the terminal while the OSGi container is running, it begins stopping all bundles one by one. 另一方面,当我在OSGi容器运行时在终端中按^ C时,它将开始逐个停止所有包。 This is ok, but the log service is one of the first bundles to stop, and I want it to be one of the last bundles. 可以,但是日志服务是最先停止的捆绑软件之一,我希望它成为最后一个捆绑软件之一。 Is there a way to set the order by which bundles are stopped when the OSGi container is closing? 有没有一种方法可以设置OSGi容器关闭时停止分发包的顺序?

Thanks! 谢谢!

I needed this because the framework would start some bundles before their dependencies have finished starting. 我需要这样做是因为框架会在依赖项完成启动之前启动一些捆绑软件。

One of the rules of OSGi is that all bundles should be implemented in the way that starting order does not matter. OSGi的规则之一是,所有捆绑软件都应以顺序无关紧要的方式实施。

In case you really need starting order, you should set start levels for your bundles. 如果您确实需要启动顺序,则应为捆绑商品设置启动级别。 See chapter 10.5 of OSGi core specification to get more information about start levels. 请参阅OSGi核心规范的10.5章以获取有关启动级别的更多信息。

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

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