Prev Next

OSGi Runtime

What You Will Learn in This Section

In this section we start by defining a runtime environment. An OSGi runtime environment consists of a classpath, a framework, and a number of configuration properties that properly setup the framework. In contrast with the application server model, the runtime is unique for the application. In this section we show how to create an executable JAR that contains all the dependencies.

Running a framework requires assembling the application. Assembly consists of selecting an appropriate set of bundles and defining the framework’s context.

This requires to select the initial requirements of a runtime and then let bnd resolve this into a set of run bundles. Once we have got this set of run bundles we can export it into an executable JAR or other format.

Make sure you are in the top directory:

$ cd ~/workspaces/osgi.enroute.examples.eval

The POM

In the osgi.enroute.examples.eval directory we create the pom.xml file in a new bndrun directory.

osgi.enroute.examples.eval $ mkdir bndrun
osgi.enroute.examples.eval $ cd bndrun
bndrun $ vi pom.xml
// add the following file
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<parent>
		<groupId>org.osgi</groupId>
		<artifactId>osgi.enroute.examples.eval</artifactId>
		<version>1.0.0-SNAPSHOT</version>
	</parent>

	<artifactId>osgi.enroute.examples.eval.bndrun</artifactId>

	<packaging>jar</packaging>

We will define the OSGi runtime environment in a bndrun file. This file contains the myriad of details that is needed to define an OSGi runtime. Details like the class path, the set of bundles, system properties, framework configuration, etc. We will use the bnd-export-maven-plugin. This plugin will take a bndrun file as input and then generate an executable JAR. This is a JAR that contains all its dependencies.

	<build>
		<plugins>
			<plugin>

We’re using the 3.4.0-SNAPSHOT revision because this tutorial needed a newer feature that missed 3.3

				<groupId>biz.aQute.bnd</groupId>
				<artifactId>bnd-export-maven-plugin</artifactId>
				<version>3.4.0-SNAPSHOT</version>

We need to configure the plugin.

				<configuration>
					<resolve>true</resolve>
					<bndruns>

Here we specify one or more bndrun files. We’ll discuss the format of this file later.

						<bndrun>osgi.enroute.examples.eval.bndrun</bndrun>
					</bndruns>
					<targetDir>.</targetDir>
				</configuration>
				<executions>
					<execution>
						<goals>
							<goal>export</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>

We need to add our provider as a runtime dependency:

	<dependencies>
		<dependency>
			<groupId>org.osgi</groupId>
			<artifactId>osgi.enroute.examples.eval.simple.provider</artifactId>
			<version>1.0.0-SNAPSHOT</version>
		</dependency>

We also need a distro. So far we’ve been compiling against API only with the OSGi enRoute base API. However, we now need to add implementations. Implementations can come from different sources. For example IBM websphere, Karaf, Knopflerfish, Apache Felix, etc. However, the OSGi enRoute project has created a distro that consists of many different open source projects to demonstrate the interoperability of OSGi.

		<dependency>
			<groupId>org.osgi</groupId>
			<artifactId>osgi.enroute.pom.distro</artifactId>
			<version>2.0.0</version>
		</dependency>

	</dependencies>
</project>

We must also add bndrun as module in the parent pom.xml, e.g. after the existing api and simple.provider modules.

The bndrun file

The osgi.enroute.examples.eval.bndrun bndrun file contains a specification of an OSGi runtime. An OSGi runtime needs quite a bit of information and we collect that all in this file.

bndrun $ vi osgi.enroute.examples.eval.bndrun
// add the following file

The -standalone instruction is there to indicate that this does not run in bndtools but as a stand-alone definition.

-standalone: 

We need access to all the dependencies of this project. The bndrun file supports this with the Bnd Pom Repository. We then need to define the list of snapshot URLs and release URLs.

-plugin.examples.eval = \
	aQute.bnd.repository.maven.pom.provider.BndPomRepository; \
		snapshotUrls=https://oss.sonatype.org/content/repositories/osgi/; \
		releaseUrls=https://repo1.maven.org/maven2/; \
		pom=${.}/pom.xml; \
		name=examples.eval; \
		location=${.}/target/cached.xml

In the -runrequires section we list OSGi requirements that we want our runtime to have. In the initial case we only need the provider to run. The syntax for the -runrequires is the syntax for an OSGi requirement, as used in the OSGi Require-Capability header. Each clause consists of a namespace and a filter. The namespace defines a number of properties and the filter is an assertion on these properties. In this case we use the identity namespace to require a specific bundle, the provider bundle. The property name is osgi.identity following the convention for namespaces and the Bundle Symbolic Name is osgi.enroute.examples.eval.simple.provider.

-runrequires: 	\
	osgi.identity; \
		filter:='(osgi.identity=osgi.enroute.examples.eval.simple.provider)'

