# Custom OSGi Launcher mit config.ini



## astralarse (30. Mrz 2009)

Hallo,

ich versuche gerade ein Equinox Framework mit Hilfe einer Wrapper-Applikation zu starten und lauf da noch an einer Stelle gegen die Wand.

Das Problem ist, dass mein aktueller Code mein config.ini nicht hernimmt um sich zu initialisieren.
Symptom: in der execute() führt er die gewollten Befehle aus, die ein CommandProvider Bundle im Framework zur Verfügung stellt. Da die ganzen Bundles beim Frameworkstart aber nicht installiert werden, findet er hier natürlich auch nix. Ich seh am Output noch das "ping", allerdings fliegt er mir aber direkt nach m_console.run() raus, so dass ich kein "pong" erhalte. Es wird leider keine Exception geworfen und merkwürdigerweise führt er danach nichtmal mehr den finally-Teil im main() aus.

Kann mir da jemand auf die Sprünge helfen?

Führe ich den Start des Frameworks ganz normal über "java -jar org.eclipse.equinox.<blabla>.jar -console" aus, so ist alles paletti und auch die Bundles entsprechend meines config.ini richtig installiert und gestartet.


```
package com.cruehl.osgi;

import java.io.File;
import org.eclipse.osgi.baseadaptor.BaseAdaptor;
import org.eclipse.osgi.framework.adaptor.FrameworkAdaptor;
import org.eclipse.osgi.framework.internal.core.OSGi;
import org.eclipse.osgi.framework.internal.core.FrameworkConsole;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;

public class FooStarter
{
   private FrameworkAdaptor m_adaptor;
   private FrameworkConsole m_console;
   private OSGi m_osgi;
   private BundleContext m_context;
   private static int m_errorcode = 3; // implicit error

   /**
    * Constructor.
    * 
    * @param args
    */
   public FooStarter(String[] args)
   {
      File test = new File("");
      String path = test.getAbsolutePath();

      System.setProperty("osgi.install.area", path);
      System.setProperty("osgi.configuration.area", "file:configuration");
      System.setProperty("osgi.framework", "file:org.eclipse.osgi_3.4.3.R34x_v20081215-1030.jar");
      //System.setProperty("osgi.launcherIni", "eclipse");

      m_adaptor = new BaseAdaptor(args);
      m_osgi = new OSGi(m_adaptor);
      m_context = m_osgi.getBundleContext();
   }

   /**
    * Launches Equinox, runs bundles and closes framework when done.
    */
   public void start()
   {
      m_osgi.launch();

      // TODO run bundles
      execute();

      // testing stuff
      System.out.println(System.getProperty("output"));
      System.out.println(m_context.getProperty("output"));
      printInstalledBundles();
      getBundleErrorFlag();
      // testing stuff end

      m_osgi.close();
   }

   /**
    * Du erträgst die Erniedrigung mit einem Lächeln im Gesicht,
    * doch was mal aus Dir werden soll, das weisst Du nicht!
    * Der Eine hats, der Andere nicht - doch das hast Du nicht so gemacht!
    * Dein Weg führt Dich in dunkle Straßen. Hörst Du wie man über Dich lacht?
    * Die Stunde des Siegers kommt für jeden irgendwann...
    */
   private void execute()
   {
      // TODO seems that it takes no note of my config.ini
      // the following commands will be sequentially executed
      String[] cmds = { "ss", "diag 1", "diag 5", "close" };

      m_console = new FrameworkConsole(m_osgi, cmds);
      System.out.println("ping");
      m_console.run(); // here something goes wrong...
      System.out.println("pong");
      m_console.shutdown();
      System.out.println("ping");
   }

   /**
    * Collects Global error flag from framework. Flag should be set by CrimsonGore.
    */
   private void getBundleErrorFlag()
   {
      // TODO problem: both return null
      System.out.println(System.getProperty("error"));
      System.out.println(m_context.getProperty("error"));

      // get error flag value
      if (m_context.getProperty("error") != null)
      {
         String bundleErrorFlagValue = m_context.getProperty("error");
         m_errorcode = Integer.parseInt(bundleErrorFlagValue);
      }
      else
      {
         System.out.println("\nERROR Could not read bundle error flag\n");
         m_errorcode = 2;
      }
   }

   /**
    * For testing: prints all currently installed bundles.
    */
   private void printInstalledBundles()
   {
      Bundle[] installed = m_context.getBundles();

      for (int i = 0; i < installed.length; i++)
         System.out.println(i + "\t" + installed[i].getSymbolicName());
   }

   /**
    * Main method.
    * 
    * @param args
    */
   public static void main(String[] args)
   {
      try
      {
         FooStarter starter = new FooStarter(args);
         starter.start();
      }
      catch (Exception ex)
      {
         // TODO
         System.out.println("ERROR Ooops, something went wrong!");
         ex.printStackTrace();
      }
      finally
      {
         System.out.println("pong " + m_errorcode);
         System.exit(m_errorcode);
      }
   }
}
```

Hier der Vollständigkeit halber noch eben mein config.ini.


```
org.osgi.framework.bootdelegation=*
osgi.bundles=org.eclipse.osgi.services_3.1.200.v20071203.jar@start,\
  org.eclipse.equinox.util_1.0.0.v20080414.jar@start,\
  org.eclipse.equinox.ds_1.0.0.v20080427-0830.jar@start,\
  bundles/de.<blabla>.loggingunit.jar@start,\
  bundles/de.<blabla>.crimsongore.jar@start,\
  bundles/de.<blabla>.basicchecker.jar@start,\
  bundles/de.<blabla>.extendedchecker.jar@start,\
  bundles/de.<blabla>.importexport.jar@start,\
  bundles/de.<blabla>.businesslogic.jar@start,\
  bundles/de.<blabla>.compiler.jar@start
eclipse.ignoreApp=true
eclipse.application.noDefault=true
osgi.clean=true
eclipse.log.backup.max=1
```

