Introduction

The aim of the maven plugin is to speed up development by means of an OSGi environment. It supports creating custom distribution packages and run integration tests on them.

Usage

Dependency collection

In case of dist or integration-test goals the plugin checks the project which the goal was started with all of it's dependencies, except for the provided scope if they are OSGi bundles. The OSGi bundles will be deployed to the generated environment where the checks ran successfully. A dependency is an OSGi bundle if it has the Bundle-SymbolicName and the Bundle-Version manifest headers defined.

Distribution packages

In the goals, this plugin uses distribution packages. A distribution package is a simple ZIP file available in a maven repository with the dependencies and configuration files of the framework. By default, there is an Equinox based distribution package. To see how to create your own distribution package, check one of the existing ones and the documentation in the XSD that is available in the source of this plugin.

Environments

In the configuration part of the maven plugin, it is possible to define multiple environments. An environment is based on a framework, which is basically a link to a distribution package. If no environment is configured for the plugin, the default Equinox environment with the id 'equinox' is used.

Default configuration

In the following, most simple configuration, where no custom environment is defined:

<plugin>
    <groupId>org.everit.osgi.dev</groupId>
    <artifactId>eosgi-maven-plugin</artifactId>
    <version>4.0.0</version>
</plugin>

The configuration above is equal to the following (default configuration):

<plugin>
    <groupId>org.everit.osgi.dev</groupId>
    <artifactId>eosgi-maven-plugin</artifactId>
    <version>4.0.0</version>
    <configuration>
        <environments>
            <environment>
                <id>equinox</id>
                <framework>equinox</framework>
            </environment>
        </environments>
    </configuration>
</plugin>

Environment settings

A plugin configuration may contain multiple environment configurations. The environment can be configured deeply. Here is the list of entries that can be used inside an environment:

Name Description

id

The id of the environment. This must be unique in the pom.xml. Sub-folders are created for each environment during the run of the dist or the integration-test goals. Therefore, the id should have a value that is valid for creating a folder, so it is not a good idea to use spaces or special characters inside.

framework

The distribution package name we should work with. Based on this value the plugin will get a maven dependency. To define a framework, you can use one of the formats below:

  • Full: You can define the maven dependency with the "groupId:artifactId:version". With this format, maven will search for a dependency with the type zip.

  • Short:The plugin searches its classpath to find all of the META-INF/eosgi-framework.properties files. You can find a sample file like this in the jar file of the plugin. These properties files contain short-name=full-name entries. A typical short name is 'equinox', that is also defined in the plugin jar.

testRunningTimeout

This setting is only used when the environment is started with the integration-test goal. The plugin will wait until all of the tests run in the test environment. It may happen that due to an error the test OSGi framework never runs the tests (missing dependencies, wiring issues, etc.). In this case, the plugin kills the environment when reaching the defined timeout. The timeout should be specified in milliseconds. The default value is five minutes that is 300000 milliseconds.

frameworkStartLevel

The start-level of the OSGi framework. Optional

initialBundleStartLevel

The default start-level of the installed bundles. Optional

artifacts

It is possible to add new artifacts to the dependency list or override the settings of existing dependencies that will be used during the environment distribution. If an artifact is already in the dependency tree, another version can be added here, so there will be multiple version of the same artifacts in the environment.

<environment>
    ...
    <artifacts>
        <artifact>
            <coordinates>groupId:artifactId:version</coordinates>
        </artifact>
    </artifacts>
</environment>

Whether an artifact is an OSGi bundle or not, it is possible to specify a targetFolder and targetFile element. In case one of those elements are specified, the artifact will be copied to the target place. E.g.:

<environment>
    ...
    <artifacts>
        <artifact>
            <coordinates>groupId:artifactId:version</coordinates>
            <targetFolder>subFolder1/subFolder2</targetFolder>
            <targetFile>somefileName</targetFile>
        </artifact>
    </artifacts>
</environment>

Additional properties can be specified for the artifact that the distribution environment supports.

<environment>
    ...
    <artifacts>
        <artifact>
            <coordinates>groupId:artifactId:version</coordinates>
            <bundle.startLevel>20</bundle.startLevel>
            <bundle.action>start/install/none</bundle.action>
        </artifact>
    </artifacts>
</environment>

launchConfig

The configuration how the environment should be launched. There is a basic definition about the main class/jar in the distributed environment package normally, it is possible to specify additional VM and program arguments here.

