Gradle

Gradle OSGi Plugin Example: BNDTools Bundle Integration

In this example we will talk about how to integrate OSGi frameworks with Gradle build tool. This work consists in build JAR files and customizing Manifest file through Gradle build Script and Deploying them in a OSGi Container like Apache Felix.

1. Introduction to Gradle and OSGi Integration

Gradle is an automatic build tool of more use today, so it’s almost necessary to integrate the different types of projects with Gradle, to automate the process of build and liberation. In this example we will see how using Gradle can compile, build, install and run a bundle in an OSGi environment. The main goal is to understand Gradle integration with OSGi BND tools.

1.1 Basic Concepts

There are some basic concepts that we must check before starting the example.

  • Gradle: Our tool to build and automate the process.
  • OSGi: It’s the framework to make Java Modular applications and the environment where to deploy.
  • BND Tools: It’s a framework or library pack, that makes OSGi development process more friendly and give to us a lot of capabilities to customize out OSGi bundles. OSGi and BND Tools are required each other.
  • Gradle-Osgi Plugin: It’s a Gradle Plugin developed by Renato Athaydes to make the OSGi integration easier.
  • Apache Felix, Eclipse Equinox: Are the main OSGi implementations, are containers to deploy OSGi bundles. Think in OSGi bundles like a war file and Apache Felix like Tomcat container.

I want to make this example so simple, so we start.

2. What do We Need?

  • IDE: Eclipse Luna 4.4, you can download here
  • Gradle 2.x or superior, you can download Gradle 2.5 here
  • Java JDK 1.7_75 or superior, download here
  • BND Tools 2.4, this is a Eclipse Plugin that we can download in Eclipse Marketplace
  • Gradle-Osgi Plugin, you can get more detail here

3. Environment Configuration

To make simpler the example, we assume that you have already installed your Eclipse, JDK, Gradle and environment variables for both tools (JAVA_HOME and GRADLE_HOME).

How to Install OSGi?

It’s the most simple installation ever, you only need to download Eclipse! Eclipse is one the projects that use OSGi for your development and release process, so OSGi, Equinox and Felix frameworks are already installed as Eclipse’s plugins.

Next Step, Install BND Tools Eclipse Plugin.

Please download and install from Eclipse Marketplace using the menu: Help > Eclipse Marketplace > type “bndtools”.

BND Tools Eclipse Plugin installation
BND Tools Eclipse Plugin installation

4. Creating OSGi Project

Create a new OSGi bundle project using File > New > Other > Bndtools > Bndtools OSGi project

BND Tools OSGi Project
BND Tools OSGi Project

Then, type a project’s name and keep all the other settings as they are, then click next to choose project template, in this case, we use OSGi component development by default.

OSGi Project Template
OSGi Project Template

So, when we create the first OSGi project, bnd tools ask to create a cnf project, that will store all OSGi configuration and libraries downloaded from external repositories. Only click next and leave all configurations by default, at the end we have 2 projects cnf (bnd tools configuration) and our Gradle OSGi project.

BND Tools CNF Project
BND Tools CNF Project

Then, define a package for the Bundle Activator and create a new class, we call HelloActivator.java

Gradle OSGi BundleProject
Gradle OSGi BundleProject

HelloActivator.java

package com.javacodegeeks.gradle.osgi;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;

public class HelloActivator implements BundleActivator {
	private BundleContext context;

	public void start(BundleContext context) throws Exception {
		System.out.println("Hello JCG, Welcome to OSGi World!!");
		this.context = context;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
	 */
	public void stop(BundleContext context) throws Exception {
		System.out.println("Goodbye JCG");
		this.context = null;
	}

}

5. Deploying OSGi Project

The last step before injects Gradle is to deploy the Bundle in an OSGi container, in this example we use Apache Felix. To make possible this, we need to configure bnd.bnd file.

Define a version number, choose the Activator that we created before. In the Export Packages please choose the green plus sign, and add the main package that contains the Activator.

OSGi-Bundle-Content
OSGi Bundle Content

In the Run Tab, we must configure 3 options.

