mavenkarafdeclarative-serviceskaraf-maven-plugin

Using declarative services in Karaf 4.1.0


I'm trying to develop a Karaf 4.1.0 application using NetBeans 8.2, Maven 3.3.9 and declarative services. Really simple services work, but as soon as I try to do something vaguely useful I get the dreaded osgi.component missing requirement error.

The following illustrates the sort of problem I'm having:

package net.winnall.enocean.bridge.sass.impl;

import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.winnall.enocean.bridge.sass.SASS;
import org.osgi.service.http.HttpService;

@Component(
        service = SASS.class
)
public class SASSImpl implements SASS {

    @Reference
    HttpService httpService;

    @Activate
    protected void activate() {
    }

    @Deactivate
    }
}

If I comment out the @Reference the component is loaded into the generated Karaf assembly without any problems. But as the component stands here (WITH the @Reference) I get the following error:

Failed to execute goal org.apache.karaf.tooling:karaf-maven-plugin:4.1.0:assembly (default-assembly) on project EnOceanBridgeAdmin: Unable to build assembly: Unable to resolve root: missing requirement [root] osgi.identity; osgi.identity=EnOceanBridgeSASSFeature; type=karaf.feature; version=0.99.99; filter:="(&(osgi.identity=EnOceanBridgeSASSFeature)(type=karaf.feature)(version>=0.99.99))" [caused by: Unable to resolve EnOceanBridgeSASSFeature/0.99.99: missing requirement [EnOceanBridgeSASSFeature/0.99.99] osgi.identity; osgi.identity=EnOceanBridgeSASS.Impl; type=osgi.bundle; version="[0.99.99,0.99.99]"; resolution:=mandatory [caused by: Unable to resolve EnOceanBridgeSASS.Impl/0.99.99: missing requirement [EnOceanBridgeSASS.Impl/0.99.99] osgi.extender; filter:="(&(osgi.extender=osgi.component)(version>=1.3.0)(!(version>=2.0.0)))"]] -> [Help 1]

This question suggests installing scr:

feature:install scr

so I tried adding <feature>scr</feature to karat-maven-plugin's <bootFeatures>, but it makes no difference.

The following is an extract from the effective POM for this component:

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.apache.felix</groupId>
        <artifactId>org.apache.felix.configadmin</artifactId>
        <version>1.8.14</version>
      </dependency>

      <dependency>
        <groupId>org.apache.felix</groupId>
        <artifactId>org.apache.felix.scr.ds-annotations</artifactId>
        <version>1.2.8</version>
      </dependency>

      <dependency>
        <groupId>org.ops4j.pax.logging</groupId>
        <artifactId>pax-logging-service</artifactId>
        <version>1.9.1</version>
      </dependency>

      <dependency>
        <groupId>org.ops4j.pax.logging</groupId>
        <artifactId>pax-logging-api</artifactId>
        <version>1.9.1</version>
      </dependency>

      <dependency>
        <groupId>org.ops4j.pax.logging</groupId>
        <artifactId>pax-logging-log4j2</artifactId>
        <version>1.9.1</version>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <dependencies>
    <dependency>
      <groupId>org.apache.karaf.features</groupId>
      <artifactId>framework</artifactId>
      <version>4.1.0</version>
      <type>kar</type>
      <scope>compile</scope>
    </dependency>

    <dependency>
      <groupId>org.apache.karaf.features</groupId>
      <artifactId>standard</artifactId>
      <version>4.1.0</version>
      <type>xml</type>
      <classifier>features</classifier>
      <scope>runtime</scope>
    </dependency>
  </dependencies>

  <build>
    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>org.apache.karaf.tooling</groupId>
          <artifactId>karaf-maven-plugin</artifactId>
          <version>4.1.0</version>
          <extensions>true</extensions>
        </plugin>
      </plugins>
    </pluginManagement>

    <plugins>
      <plugin>
        <groupId>org.apache.karaf.tooling</groupId>
        <artifactId>karaf-maven-plugin</artifactId>
        <version>4.1.0</version>
        <extensions>true</extensions>
        <configuration>
          <installedFeatures></installedFeatures>
          <startupFeatures></startupFeatures>
          <bootFeatures>
            <feature>minimal</feature>
            <feature>scr</feature>
          </bootFeatures>
          <javase>1.8</javase>
        </configuration>
      </plugin>

