0

I have been trying to port Paul Bakker's (@paul-bakker) Making JavaFX better with OSGi : javafx-osgi-example to a maven OSGi project that uses the Apache Felix Maven Bundle Plugin (BND). So far it compiles without any errors, but I can't get it to run:

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

As you can see, the bundles never get started. No errors are thrown. It just simply doesn't start.

Why won't the bundles start?

THE PROJECT SOURCES

  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

From the terminal (Windows), mvn clean install works perfectly.

UPDATE

I've been trying to run it from Eclipse, but to no success:

Run -> Run as -> Java Application


Eclipse Java EE IDE for Web Developers.

Version: Mars.2 Release (4.5.2)
Build id: 20160218-0600


UPDATE

I have a class App under dist in the package rev.dist that does the launching. It goes loops throug all the directories under the rev and starts any jars whose names match the names under resources/plugins.txt.

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();
    }
}
Community
  • 1
  • 1
Program-Me-Rev
  • 6,184
  • 18
  • 58
  • 142
  • mvn clean install does not work perfectly. The ui pom declares a dependency on rev.launcher:launcher:1.0-SNAPSHOT and the mainscreen pom declares a dependency on rev.ui:ui:1.0-SNAPSHOT. The group Ids of the launcher and ui modules that are currently being built are simply 'rev'. I think you renamed the group Ids after running mvn install and are picking up old versions from you local repository. – Matt Champion Mar 28 '16 at 15:01
  • 1
    The assembly descriptor used in dist uses moduleSet but other the other modules are children of the rev:rev top level pom. I think you need to use dependencySet see http://stackoverflow.com/questions/17310482/the-maven-assembly-plugin-moduleset-sources-instructions-are-not-including-any-f . Could you update the question with more detail about how to build and run your code? – Matt Champion Mar 28 '16 at 15:24
  • How are you launching it? There is almost no information here... – Neil Bartlett Mar 28 '16 at 20:08
  • Hi @Neil Bartlett I have a class `App` under **dist** in the package `rev.dist` that does the launching. It goes loops throug all the directories under the **rev** and starts any jars whose names match the names under `resources/plugins.txt`. I did an update to the question with `App.class` – Program-Me-Rev Mar 28 '16 at 20:22
  • Okay the code is fairly long and confusing so I'm not going to bother working out exactly what it does. However the basic pattern of: (1) install all the bundles, then (2) start all the bundles, is sound. So perhaps there is just a bug in the code. Have you tried running in a debugger? BTW why do you need to separately install and start the SCR bundle? Note that that bundle does actually start so there may be a clue here. – Neil Bartlett Mar 28 '16 at 20:31

1 Answers1

1

I have released a couple of first Early Access versions of Drombler FX - the modular application framework for JavaFX.

It's not based on Paul Bakker's work, but it's based on OSGi and Maven (POM-first), as well. Maybe you find it useful. The application framework is Open Source.

There is also a tutorial with a Getting Started page.

Puce
  • 37,247
  • 13
  • 80
  • 152