  • Core Runtime, establish the OSGi Framework and JDK to execution, for this case choose Apache Felix 4.0.3 and Java 1.7.
  • Run Requirements, add all 4 bundles that appears in the caption, project itself (GradleOSGiProject in this case), osgi.cmpn, felix.command and felix.shell.
  • In the bottom of the Run tab, add the same bundles at Run Bundles configuration

OSGi Run BND Tools
OSGi Run BND Tools

Finally, we can run the project using Run OSGi button in Run tab of bnd.bnd file, so this is the output. We can see the installed bundles typing lb on Apache Felix Gogo Shell, so when we start or stop OSGiGradle Bundle, start and stop Activator’s methods are executed.

Hello JCG, Welcome to OSGi World!!
____________________________
Welcome to Apache Felix Gogo

g! lb
START LEVEL 1
   ID|State      |Level|Name
    0|Active     |    0|System Bundle (4.4.1)
    1|Active     |    1|GradleOSGiProjectIntegration (1.0.0.201507130549)
    2|Active     |    1|Apache Felix Gogo Command (0.14.0)
    3|Active     |    1|Apache Felix Gogo Runtime (0.12.1)
    4|Active     |    1|Apache Felix Gogo Shell (0.10.0)
g! 

6. Gradle Integration

To “Gradlify” the OSGi Project we need to create a Gradle Build script and configure it correctly. So, create a new File in root project, New > File > type name “build.gradle”.

This is the file, so we’ll look in detail each instruction.

build.gradle

/*
 * Author: Andres Cespedes
 * Date: 01 July 2015
 * Example: Gradle OSGi Integration Example
 * Site: www.javacodegeeks.com
 * */
buildscript {
	repositories {
		jcenter()
		mavenCentral()
	}
	dependencies {
		classpath "com.athaydes.gradle.osgi:osgi-run-core:1.2"
	}
}

// repositories to download external files, like apache felix
repositories {
	jcenter()
	mavenCentral()
}

// java version source compatibility
sourceCompatibility = 1.7

apply plugin: 'osgi-run'

// osgi-run plugin task that add OSGi subprojects as a bundle files to deploy.
runOsgi {
  bundles += subprojects
}

jar {
    manifest { // Manifest.MF file customization
        instruction 'Private-Package','com.javacodegeeks.gradle.osgi'
        instruction 'Bundle-Vendor', 'JavaCodeGeeks'
        instruction 'Bundle-Description', 'First OSGi Bundle Created By Gradle JCG Tutorial'
        instruction 'Bundle-Activator', 'com.javacodegeeks.gradle.osgi.HelloActivator'
        instruction 'Bundle-ManifestVersion', '2'
        instruction 'Bundle-Version', '1.0.0.${tstamp}'
        instruction 'Bundle-Name', 'GradleOSGiProjectIntegration'
        instruction 'Bundle-SymbolicName', 'GradleOSGiProjectIntegration'
        instruction 'Export-Package', 'com.javacodegeeks.gradle.osgi;version="1.0.0";uses:="org.osgi.framework"'	
    }
}

The first part buildscript, define the repositories and dependencies to import Gradle Bnd OSGi Plugin. In line 18, we set repositories to download and import external libraries to Gradle, this part it’s important as some think they just simply repositories defined in the buildscript block, are necessary to get libraries like apache felix, these libraries are downloaded to ‘%USER_HOME%\.gradle\caches\modules-2\files-2.1’ directory.

In line 20, apply the external OSGi plugin developed by Renato Athaydes, because Gradle’s official plugin doesn’t add value at all, don’t adds tasks more than customize the Manifest.

Line 23 and 27 are the main part of the script, then we add the project to the bundles to deploy and then can configure OSGi Manifest, each Manifest property is added as instruction, you can check OSGi documentation for available properties.

7. Running Gradle OSGi Integration

This is how integration works.

Select build.gradle file and press Ctrl+Alt+D to open windows command shell, then execute this Gradle command to run the OSGi environment.gradle runOsgi or gradle rO as shortened way.

Microsoft Windows [Versión 6.3.9600]
(c) 2013 Microsoft Corporation. Todos los derechos reservados.

C:\Users\Andres\workspaceLuna\GradleOSGiProject>gradle rO
:GradleOSGiProject:compileJava UP-TO-DATE
:GradleOSGiProject:processResources UP-TO-DATE
:GradleOSGiProject:classes UP-TO-DATE
:GradleOSGiProject:jar
:GradleOSGiProject:createOsgiRuntime
:GradleOSGiProject:runOsgi
____________________________
Welcome to Apache Felix Gogo

> Building 83% > :GradleOSGiProject:runOsgilb
g! START LEVEL 1
   ID|State      |Level|Name
    0|Active     |    0|System Bundle (4.4.0)
    1|Active     |    1|Apache Felix Gogo Command (0.14.0)
    2|Active     |    1|Apache Felix Gogo Runtime (0.12.1)
    3|Active     |    1|Apache Felix Gogo Shell (0.10.0)
> Building 83% > :GradleOSGiProject:runOsgiinstall file:../GradleOSGiProject.jar

g! Bundle ID: 4
> Building 83% > :GradleOSGiProject:runOsgi

When apache felix gogo shell is active, type lb to see all available Bundles, if your bundle don’t appears yet, so let install it, how? Execute this simple command install file:../GradleOSGiProject.jar, obviously considering the name of your jar; apache gogo shell will tell you the Bundle ID, in this case is 4.

8. Testing Gradle OSGi

Gradle already setup OSGi environment, so, executing apache gogo shell commands we can interact in Gradle thread with the OSGi Bundle, updating Manifest or Activator itself.

Testing Gradle OSGi Plugin
Testing Gradle OSGi Plugin

Then, if we modify any artifact or java file only executing update BundleID in Gradle OSGI environment shell, in this case update 5 we get updated Bundle, if we start or stop the Bundle can get updated messages.

For the last part of this example, the Manifest is printed in console executing headers BundleID command, headers 5, useful to compare the deployed Bundle with Gradle Manifest configuration.

> Building 83% > :GradleOSGiProject:runOsgiheaders 5
g!
GradleOSGiProject (5)
---------------------
Bnd-LastModified = 1436938982133
Bundle-Activator = com.javacodegeeks.gradle.osgi.Activator
Bundle-ManifestVersion = 2
Bundle-Name = GradleOSGiProject
Bundle-SymbolicName = GradleOSGiProject
Bundle-Version = 1.0.0.201507150543
Created-By = 1.7.0_67 (Oracle Corporation)
Export-Package = com.javacodegeeks.gradle.osgi;version="1.0.0";uses:="org.osgi.f
ramework"
Import-Package = org.osgi.framework;version="[1.3,2)"
Manifest-Version = 1.0
Private-Package = com.javacodegeeks.gradle.osgi
Require-Capability = osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.7))"
Tool = Bnd-2.4.1.201501161923
> Building 83% > :GradleOSGiProject:runOsgi

9. Key Points

Tips

  • Gradle Official plugin is poor to support OSGi integration
  • Key point to Gradle-OSGi integration is to know how to install external bundles
  • Unofficial Gradle Run Osgi Bundle plugin facilitates the integration process, thanks to Renato Athaydes for his job.
  • Manage OSGi deployment through Gradle enhances the development process by automatization and isolation the execution from Eclipse

10. Download the Eclipse Project

This was an example of Gradle OSGi Plugin.

Download
You can download the full source code of this example here Gradle OSGi Project

Andres Cespedes

Andres is a Java Software Craftsman from Medellin Colombia, who strongly develops on DevOps practices, RESTful Web Services, Continuous integration and delivery. Andres is working to improve software process and modernizing software culture on Colombia.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button