The -runfw specifies the framework we want to use.

-runfw: 		org.eclipse.osgi;version='[3.10.100.v20150529-1857,3.10.100.v20150529-1857]'

We can control the logging information during launching. Let’s keep this off for now:

-runtrace: 		false

In the example we use Equinox and equinox has a number of habits that need to be unlearned. For example, it has a built-in shell but it is better to define the used shell using standard OSGi techniques. These settings will not be further explained here.

#
# OSGi enRoute setting. These settings
# fixup some of the issues around equinox 
# defaults.
#

-runee: 						JavaSE-1.8
-resolve.effective:				resolve, active

-runproperties.eqnx: 				\
	osgi.console.enable.builtin=false, \
	osgi.console=, \
	org.osgi.service.http.port=8080

-runpath.eqnx: 					osgi.enroute.equinox.log.adapter
-runrequires.eqnx: \
	osgi.identity;filter:='(osgi.identity=org.apache.felix.log)'

-runsystempackages.eqnx:		javax.script
-runsystemcapabilities.dflt: 	${native_capability}

How to get the -runbundles

The definition so far cannot be run. We need to resolve the bndrun file. Resolving will take the -runrequires and the repository and calculate a closure of bundles. This closure then is the list of -runbundles that we need in our runtime.

We can resolve the requirements from Maven and get the list of bundles by running a mvn install in this project. This will attempt to resolve the initial requirements and calculate the list of bundles. If the list differs from the -runbundles setting then the install will fail but it will give the list of calculated bundles:

bndrun $ mvn install
...

-runbundles: \
	org.apache.felix.configadmin; version='[1.8.8,1.8.9)',\
	org.apache.felix.log; version='[1.0.1,1.0.2)',\
	org.apache.felix.scr; version='[2.0.2,2.0.3)',\
	org.eclipse.equinox.metatype; version='[1.4.100,1.4.101)',\
	org.osgi.service.metatype; version='[1.3.0,1.3.1)',\
	osgi.enroute.examples.eval.simple.provider; version='[1.0.0,1.0.1)'

[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
...
[INFO] ------------------------------------------------------------------------

You can now copy this list and paste it into the osgi.enroute.examples.eval.bndrun file at the end. Make sure there is only one (1) -runbundles instruction in the bndrun file.

NOTE: You can add false inside bnd-export-maven-plugin configurations if you wish the update is done automatically.

If we now run maven again we succeed and a JAR file is created in the project directory.

bndrun $ vi osgi.enroute.examples.eval.bndrun
// add/replace the -runbundles
bndrun $ mvn install
...
bndrun $ ls
osgi.enroute.examples.eval.bndrun	pom.xml					target
osgi.enroute.examples.eval.jar		src

Running

We can now run the application as follows:

bndrun $ java -version
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)
bndrun $ java -jar osgi.enroute.examples.eval.jar

The output is a little embarrassing …

Though rather disappointing, it does make sense since we’ve not created any bundle that does something that is visual to us. So the lack of output is understandable.

You can use Control-C to quit the application.

Tracing

Since we do not see any output it would be nice to know if the launching was ok. We can set the -runtrace instruction to true in the osgi.enroute.examples.eval.bndrun file to see the launching progress:

-runtrace: true

If we build and run the application, we see the following:

bndrun $ vi osgi.enroute.examples.eval.bndrun
// set -runtrace: true
bndrun $ mvn install
...
bndrun $ java -jar osgi.enroute.examples.eval.jar
# properties {launch.name=bndrun, osgi.console=, launch.noreferences=false, ...
...	
Id    State Modified      Location
0     ACTIV <>            System Bundle
1     ACTIV <>            jar/org.apache.felix.configadmin-1.8.8.jar
2     ACTIV <>            jar/org.apache.felix.log-1.0.1.jar
3     ACTIV <>            jar/org.apache.felix.scr-2.0.2.jar
4     ACTIV <>            jar/org.eclipse.equinox.metatype-1.4.100.v20150408-1437.jar
5     ACTIV <>            jar/org.osgi.service.metatype-1.3.0.jar
6     ACTIV <>            jar/osgi.enroute.examples.eval.provider-1.0.0-SNAPSHOT.jar
# framework=org.eclipse.osgi.launch.Equinox@7c0e2abd
# registered launcher with arguments for syncing
# will wait for a registered Runnable

The output is quite extensive. If you have problems during the launch it is a great help and including this information with a bug report is highly appreciated.

The Gogo Shell

What we’re missing is a shell to see the inner bowels of our runtime. The most popular shell in OSGi is the Gogo shell. We can add this shell by adding it as an initial run requirement in the osgi.enroute.examples.eval.bndrun file:

