【问题标题】:Maven OSGi project compiles, but won't runMaven OSGi 项目编译,但不会运行
【发布时间】:2016-07-15 19:20:46
【问题描述】:

我一直在尝试将 Paul Bakker's (@paul-bakker) Making JavaFX better with OSGi : javafx-osgi-example 移植到使用 Apache Felix Maven Bundle Plugin (BND) 的 maven OSGi 项目。到目前为止它编译没有任何错误,但我无法让它运行:

Starting OSGi Framework
Found declarative services implementation: file:/C:/Users/Rev/.m2/repository/org/apache/felix/org.apache.felix.scr/1.6.2/org.apache.felix.scr-1.6.2.jar
INFO : org.apache.felix.scr (1):  Version = 1.6.2
Bundle: org.apache.felix.framework
    Registered service: [org.osgi.service.resolver.Resolver]
    Registered service: [org.osgi.service.packageadmin.PackageAdmin]
    Registered service: [org.osgi.service.startlevel.StartLevel]
Bundle: org.apache.felix.scr
    Registered service: [org.apache.felix.scr.ScrService]
    Registered service: [org.osgi.service.cm.ManagedService]
    Registered service: [org.apache.felix.scr.impl.ScrGogoCommand]
DEBUG: Starting ComponentActorThread
Bundle: null
Bundle: null
Bundle: null

如您所见,捆绑包永远不会启动。没有错误被抛出。它只是无法启动。

为什么捆绑包不启动?

项目来源

  1. Paul Bakker's (The original non-maven project) : javafx-osgi-example

  2. My maven implementation of Paul Bakker's javafx-osgi-example : JavaFX-Maven-Multi-Module-OSGi

在终端 (Windows) 中,mvn clean install 可以完美运行。

更新

我一直在尝试从 Eclipse 运行它,但没有成功:

运行 -> 运行方式 -> Java 应用程序


面向 Web 开发人员的 Eclipse Java EE IDE。

版本:Mars.2 版本 (4.5.2)
内部版本号:20160218-0600


更新

我在包rev.distdist 下有一个类App,用于启动。它循环遍历 rev 下的所有目录,并启动名称与 resources/plugins.txt 下的名称匹配的所有 jar。

APP.java

package rev.dist;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.stream.Collectors;

import org.apache.commons.io.FilenameUtils;
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 {

    FrameworkFactory frameworkFactory;
    private Framework framework;

    private List<String> pluginsList = new ArrayList<>();

    private int addedPlugins;

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

    private void initialize() throws BundleException, URISyntaxException {
        this.plugins();

        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 = ServiceLoader.load(FrameworkFactory.class).iterator().next();
        framework = frameworkFactory.newFramework(map);

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

        loadScrBundle(framework);

        File baseDir = new File("../");
        String baseDirPath = baseDir.getAbsolutePath();

        File[] files = new File(baseDirPath).listFiles();

        this.showFiles(files);

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

    public void showFiles(File[] files) throws BundleException {

        if (addedPlugins != pluginsList.size()) {
            System.out.println(":: " + pluginsList.size());
            addedPlugins--;
        }

        for (File file : files) {
            if (file.isDirectory()) {
                // System.out.println("Directory: " + file.getName());
                showFiles(file.listFiles()); // Calls same method again.
            } else {
                String[] bits = file.getName().split(".");
                if (bits.length > 0 && bits[bits.length - 1].equalsIgnoreCase("jar")) {
                    // framework.getBundleContext().installBundle(file.toURI().toString());
                }

                // String ext = FilenameUtils.getExtension(file.getAbsolutePath());

                String basename = FilenameUtils.getBaseName(file.getName());

                if (pluginsList.contains(basename)) {
                    framework.getBundleContext().installBundle(file.toURI().toString());
                    System.out.println("File: " + file.getName());

                    System.out.println("Base >>>>>>>>>>>>> : " + basename);

                    pluginsList.remove(basename);
                }
            }
        }
    }

    public void plugins() {
        File plugins = new File("src/main/resources/plugins.txt");
        String fileName = plugins.getAbsolutePath();

        try (BufferedReader br = Files.newBufferedReader(Paths.get(fileName))) {

            // br returns as stream and convert it into a List
            pluginsList = br.lines().collect(Collectors.toList());

        } catch (IOException e) {
            e.printStackTrace();
        }

        pluginsList.forEach(System.out::println);
        addedPlugins = pluginsList.size();
    }

    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();
    }
}

【问题讨论】:

  • mvn 全新安装无法完美运行。 ui pom 声明了对 rev.launcher:launcher:1.0-SNAPSHOT 的依赖,主屏幕 pom 声明了对 rev.ui:ui:1.0-SNAPSHOT 的依赖。当前正在构建的启动器和 ui 模块的组 ID 只是“rev”。我认为您在运行 mvn install 后重命名了组 ID,并且正在从本地存储库中获取旧版本。
  • dist 中使用的程序集描述符使用 moduleSet,但其他其他模块是 rev:rev 顶级 pom 的子级。我认为您需要使用 dependencySet 见 stackoverflow.com/questions/17310482/… 。您能否更新问题,详细说明如何构建和运行您的代码?
  • 你是如何启动它的?这里几乎没有信息……
  • 嗨@Neil Bartlett 我在包rev.dist 中的dist 下有一个类App,用于启动。它循环遍历 rev 下的所有目录,并启动名称与resources/plugins.txt 下的名称匹配的所有 jar。我用App.class 更新了这个问题
  • 好吧,代码相当长而且令人困惑,所以我不会费心去弄清楚它到底做了什么。但是,基本模式:(1)安装所有捆绑包,然后(2)启动所有捆绑包,是合理的。所以也许代码中只有一个错误。您是否尝试过在调试器中运行?顺便说一句,为什么您需要单独安装和启动 SCR 捆绑包?请注意,该捆绑包确实开始了,所以这里可能有一个线索。

标签: java eclipse maven javafx osgi


【解决方案1】:

我已经发布了 Drombler FX 的几个早期访问版本 - JavaFX 的模块化应用程序框架。

它不是基于 Paul Bakker 的工作,而是基于 OSGi 和 Maven(POM 优先)。也许你觉得它很有用。应用程序框架是开源的。

还有一个tutorial 和一个Getting Started 页面。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-04
    • 1970-01-01
    • 2018-05-03
    • 2018-03-26
    • 1970-01-01
    • 1970-01-01
    • 2020-08-29
    相关资源
    最近更新 更多