The feature I use to make it known to the Karaf assembly is:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<features xmlns="http://karaf.apache.org/xmlns/features/v1.4.0" name="EnOceanBridgeSASS.Impl">
    <feature name="EnOceanBridgeSASS.Impl" description="EnOceanBridge SASS Impl" version="0.99.99">
        <details>Karaf :: Declarative Services :: Service :: EnOceanBridge SASS Implementation</details>
        <bundle start-level="80">mvn:net.winnall.enocean.service.api/EnOceanBridgeSASS.API/0.99.99</bundle>
        <bundle start-level="80">mvn:org.apache.felix/org.apache.felix.configadmin/1.8.14</bundle>
        <bundle start-level="80">mvn:org.ops4j.pax.logging/pax-logging-api/1.9.1</bundle>
        <bundle start-level="80">mvn:org.ops4j.pax.logging/pax-logging-service/1.9.1</bundle>
    </feature>
</features>

And the Karaf assembly's effective POM contains this:

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.apache.felix</groupId>
        <artifactId>org.apache.felix.configadmin</artifactId>
        <version>1.8.14</version>
      </dependency>

      <dependency>
        <groupId>org.apache.felix</groupId>
        <artifactId>org.apache.felix.scr.ds-annotations</artifactId>
        <version>1.2.8</version>
      </dependency>

      <dependency>
        <groupId>org.ops4j.pax.logging</groupId>
        <artifactId>pax-logging-service</artifactId>
        <version>1.9.1</version>
      </dependency>

      <dependency>
        <groupId>org.ops4j.pax.logging</groupId>
        <artifactId>pax-logging-api</artifactId>
        <version>1.9.1</version>
      </dependency>

      <dependency>
        <groupId>org.ops4j.pax.logging</groupId>
        <artifactId>pax-logging-log4j2</artifactId>
        <version>1.9.1</version>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <dependencies>
    <dependency>
      <groupId>net.winnall.enocean.feature</groupId>
      <artifactId>EnOceanBridgeSettingsFeature</artifactId>
      <version>0.99.99</version>
      <type>xml</type>
      <classifier>features</classifier>
      <scope>compile</scope>
    </dependency>

    <dependency>
      <groupId>net.winnall.enocean.feature</groupId>
      <artifactId>EnOceanBridgeSASSFeature</artifactId>
      <version>0.99.99</version>
      <type>xml</type>
      <classifier>features</classifier>
      <scope>compile</scope>
    </dependency>

    <dependency>
      <groupId>net.winnall.enocean.feature</groupId>
      <artifactId>EnOceanBridgePersistenceFeature</artifactId>
      <version>0.99.99</version>
      <type>xml</type>
      <classifier>features</classifier>
      <scope>compile</scope>
    </dependency>

    <dependency>
      <groupId>org.apache.karaf.features</groupId>
      <artifactId>framework</artifactId>
      <version>4.1.0</version>
      <type>kar</type>
      <scope>compile</scope>
    </dependency>

    <dependency>
      <groupId>org.apache.karaf.features</groupId>
      <artifactId>standard</artifactId>
      <version>4.1.0</version>
      <type>xml</type>
      <classifier>features</classifier>
      <scope>runtime</scope>
    </dependency>
  </dependencies>

  <build>
    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>org.apache.karaf.tooling</groupId>
          <artifactId>karaf-maven-plugin</artifactId>
          <version>4.1.0</version>
          <extensions>true</extensions>
        </plugin>

        <plugin>
          <artifactId>maven-archetype-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>

        <plugin>
          <groupId>com.github.ferstl</groupId>
          <artifactId>depgraph-maven-plugin</artifactId>
          <version>2.1.0</version>
        </plugin>

        <plugin>
          <groupId>org.codehaus.mojo</groupId>
          <artifactId>exec-maven-plugin</artifactId>
          <version>1.6.0</version>
        </plugin>

        <plugin>
          <groupId>org.codehaus.mojo</groupId>
          <artifactId>license-maven-plugin</artifactId>
          <version>1.12</version>
        </plugin>

        <plugin>
          <artifactId>maven-antrun-plugin</artifactId>
          <version>1.8</version>
        </plugin>

        <plugin>
          <artifactId>maven-assembly-plugin</artifactId>
          <version>2.2-beta-5</version>
        </plugin>

        <plugin>
          <artifactId>maven-dependency-plugin</artifactId>
          <version>2.1</version>
        </plugin>

        <plugin>
          <artifactId>maven-release-plugin</artifactId>
          <version>2.0</version>
        </plugin>

        <plugin>
          <groupId>org.apache.felix</groupId>
          <artifactId>maven-bundle-plugin</artifactId>
          <version>3.3.0</version>
        </plugin>

        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
      </plugins>
    </pluginManagement>

    <plugins>
      <plugin>
        <groupId>com.github.ferstl</groupId>
        <artifactId>depgraph-maven-plugin</artifactId>
        <version>2.1.0</version>
      </plugin>

      <plugin>
        <artifactId>maven-resources-plugin</artifactId>
        <version>3.0.2</version>
        <executions>
          <execution>
            <id>default-resources</id>
            <phase>process-resources</phase>
            <goals>
              <goal>resources</goal>
            </goals>
          </execution>
          <execution>
            <id>process-resources</id>
            <goals>
              <goal>resources</goal>
            </goals>
          </execution>
        </executions>
      </plugin>

      <plugin>
        <groupId>org.apache.karaf.tooling</groupId>
        <artifactId>karaf-maven-plugin</artifactId>
        <version>4.1.0</version>
        <extensions>true</extensions>
        <executions>
          <execution>
            <id>default-archive</id>
            <phase>package</phase>
            <goals>
              <goal>archive</goal>
            </goals>
            <configuration>
              <installedFeatures></installedFeatures>
              <startupFeatures></startupFeatures>
              <bootFeatures>
                <feature>minimal</feature>
                <feature>scr</feature>
              </bootFeatures>
              <javase>1.8</javase>
            </configuration>
          </execution>

          <execution>
            <id>default-assembly</id>
            <phase>process-resources</phase>
            <goals>
              <goal>assembly</goal>
            </goals>
            <configuration>
              <installedFeatures></installedFeatures>
              <startupFeatures></startupFeatures>
              <bootFeatures>
                <feature>minimal</feature>
                <feature>scr</feature>
              </bootFeatures>
              <javase>1.8</javase>
            </configuration>
          </execution>
        </executions>

        <configuration>
          <installedFeatures></installedFeatures>
          <startupFeatures></startupFeatures>
          <bootFeatures>
            <feature>standard</feature>
            <feature>scr</feature>
          </bootFeatures>
          <javase>1.8</javase>
        </configuration>
      </plugin>

I've spent all weekend googling this problem: it seems to me that there is hardly any current documentation in the Internet on using declarative services in Karaf.

Can anyone give me some tips about how to resolve my problem?

Steve


Solution

  • I've finally got rid of the error, though – to be honest – I'm not sure what I did to fix it. The final edit that made the thing work was to remove something from the feature file listed above that wasn't in there at all when I reported the initial problem (it was a <repository /> and a <feature /> reference that I had added in a vain attempt to force the installation of HttpService...).

    My current view of a better possible world (i.e. where I don't lose 4 days on problems like this) includes:

    1. OSGi error messages that help the programmer to isolate errors;
    2. A way of telling Google that I am really only interested in the latest incarnation of declarative services (i.e. annotation-based and not raw BND or XML files);
    3. More clean annotation-based DS documentation without illustrations on how to do it in Eclipse, because I don't use Eclipse and don't want to;
    4. More simple documentation on how to use DS in Karaf;
    5. A Karaf IDE (is that what Karaf Boot is?).

    I think Karaf and DS are both cool ways of working. I wish it were easier.