Java 如何加载OSGi捆绑包

Java 如何加载OSGi捆绑包,java,maven,osgi,bndtools,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() { FrameworkFa

我试图从一个用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 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 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());
            }
        });
    }
}
下面是将组件加载到场景图的示例模块

@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;
    }

}

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

您说过没有错误。。。听起来好像很有效,不是吗?你期望什么样的产出?另外,像
@Start
@ServiceDependency
这样的注释不是OSGi标准的注释,那么它们属于哪个库呢?您不应该在代码示例中忽略导入。您说过没有错误。。。听起来好像很有效,不是吗?你期望什么样的产出?另外,像
@Start
@ServiceDependency
这样的注释不是OSGi标准的注释,那么它们属于哪个库呢?您不应该在代码示例中忽略导入。
@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;
    }

}