Hier auch gleich noch die Frage wie ich das Loggingverhalten des Frameworks unterdrücken kann? "eclipse.log.backup.max=1" scheint keine Wirkung zu haben, denn er erzeugt im Falle dass, einen neuen Log ohne den alten zu entfernen. Und da ich ja nen eigenen Logger hab, und das Tool ansonsten in einer ReadOnly-Umgebung laufen soll, wär's praktisch, wenn man die Anzahl automatisierter Framework-Files auf den OSGi-Cache reduzieren könnte.

So, viel Text und viel Code, aber ich hoffe dennoch auf Eure Hilfe! 
Danke schonmal!


----------



## Wildcard (30. Mrz 2009)

Starte doch einfach so wie es die jar tun würde:
[HIGHLIGHT="Java"]Main.main(args)[/HIGHLIGHT]


----------



## astralarse (31. Mrz 2009)

Also das versteh ich jetzt nicht. Wie genau meinst Du das? Ich hab doch ne main(args). Mein Problem liegt doch - so vermute ich zumindest - in der Art und Weise wie ich das Framework und die FrameworkConsole starte/initialisiere.


----------



## astralarse (31. Mrz 2009)

Okay, um das ganze Thema nochmal verkürzt darzustellen:

Ich habe meine Bundles im Unterordner bundles/. Die System-Bundles *org.eclipse.osgi*, *org.eclipse.osgi.services*, *org.eclipse.equinox.util* und *org.eclipse.equinox.ds* liegen im Wurzelverzeichnis meiner Anwendung.

Im Unterordner *configuration/* habe ich folgendes *config.ini*:

```
osgi.clean=true
osgi.locking=none
org.osgi.framework.bootdelegation=*
osgi.compatibility.bootdelegation=true
osgi.configuration.cascaded=true
eclipse.ignoreApp=true
eclipse.application.noDefault=true
eclipse.log.backup.max=1
osgi.bundles=org.eclipse.osgi.services_3.1.200.v20071203.jar@start,\
  org.eclipse.equinox.util_1.0.0.v20080414.jar@start,\
  org.eclipse.equinox.ds_1.0.0.v20080427-0830.jar@start,\
  bundles/de.bla.bundle1.jar@start,\
  bundles/de.bla.bundle2.jar@start,\
  bundles/de.bla.bundle3.jar@start,\
  bundles/de.bla.bundle4.jar@start,\
  bundles/de.bla.bundle5.jar@start,\
  bundles/de.bla.bundle6.jar@start,\
  bundles/de.bla.bundle7.jar@start
```

1.) Problem:

Wie bewerkstellige ich eine "zweigleisige Fahrt" zwischen herkömmlichem Aufruf,

```
java -jar -Doutput="blabla" org.eclipse.osgi.jar -console
```
der offensichtlich auf das *config.ini* zurückgreift und alles meiner Vorstellung entsprechend installiert und startet; und dem Aufruf mittels einer "Wrapperaplikation"

```
java -jar -Doutput="blabla" my_foo_launcher.jar -console
```
 die *leider KEINE Notiz von meinem config.ini zu nehmen scheint*. Und wie bekomme ich es darüberhinaus hin, dass beide denselben OSGi Cache verwenden?

2.) Problem:

Lege ich innerhalb dieser Wrapperapplikation eine FrameworkConsole Instanz an und starte diese mit console.run(), so werden zwar alle via cmd-Argumente übergebenen Befehle ausgeführt, aber danach einfach abgebrochen. Jeder nachfolgende Methodenaufruf wird einfach ignoriert. Nichtmal der finally-Block im main() wird mehr ausgeführt. Woran könnte das liegen?

Ich fange mein config.ini bzw. meine Wrapperapplikation gerne auch nochmal from scratch an, sofern Ihr mir dabei helfen könnt! Allerdings will bzw. kann ich auch nicht den Code in den Bundles selbst verändern. Mein einziger Spielraum sind also tatsächlich die Wrapperapp. und das config.ini.


----------



## Wildcard (31. Mrz 2009)

1. Du startest doch ganz anders. Der equinox Launcher startet die Main während du new OSGi().launch() machst. Also: warum startest du nicht auch die Main? org.eclipse....Main.main(args).

2. Ich vermute deine Console wartet einfach auf weitere eingaben


----------



## astralarse (1. Apr 2009)

Hallo Wildcard,

1.) Ich glaub ich weiss worauf Du hinaus willst, aber ich steh grad noch aufm Schlauch was die Umsetzung betrifft. Kannst Du mir beispielhaft zeigen wie Du das im Code umsetzen würdest?



> Unable to create FrameworkAdaptor.
> java.lang.reflect.InvocationTargetException
> at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
> at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
> ...



2.) Okay...? Hm, möglicherweise gibts da ein spezielles Command Set das ich übersehen hab. Ich schau mal nach ob ich hierzu was googlen kann. Danke für den Hinweis!


----------



## astralarse (1. Apr 2009)

Ich weiss nicht, ob meine aktuelle Idee nicht Deine sogar umsetzt (hab mir die Methoden noch nicht genauer angesehen), aber mit EclipseStarter.run(args, null) scheint zumindest das Framework richtig aufgesetzt und gestartet zu werden. Womit Punkt 1.) rein theoretisch abgearbeitet wäre. Die Console osgi> wird automatisch gestartet, aber nach kurzer Zeit wieder geschlossen. Auch der exitcode stimmt. Jetzt fehlt mir nur noch der Zugriff auf die Console und das dortige "abspulen" meiner Commands oder kann ich die sogar ins ini File reinklatschen?


----------

