Eclipse Kura™ Add-on Archetype

July 30, 2026 · View on GitHub

A Maven archetype that bootstraps an Eclipse Kura™ add-on project. A generated project comes with:

  • a Maven + bnd build targeting Java 21 and OSGi;
  • an example bundle with Declarative Services and Metatype annotations (ExampleComponent, its OCD and its configuration options);
  • a bill of materials (-bom) listing the bundles you release;
  • unit tests (JUnit 4 + Mockito) and OSGi integration tests run by bnd against an embedded Kura framework;
  • Debian packaging producing an installable .deb for your add-on.

The archetype version matches the Kura version it targets: use 6.0.0-SNAPSHOT (or 6.0.0 once released) to generate an add-on for Kura 6. The generated templates are Kura-6-specific — the Debian control file declares Depends: kura-core (>= 6.0.0~), kura-core (<< 7.0.0~).

Full documentation, including IDE setup: https://eclipse-kura.github.io/kura/docs-develop/java-application-development/kura-addon-archetype/

Prerequisites

JDK 21Required. The generated project sets maven.compiler.release=21; older JDKs fail with release version 21 not supported.
Maven 3.9.xThe version used by CI is 3.9.9.
gitRequired to build a generated project: git-commit-id-maven-plugin runs in the initialize phase to stamp the Debian package version.

Installing the archetype

The archetype is not published to a public repository yet, so build and install it locally:

git clone https://github.com/eclipse-kura/kura-archetype.git
cd kura-archetype
mvn clean install

This installs org.eclipse.kura:kura-addon-archetype into ~/.m2 and registers it in ~/.m2/repository/archetype-catalog.xml, which is why the commands below pass -DarchetypeCatalog=local. Once the artifact is published to https://repo.eclipse.org/content/repositories/kura-snapshots/, declare that repository in your ~/.m2/settings.xml and drop the -DarchetypeCatalog=local flag.

Generating a project

Interactively — Maven prompts for every property:

mvn archetype:generate \
  -DarchetypeCatalog=local \
  -DarchetypeGroupId=org.eclipse.kura \
  -DarchetypeArtifactId=kura-addon-archetype \
  -DarchetypeVersion=6.0.0-SNAPSHOT

Or in one shot:

mvn -B archetype:generate \
  -DarchetypeCatalog=local \
  -DarchetypeGroupId=org.eclipse.kura \
  -DarchetypeArtifactId=kura-addon-archetype \
  -DarchetypeVersion=6.0.0-SNAPSHOT \
  -DgroupId=com.example \
  -DartifactId=kura-myfeature \
  -Dpackage=com.example.myfeature \
  -Dversion=1.0.0-SNAPSHOT \
  -DmainBundleVendor="My Company" \
  -DkuraVersion=6.0.0-SNAPSHOT \
  -Dyear=2026
PropertyMeaningDefault
groupIdMaven groupId of every generated moduleprompted
artifactIdRoot project artifactId and top-level directory nameprompted
packageBase Java package and the main bundle's artifactId / OSGi symbolic nameprompted
versionVersion of the generated project1.0.0-SNAPSHOT
mainBundleVendorVendor name for the add-on 1Eclipse Kura
kuraVersionKura version whose BOMs resolve the dependenciesthe archetype's own version
yearCopyright year written into the generated file headersthe year the archetype was built 2

1 Declared by the archetype but not referenced by any template file at the moment; set it anyway, it is the intended place for the bundle vendor. 2 Baked in when the archetype jar is built, so pass -Dyear= explicitly if you want the current year.

There is one more property, archetypeVersion, which you never have to set: it defaults to the version of the archetype being used and is recorded as a comment in the generated root pom.xml, so a project always states what generated it:

<!-- Generated by org.eclipse.kura:kura-addon-archetype:6.0.0-SNAPSHOT -->

Two rules to respect:

  • artifactId must differ from package — the root project and the main bundle are separate Maven modules.
  • Recommended naming for contributions to the Kura ecosystem: groupId=org.eclipse.kura, artifactId=kura-<feature>, package=org.eclipse.kura.<feature>.

Generated project layout

With the values used above:

