如何确保OSGi包以正确的顺序加载

时间:2016-11-02 07:25:10

标签: java osgi bundles

我有一个以编程方式启动OSGi容器的类,加载bundle,然后启动它们。我遇到的问题是捆绑包没有按正确的顺序启动。有些bundle会在依赖于它们开始之前加载并启动。

如何确保所有捆绑包以正确的顺序启动,而不是在他们依赖的捆绑包之前?

P.S: 我们欢迎任何代码改进建议到目前为止。

提前谢谢大家。

import java.io.File;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.ServiceLoader;

import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.launch.Framework;
import org.osgi.framework.launch.FrameworkFactory;

public class App {

    public static void main(String[] args) throws BundleException, URISyntaxException {
        App app = new App();
        app.initialize();
    }

    private void initialize() throws BundleException, URISyntaxException {
        Map<String, String> map = new HashMap<String, String>();

        // make sure the cache is cleaned
        map.put(Constants.FRAMEWORK_STORAGE_CLEAN, Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT);

        map.put("ds.showtrace", "true");
        map.put("ds.showerrors", "true");

        FrameworkFactory frameworkFactory = ServiceLoader.load(FrameworkFactory.class).iterator().next();
        Framework framework = frameworkFactory.newFramework(map);

        System.out.println("Starting OSGi Framework");
        framework.init();

        File baseDir = new File("target/dist-1.0-SNAPSHOT-bin/plugins/");

        loadScrBundle(framework);

        // get all the Bundles from our plugins directory
        File[] fList = baseDir.listFiles();

        for (File file : fList) {
            if (file.isFile()) {
                System.out.println(file.getAbsolutePath());

                if (file.getName().endsWith(".jar")) {
                    framework.getBundleContext().installBundle(file.toURI().toString());
                }
            } else if (file.isDirectory()) {
                // recurse
            }
        }

        for (Bundle bundle : framework.getBundleContext().getBundles()) {
            bundle.start();
            System.out.println("Bundle: " + bundle.getSymbolicName());
            if (bundle.getRegisteredServices() != null) {
                for (ServiceReference<?> serviceReference : bundle.getRegisteredServices())
                    System.out.println("\tRegistered service: " + serviceReference);
            }
        }
    }

    private void loadScrBundle(Framework framework) throws URISyntaxException, BundleException {
        URL url = getClass().getClassLoader().getResource("org/apache/felix/scr/ScrService.class");
        if (url == null)
            throw new RuntimeException("Could not find the class org.apache.felix.scr.ScrService");
        String jarPath = url.toURI().getSchemeSpecificPart().replaceAll("!.*", "");
        System.out.println("Found declarative services implementation: " + jarPath);
        framework.getBundleContext().installBundle(jarPath).start();
    }
}

1 个答案:

答案 0 :(得分:7)

如果你编写依赖于起始顺序的OSGi代码,那么你就没有OSGi代码......过去18年中我所知道的任何试图通过启动顺序进行破解的人都有很多可预防的OSGi问题。因为在OSGi中,任何捆绑包都可以随时启动/停止,您可以在启动时使其工作一次,但任何干扰都会导致代码中断。

如果您使用OSGi声明服务,那么这些问题就不存在了。只需将依赖项转换为服务并依赖于该服务。

真的,克服它,OSGi中没有订购......