-runrequires: \
	osgi.identity;filter:='(osgi.identity=osgi.enroute.examples.eval.simple.provider)',\
	osgi.identity;filter:='(osgi.identity=osgi.enroute.gogo.shell.provider)'

You probably also want to set -runtrace to false to minimize the output. We will now get a shell; as long as the shell works we can assume the launch was ok.

We now need to resolve the bndrun file. We run mvn install which will fail because the new list of bundles does not match the current list of bundles. We then copy the -runbundles into the osgi.enroute.examples.eval.bndrun file by replacing the existing list. (Make sure you do not get more than 1 -runbundles instruction in the file.)

bndrun $ vi osgi.enroute.examples.eval.bndrun
// add the -runrequires for Gogo
bndrun $ mvn install
....
-runbundles: \
	org.apache.felix.configadmin; version='[1.8.8,1.8.9)',\
	org.apache.felix.gogo.runtime; version='[0.16.2,0.16.3)',\
	org.apache.felix.log; version='[1.0.1,1.0.2)',\
	org.apache.felix.scr; version='[2.0.2,2.0.3)',\
	org.eclipse.equinox.metatype; version='[1.4.100,1.4.101)',\
	org.osgi.service.metatype; version='[1.3.0,1.3.1)',\
	osgi.enroute.examples.eval.provider; version='[1.0.0,1.0.1)',\
	osgi.enroute.gogo.shell.provider; version='[2.0.0,2.0.1)'
....
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
bndrun $ vi osgi.enroute.examples.eval.bndrun
// copy the -runbundles from the output of mvn into the file
// replacing the existing -runbundles 
bndrun $ mvn install
...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
bndrun $ java -jar osgi.enroute.examples.eval.jar 
             ____             _       
   ___ _ __ |  _ \ ___  _   _| |_ ___ 
  / _ \ '_ \| |_) / _ \| | | | __/ _ \
 |  __/ | | |  _ < (_) | |_| | |_  __/
  \___|_| |_|_| \_\___/ \__,_|\__\___|
              https://v2archive.enroute.osgi.org
              
G! 

Gogo has many commands. You can find an introduction at the Gogo App Note.

For example:

G! bundles
0|Active     |    0|org.eclipse.osgi (3.10.100.v20150529-1857)
1|Active     |    1|org.apache.felix.configadmin (1.8.8)
2|Active     |    1|org.apache.felix.gogo.runtime (0.16.2)
3|Active     |    1|org.apache.felix.log (1.0.1)
4|Active     |    1|org.apache.felix.scr (2.0.2)
5|Active     |    1|org.eclipse.equinox.metatype (1.4.100.v20150408-1437)
6|Active     |    1|org.osgi.service.metatype (1.3.0.201505202024)
7|Active     |    1|osgi.enroute.examples.eval.provider (1.0.0.201610030911)
8|Active     |    1|osgi.enroute.gogo.shell.provider (2.0.0.201608121439-SNAPSHOT)
G! 

User Friendly Commands

What we’re running is the base core primitive simple Gogo shell. This means it can run the commands that are on the Bundle Context (that is bundles command is mapped to BundleContext.getBundles()) but there are now user friendly commands. A number of such commands are implemented in the org.apache.felix.gogo.command bundle. So we could add this bundle to the -runrequires instruction:

-runrequires: \
	osgi.identity;filter:='(osgi.identity=osgi.enroute.examples.eval.simple.provider)',\
	osgi.identity;filter:='(osgi.identity=osgi.enroute.gogo.shell.provider)',\
	osgi.identity;filter:='(osgi.identity=org.apache.felix.gogo.command)'

So now you can resolve again and then we can run help in the Gogo shell:

bndrun $ vi osgi.enroute.examples.eval.bndrun
// replace the -runrequires
bndrun $ mvn install
...

-runbundles: ...
...
bndrun $ vi osgi.enroute.examples.eval.bndrun
// replace -runbundles
bndrun $ java -jar osgi.enroute.examples.eval.jar 
             ____             _       
   ___ _ __ |  _ \ ___  _   _| |_ ___ 
  / _ \ '_ \| |_) / _ \| | | | __/ _ \
 |  __/ | | |  _ < (_) | |_| | |_  __/
  \___|_| |_|_| \_\___/ \__,_|\__\___|
              https://v2archive.enroute.osgi.org

              
G! help
felix:bundlelevel
felix:cd
felix:frameworklevel
felix:headers
...
scr:config
scr:disable
scr:enable
scr:info
scr:list
G! 

What did We Learn?

In this section we’ve created a bndrun file to create an OSGi runtime. We then learned how to add requirements to the file and resolve it so we get the -runbundles. We then learned how to add these -runbundles to the bndrun file so they can be exported into an executable jar.

We then executed this JAR and added a Gogo shell.


Prev Next