kura-myfeature
├── pom.xml                             aggregator: bnd 7.2.2, Java 21, imports the
│                                       org.eclipse.kura:kura and :target-platform BOMs
├── bom/pom.xml                         kura-myfeature-bom — the bundles you release
├── com.example.myfeature/              the OSGi bundle
│   ├── pom.xml                         built by bnd-maven-plugin
│   ├── about.html, about_files/        licence files shipped inside the bundle
│   └── src/main/java/com/example/myfeature/
│       ├── ExampleComponent.java       @Component with lifecycle and config update
│       ├── ExampleComponentOCD.java    @ObjectClassDefinition (metatype)
│       ├── ExampleComponentOptions.java
│       ├── ExampleDependencyService.java, ExampleDependencyServiceComponent.java
│       └── Property.java
├── distrib/                            kura-myfeature-distrib — Debian packaging
│   ├── pom.xml                         jdeb, bound to the package phase
│   └── deb/control/control             package metadata and kura-core dependency
└── tests/                              kura-myfeature-tests
    ├── pom.xml                         JUnit, Mockito, Moquette, Kura PDE deps
    ├── test-env/                       Kura framework used by the integration tests
    │   ├── framework/kura.properties, log4j/log4j.xml, user/snapshots/snapshot_0.xml
    └── com.example.myfeature.test/
        ├── integration-test.bndrun     OSGi runtime for the integration tests
        └── src/main/java/.../ExampleComponentItTest.java   (OSGi integration test)
            src/test/java/.../ExampleComponentTest.java     (unit test)

Only the BOM and the bundle are deployed: maven-deploy-plugin is skipped in the aggregator and in distrib, and re-enabled in the bundle module.

Building a generated project

cd kura-myfeature
git init && git add -A && git commit -m "initial commit"
mvn clean install -Presolve-integration-tests

Both extra steps are required on the first build:

  • git initgit-commit-id-maven-plugin needs a repository to read the commit hash that goes into the snapshot Debian version;
  • -Presolve-integration-tests — the generated integration-test.bndrun ships -runbundles: ${error;Integration test bundles must be resolved…}. The profile moves the bnd-resolver-maven-plugin:resolve execution from phase none to pre-integration-test, computing the actual -runbundles list. Re-run it whenever you change -runrequires or the bundle's imports, and commit the resolved .bndrun.

Afterwards a plain mvn clean install is enough.

Running the tests

Both test kinds run as part of mvn verify / mvn install:

  • Unit testsmaven-surefire-plugin, from src/test/java in tests/<package>.test.
  • OSGi integration testsbnd-testing-maven-plugin in the integration-test phase. Test classes live in src/main/java (they are part of the test bundle) and are selected by Test-Cases: ${classes;CONCRETE;PUBLIC;NAMED;*Test} in the .bndrun. The framework is assembled from tests/test-env/ into tests/<package>.test/target/test-env before the run.

Reports land in tests/<package>.test/target/surefire-reports/ (unit) and .../surefire-reports/integration-test/ (OSGi). JaCoCo writes an aggregate report to tests/<package>.test/target/site/jacoco-aggregate/.

Building the Debian package

jdeb is bound to the package phase, so any mvn package/install produces

distrib/target/deb/<package.name>_<version>-<revision>_<arch>.deb

Two version schemes:

BuildVersionCommand
development (default)1.0.0~git202607290932.c607da2-1mvn clean install
release1.0.0-1mvn clean install -DreleaseBuild

-DreleaseBuild also activates maven-enforcer-plugin's requireReleaseVersion, which fails the build if the project version is still a -SNAPSHOT.

Install it on a device with apt install ./<file>.deb, then restart Kura.

What to customise after generating

  • distrib/pom.xmlkura.repo.distribution and kura.repo.module (both CHANGEME), deb.architecture (all, amd64, arm64), package.name, package.revision, summary, long.description, addon.installation.dir (defaults to /opt/eclipse/kura/plugins). Bundles are copied into plugins/6s, i.e. OSGi start level 6, started automatically; duplicate the copy-deps execution and the jdeb <data> entry to use other start levels.
  • distrib/deb/control/control — package metadata and the kura-core version bounds.
  • bom/pom.xml — list every bundle you want to release.
  • tests/<package>.test/integration-test.bndrun-runrequires for the bundles your integration tests need.

Working on the archetype itself

src/main/resources/archetype-resources/ is a template tree, so mind which layer resolves each placeholder:

  • ${groupId}, ${artifactId}, ${package}, ${version}, ${kuraVersion}, ${year} are substituted at generation time by the archetype plugin;
  • [[...]] in distrib/deb/control/control is resolved by jdeb, when the generated project is built;
  • META-INF/maven/archetype-metadata.xml and archetype-resources/tests/test-env/framework/kura.properties are the only files filtered by Maven at archetype build time — that is where ${project.version} becomes the targeted Kura version;
  • keystores (**/*.ks) and integration-test.bndrun are deliberately excluded from filtering so they are not corrupted.

After mvn clean install, generate a throw-away project with -DarchetypeCatalog=local and build it to validate any change.

Contributing

See the Kura contribution guide. Pull request titles must follow the Conventional Commits format, and signing the Eclipse Contributor Agreement is required.