Hello World Example

The HelloWorld example shows how to create a simple activator that prints a message when starting/stopping the bundle. To show how data can be stored by the activator a data struct is created which is passed to all calls made from the framework to the activator.

Activator

To be able to start or stop a bundle an activator is needed. In Celix an activator has to implement the "bundle_activator.h" header. This header contains the following templates:

  • bundleActivator_create()
  • bundleActivator_start(void * data, BUNDLE_CONTEXT ctx)
  • bundleActivator_stop(void * data, BUNDLE_CONTEXT ctx)

These functions will be implemented in a file called activator.c:

1
2
3
4
#include <stdlib.h>
#include <stdio.h>

#include "bundle_activator.h"

Create

The create function is used to create the data object for the activator. In this data object the service registration etc can be stored. It is possible to return NULL. The HelloWorld example uses a data struct to store a string which is printed during the start and stop function.

1
2
3
4
5
6
7
8
9
struct userData {
    char * word;
};

void * bundleActivator_create() {
    struct userData * data = malloc(sizeof(*data));
    data->word = "World";
    return data;
}

Start

The start function is the entry point of the bundle. After installing the bundle, the framework calls the start function to actually start the bundle. In the HelloWorld example it only prints a message using the data from the userData struct.

1
2
3
4
5
void bundleActivator_start(void * userData, BUNDLE_CONTEXT context) {
    struct userData * data = (struct userData *) userData;
    printf("Hello %s\n", data->word);

}

Stop

The stop function is called when the bundle is stopped.

1
2
3
4
void bundleActivator_stop(void * userData, BUNDLE_CONTEXT context) {
    struct userData * data = (struct userData *) userData;
    printf("Goodbye %s\n", data->word);
}

Manifest

In Celix manifest files are used to describe a service. For example a symbolic name, the version but also exported (provided) or imported (required) services and the name of the library contained in a bundle. Every bundle requires a manifest file, and this file must be located in the MANIFEST directory and called MANIFEST.MF. For the HelloWorld example a simple Manifest file is needed with a symbolic name, version and library name.

1
2
3
Bundle-SymbolicName: hello_world
Bundle-Version: 1.0.0
library: hello_world

Bundle

Finally, to build the library and create the bundle, a CMake build file is needed. In this build file the library is created from the source code, includes can be given, link libraries can be defined and the bundle is created.

1
2
3
4
5
add_library(hello_world SHARED activator)
include_directories("${PROJECT_SOURCE_DIR}/celix")
target_link_libraries(hello_world framework)

bundle(hello_world)

In the top level CMake file the HelloWorld make file has to be included. This depends on the location of the HelloWorld example. Top Level CMakeList.txt

add_subdirectory(hello_world)

Target

To be able to use bundles a configuration is needed. This configuration contains a list of bundles to start. Celix contains a CMake macro to simply the process of create such configuration. The target macro can be called with a name and a list of bundles. The build creates the configuration file and copies the bundles to a directory with the same name as the target. The HelloWorld bundle is included, as well as a shell. The shell is used to be able to list and stop/start installed bundles. Targets are defined in the target.cmake file in the root of the project. target.cmake

deploy("hello_world" BUNDLES hello_world shell shell_tui)

Building

After creating the build files, the bundle and target must be build/created. Building and running is explained in detail on Building and Running Celix. For the HelloWorld example the following steps need to be executed from the root of the project. It is assumed that the environment is setup properly.

mkdir build
cd build
cmake ..
make deploy
cd deploy/hello_world
../../launcher/launcher

After starting the launcher, "Hello World" is printed and the Celix shell is visible. In the shell the "ps" command can be used to print a list of running bundles.

-> ps
  ID    State        Name
  1     Active       hello_world
  3     Active       shell_tui
  2     Active       shell
  0     Active       framework

There is also a stop and start command. Stopping the hello_world bundle will print "Goodbye World", and starting it again "Hello World".

-> stop 1
Goodbye World
-> start 1
Hello World

The executable can be stopped using "ctrl-c". This will interrupt the process, stop and uninstall all bundles and exit the process.