如何加载OSGi包

时间:2017-01-19 06:47:32

标签: java maven osgi bndtools

我正在尝试从用Java创建的OSGi容器运行BnD OSGi包,但根本没有任何事情发生。

在一个模块中,加载和启动包的模块:

public class Launcher {

    private static String[] jars = null;
    private static String[] libs = null;

    private BundleContext context;

    private Launcher() {

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

        Map<String, String> config = new HashMap<String, String>();
        config.put("osgi.console", "");
        config.put("osgi.clean", "true");
        config.put("osgi.noShutdown", "true");
        config.put("eclipse.ignoreApp", "true");
        config.put("osgi.bundles.defaultStartLevel", "4");
        config.put("osgi.configuration.area", "./configuration");

        // automated bundles deployment
        config.put("felix.fileinstall.dir", "./dropins");
        config.put("felix.fileinstall.noInitialDelay", "true");
        config.put("felix.fileinstall.start.level", "4");

        Framework framework = frameworkFactory.newFramework(config);

        try {
            framework.start();
        } catch (BundleException e) {
            e.printStackTrace();
        }

        context = framework.getBundleContext();

        Bundle stageModule = install("stage-module-1.0-SNAPSHOT");

        try {
            stageModule.start();
        } catch (BundleException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        new Launcher();
    }

    private String[] getJARs() {
        if (jars == null) {
            List<String> jarsList = new ArrayList<String>();
            File pluginsDir = new File("plugins");
            for (String jar : pluginsDir.list()) {
                jarsList.add(jar);
            }
            jars = jarsList.toArray(new String[jarsList.size()]);
        }
        return jars;
    }

    private String[] getLibs() {
        if (libs == null) {
            List<String> jarsList = new ArrayList<String>();
            File pluginsDir = new File("libs");

            System.out.println("PATHS : " + pluginsDir.getAbsolutePath());

            for (String jar : pluginsDir.list()) {
                jarsList.add(jar);
            }
            libs = jarsList.toArray(new String[jarsList.size()]);
        }
        return libs;
    }

    protected Bundle start(String name) {
        Bundle bundle = install(name);
        if (bundle != null) {
            try {
                bundle.start();
            } catch (BundleException e) {
                e.printStackTrace();
            }
        }
        return bundle;
    }

    protected Bundle install(String name) {
        String found = null;
        for (String jar : getJARs()) {
            if (jar.startsWith(name + "_") || jar.startsWith(name + "-")) {
                found = String.format("file:plugins/%s", jar);
                break;
            }
        }
        for (String jar : getLibs()) {
            if (jar.startsWith(name)) {
                found = String.format("file:libs/%s", jar);
                System.out.println(found);
                break;
            }
        }
        if (found == null) {
            throw new RuntimeException(String.format("JAR for %s not found", name));
        }
        try {
            return context.installBundle(found);
        } catch (BundleException e) {
            e.printStackTrace();
        }
        return null;
    }
}

以下是我要加载的一个捆绑包:

服务:

public interface StageService {
    Stage getStage();
}

实现:

public class StageServiceImpl implements StageService {

    private final Stage m_stage;

    public StageServiceImpl(Stage stage) {
        m_stage = stage;
    }


    @Override
    public Stage getStage() {
        return m_stage;
    }
}
@Component
public class App extends Application {

    @Start
    public void startBundle() {

        Executors.defaultThreadFactory().newThread(() -> {
            Thread.currentThread().setContextClassLoader(
                    this.getClass().getClassLoader());
            launch();
        }).start();
    }

    @Override
    public void start(Stage primaryStage) throws Exception {

        BundleContext bc = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
        DependencyManager dm = new DependencyManager(bc);

        dm.add(dm.createComponent()
                .setInterface(StageService.class.getName(), null)
                .setImplementation(new StageServiceImpl(primaryStage)));
    }

    @Stop
    public void stopBundle() {
        Platform.exit();
    }
}

然后我使用这个模块加载场景图:

@Component
public class UI {

    @ServiceDependency
    private volatile StageService m_stageService;
    private volatile TabPane tabPane;

    private final Map<ServiceReference, AppScreen> screens = new ConcurrentHashMap<>();

    @Start
    public void start() {
        Platform.runLater(() -> {

            Stage primaryStage = m_stageService.getStage();
            primaryStage.setTitle("Tabs example!");
            tabPane = new TabPane();

            screens.values().forEach(this::createTab);

            primaryStage.setScene(new Scene(tabPane, 300, 250));
            primaryStage.show();

        });
    }

    private void createTab(AppScreen s) {
        Tab tab = new Tab(s.getName());
        tab.setContent(s.getContent());
        if (s.getPosition() < tabPane.getTabs().size()) {
            tabPane.getTabs().add(s.getPosition(), tab);
        } else {
            tabPane.getTabs().add(tab);
        }
        tabPane.getSelectionModel().select(tabPane.getTabs().size() - 1);
    }

    @ServiceDependency(removed = "removeScreen")
    public void addScreen(ServiceReference sr, AppScreen screen) {
        if (tabPane != null) {
            Platform.runLater(() -> {
                createTab(screen);
            });
        }

        screens.put(sr, screen);
    }

    public void removeScreen(ServiceReference sr) {
        Platform.runLater(() -> {
            AppScreen remove = screens.remove(sr);
            Optional<Tab> findAny = tabPane.getTabs().stream()
                    .filter(t -> t.getText().equals(remove.getName()))
                    .findAny();
            if (findAny.isPresent()) {
                tabPane.getTabs().remove(findAny.get());
            }
        });
    }
}
public interface AppScreen {

    String getName();

    Node getContent();

    int getPosition();
}

以下是将组件加载到场景图上的示例模块。

@Component
public class MainScreen implements AppScreen {

    @Override
    public String getName() {
        return "Main";
    }

    @Override
    public Node getContent() {
        return new Label("Main screen");
    }

    @Override
    public int getPosition() {
        return 0;
    }

}

我没有抛出任何错误。我错过了什么?提前谢谢大家。

0 个答案:

没有答案