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.