<environment>
  ...
  <launchConfig>
    <vmArguments>
      <minHeap>-Xms20m</minHeap>
      <maxheap>-Xmx200m</maxheap>
      <someSystemProp>-Dkey=value</someSystemProp>
    </vmArguments>
    <programArguments>
      <console>-console</console>
    </programArguments>
  </launchConfig>
</environment>

It is possible to override the default launch configuration settings depending how the environment is launched:

  • IDE: The environemnt is launched by an IDE (like the EOSGi Eclipse plugin)
  • INTEGRATION_TEST: The environment is launched by the integration-test goal of eosgi-maven-plugin.
  • PARSABLES: The configuration is used when parsable files are replaced in the distribution package.

An example:

<environment>
  ...
  <launchConfig>
    <vmArguments>
      <minHeap>-Xms20m</minHeap>
      <maxheap>-Xmx200m</maxheap>
    </vmArguments>
    <overrides>
      <override>
        <useBy>PARSABLES</useBy>
        <vmArguments>
          <!-- Having the same key overrides a value in the arguments -->
          <minHeap>-Xms100m</minHeap>
          
          <!-- It is possible to add new arguments, too -->
          <debug>-agentlib:jdwp=transport=dt_socket,server=y,address=8000,suspend=n</debug>
        </vmArguments>
        <programArguments>
          <!-- Removing an argument from the defaults can be done by adding it with no value -->
          <console />
        </programArguments>
      </override>
    </overrides>
  </launchConfig>
</environment>

There are additional settings that can be defined for the goals. To see them, please check the documentation of the goal you want to run!

Running integration tests in maven compilation lifecycle

Additional dependencies of the project

To be able to run tests with the maven plugin, the started OSGi containers must contain the osgi-testrunner bundle and at least one Test Engine implementation. At the moment there is one Test Engine implementation that makes it possible to run tests with JUnit4. To have all necessary bundles within the environment, add the following dependency to the project:

<dependency>
  <groupId>org.everit.osgi.dev</groupId>
  <artifactId>org.everit.osgi.dev.testrunner.junit4</artifactId>
  <version>3.0.3</version>
</dependency>

See the documentation of the testrunner for more information!

Configuration of the maven plugin

In order to run the integration-test goal at the integration phase of maven you can use the following configuration snippet:

<plugin>
    <groupId>org.everit.osgi.dev</groupId>
    <artifactId>eosgi-maven-plugin</artifactId>
    <version>4.0.0</version>
    <executions>
        <execution>
            <id>integration-test</id>
            <phase>integration-test</phase>
            <goals>
                <goal>integration-test</goal>
            </goals>
        </execution>
    </executions>
</plugin>

The configuration of the plugin (with the environments) can go on the plugin level or on the execution level.

Incremental and live update

It is possible to run incremental updates on distributions. To carry out an update, simply run the following command:
mvn package eosgi:dist

By running the command, all extracted environments will be updated. If the target environment is running, eosgi-maven-plugin will try to update it using Java Attach API and OSGi JMX Management Model Specification. The dist or integration-test goal of eosgi-maven-plugin will fail if

  • the target environment is started more than once (multiple running processes)
  • the target environment is started once, but the OSGi JMX Management Model Specification is not available via JMX.

OSGi JMX Management Model Specification is implemented by several projects. We recommend to use the following two dependencies to be sure that the necessary JMX services will be available, add the following dependencies to your project:

<dependency>
  <groupId>org.apache.aries.jmx</groupId>
  <artifactId>org.apache.aries.jmx.core</artifactId>
  <version>1.1.6</version>
</dependency>
<dependency>
  <groupId>org.everit.osgi.jmx</groupId>
  <artifactId>org.everit.osgi.jmx.activator</artifactId>
  <version>1.0.0</version>
</dependency>

Google Analytics tracking

The eosgi-maven-plugin collects anonymous usage statistics. The collected statistics are used to convince our managers that others use the plugin and we should continue our work. Collected data are:

  • analytics referer: the eosgi-maven-plugin or other plugin. Example eclipse-e4-plugin, which is under development now.
  • executed goal: the executed goal. Available values (goals) are:
    • analyse
    • dist
    • integration-test
  • mac address hash: the hashed value of the MAC address of the first network interface controller of the user's computer. SHA-1 algorithm is used to create the hash to make the user anonymous and unique.
  • plugin version: the plugin version.

To turn off the Google Analytics tracking add the "-Deosgi.analytics.skip=true" property to the build command or set the same property in the pom file of your project.