2017-06-04 2 views
0

Remarque: Dans mon cas, j'utilise l'implémentation Apache Felix si cela est important.Impossible de démarrer le regroupement par programme

J'ai écrit un paquet que j'utilise comme test. Il est très simple « Bonjour tout le monde » paquet qui ne font que un message d'impression stdout lors du démarrage/arrêt:

public class Activator implements BundleActivator { 

    @Override 
    public void start(BundleContext context) throws Exception { 
     System.out.println("Hello, World."); 
    } 

    @Override 
    public void stop(BundleContext context) throws Exception { 
     System.out.println("Goodbye, World."); 
    } 

} 

Il y a aussi le fichier MANIFEST qui plutôt inutile de poster depuis quand je déploie au-dessus de bundle via la console Apache Felix de la norme distribution (which can be downloaded here) Le paquet commence et imprime le message.


La prochaine étape que j'essaye de faire est de déployer le même paquet en utilisant l'approche programmatique. Malheureusement, cela ne fonctionne pas pour moi. Mon code ressemble comme suit:

public static void main(String[] args) throws Exception { 
    FrameworkFactory frameworkFactory = getFrameworkFactory(); 
    Framework framework = frameworkFactory.newFramework(null); 

    System.out.println("BundleID = " + framework.getBundleId()); 
    System.out.println("State = " + getState(framework.getState())); 

    framework.init(); 

    System.out.println("BundleID = " + framework.getBundleId()); 
    System.out.println("State = " + getState(framework.getState())); 

    BundleContext bundleContext = framework.getBundleContext(); 
    bundleContext.addBundleListener((event) -> { 
     System.out.println("Bundle Changed Event"); 
    }); 
    bundleContext.addFrameworkListener((event) -> { 
     System.out.println("Framework Event"); 
    }); 
    bundleContext.addServiceListener((event) -> { 
     System.out.println("Service Changed Event"); 
    }); 

    Bundle bundle = bundleContext.installBundle("file://<absolute-path-to-bundle-jar-same-as-above"); 

    System.out.println("BundleID = " + bundle.getBundleId()); 
    System.out.println("State = " + getState(bundle.getState())); 

    bundle.start(); 

    System.out.println("BundleID = " + bundle.getBundleId()); 
    System.out.println("State = " + getState(bundle.getState())); 
} 

private static FrameworkFactory getFrameworkFactory() throws IllegalStateException { 
    ServiceLoader<FrameworkFactory> loader = ServiceLoader.load(FrameworkFactory.class); 

    FrameworkFactory factory = null; 
    for (FrameworkFactory iterator : loader) { 
     if (factory != null) { 
      throw new IllegalStateException("Ambiguous SPI implementations."); 
     } 

     factory = iterator; 
    } 

    return factory; 
} 

private static String getState(int state) { 
    switch (state) { 
    case Bundle.UNINSTALLED: 
     return "UNINSTALLED"; 
    case Bundle.INSTALLED: 
     return "INSTALLED"; 
    case Bundle.RESOLVED: 
     return "RESOLVED"; 
    case Bundle.STARTING: 
     return "STARTING"; 
    case Bundle.STOPPING: 
     return "STOPPING"; 
    case Bundle.ACTIVE: 
     return "ACTIVE"; 
    default: 
     throw new IllegalStateException("Unknown state"); 
    } 
} 

La sortie ressemble à suivre:

BundleID = 0 
State = INSTALLED 
BundleID = 0 
State = STARTING 
Bundle Changed Event 
BundleID = 1 
State = INSTALLED 
BundleID = 1 
State = INSTALLED 

Pour autant que je comprends bundle est bien installé, mais 4 dernières lignes indiquent que bundle.start() mais j'ai Ignoré pour une raison quelconque.

Pourriez-vous me préciser ce qui me manque pour faire ce travail?

Répondre

0

Après une heure de débogage et de lecture à travers javadoc plus attentivement cela se produit car l'infrastructure a été initialisée au lieu d'être démarré. Pour faire un exemple de travail, vous devez simplement ajouter framework.start() après framework.init() (ou simplement appeler framwork.start() qui appelle framework.init() si nécessaire).

Je quittais ces informations car il y a peu de choses confuses:

  1. Documentation officielle à Apache Felix ont des informations sur l'intégration dans le cadre de l'application hôte. Malheureusement, il n'y a qu'un exemple qui utilise les mécanismes personnalisés Apache Felix qui le rendent non portable pour d'autres implémentations. Ce qui prête à confusion est warning note qui, si vous voulez créer une solution portable, vous devez utiliser init() et getBundleContext(). whole note citée ci-dessous:

AVERTISSEMENT La propriété de configuration felix.systembundle.activators est spécifique à la mise en œuvre du cadre Felix. Si vous souhaitez que votre code fonctionne avec d'autres implémentations de structure, vous devez appeler le init() sur l'instance de structure et utiliser directement getBundleContext(). Sinon, l'approche serait très similaire.

  1. JavaDoc pour la version de la méthode init() parameterless ne mentionnent pas l'initialisation n'est pas même que le démarrage du cadre, bien que ces informations ont init(FrameworkListener...).

Ce cadre ne sera pas réellement démarré avant l'appel de start.