When using the features-generate-descriptor goal of the karaf-maven-plugin, including a feature dependency that has been defined with a classifier other than "features" doesn't include the this as a dependent feature within the generated feature but rather includes the entire contents of the feature file as bundles.
For example, the ActiveMQ client features are defined within dependency
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-karaf</artifactId>
<classifier>features-core</classifier>
<type>xml</type>
</dependency>
Including this dependency results in a feature file with all the bundles of the features-core injected into our generated feature
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<features xmlns="http://karaf.apache.org/xmlns/features/v1.6.0" name="features-test">
<feature name="features-test" description="features-test" version="0.0.1.SNAPSHOT">
<feature prerequisite="true" dependency="false">wrap</feature>
<bundle>mvn:com.test/test-bundle/0.0.1-SNAPSHOT</bundle>
<bundle>wrap:mvn:org.apache.activemq/activemq-karaf/5.18.3/xml/features-core</bundle>
<bundle>mvn:org.apache.geronimo.specs/geronimo-jms_2.0_spec/1.0-alpha-2</bundle>
<bundle>mvn:org.ops4j.pax.logging/pax-logging-api/2.1.3</bundle>
<bundle>mvn:org.osgi/osgi.core/7.0.0</bundle>
<bundle>mvn:org.osgi/osgi.cmpn/7.0.0</bundle>
<bundle>mvn:org.ops4j.pax.logging/pax-logging-log4j2/2.1.3</bundle>
<bundle>mvn:org.apache.aries.blueprint/org.apache.aries.blueprint.core/1.10.2</bundle>
<bundle>mvn:org.apache.aries.blueprint/org.apache.aries.blueprint.api/1.0.0</bundle>
<bundle>mvn:org.apache.aries.quiesce/org.apache.aries.quiesce.api/1.0.0</bundle>
<bundle>mvn:org.apache.aries.proxy/org.apache.aries.proxy.api/1.1.0</bundle>
<bundle>mvn:org.apache.felix/org.apache.felix.framework/5.6.12</bundle>
<bundle>mvn:org.apache.felix/org.apache.felix.bundlerepository/2.0.10</bundle>
<bundle>mvn:org.osgi/org.osgi.core/6.0.0</bundle>
<bundle>mvn:org.easymock/easymock/3.4</bundle>
<bundle>mvn:org.objenesis/objenesis/2.2</bundle>
<bundle>mvn:org.apache.karaf.shell/org.apache.karaf.shell.console/4.3.7</bundle>
<bundle>mvn:org.jline/jline/3.21.0</bundle>
<bundle>mvn:org.fusesource.jansi/jansi/2.4.0</bundle>
<bundle>mvn:org.apache.karaf.jaas/org.apache.karaf.jaas.modules/4.3.7</bundle>
<bundle>mvn:org.apache.karaf.jaas/org.apache.karaf.jaas.config/4.3.7</bundle>
<bundle>mvn:jakarta.xml.bind/jakarta.xml.bind-api/2.3.3</bundle>
<bundle>mvn:jakarta.activation/jakarta.activation-api/1.2.2</bundle>
<bundle>mvn:org.glassfish.jaxb/jaxb-runtime/2.3.3</bundle>
<bundle>wrap:mvn:org.glassfish.jaxb/txw2/2.3.3</bundle>
<bundle>mvn:com.sun.istack/istack-commons-runtime/3.0.11</bundle>
<bundle>wrap:mvn:javax.activation/activation/1.1.1</bundle>
<bundle>mvn:org.apache.karaf.jaas/org.apache.karaf.jaas.boot/4.3.7</bundle>
<bundle>mvn:org.apache.karaf.shell/org.apache.karaf.shell.core/4.3.7</bundle>
<bundle>mvn:org.apache.sshd/sshd-osgi/2.8.0</bundle>
<bundle>mvn:org.slf4j/jcl-over-slf4j/1.7.32</bundle>
<bundle>mvn:org.apache.activemq/activemq-http/5.18.3</bundle>
<bundle>wrap:mvn:org.apache.activemq/activemq-spring/5.18.3</bundle>
<bundle>wrap:mvn:org.apache.activemq/activemq-broker/5.18.3</bundle>
<bundle>wrap:mvn:org.apache.activemq/activemq-openwire-legacy/5.18.3</bundle>
<bundle>mvn:javax.annotation/javax.annotation-api/1.3.2</bundle>
<bundle>wrap:mvn:org.springframework/spring-context/5.3.30</bundle>
<bundle>wrap:mvn:org.springframework/spring-aop/5.3.30</bundle>
<bundle>wrap:mvn:org.springframework/spring-beans/5.3.30</bundle>
<bundle>wrap:mvn:org.springframework/spring-core/5.3.30</bundle>
<bundle>wrap:mvn:org.springframework/spring-jcl/5.3.30</bundle>
<bundle>wrap:mvn:org.springframework/spring-expression/5.3.30</bundle>
<bundle>wrap:mvn:org.springframework/spring-jms/5.3.30</bundle>
<bundle>wrap:mvn:org.springframework/spring-messaging/5.3.30</bundle>
<bundle>wrap:mvn:org.springframework/spring-tx/5.3.30</bundle>
<bundle>wrap:mvn:org.apache.activemq/activemq-mqtt/5.18.3</bundle>
<bundle>wrap:mvn:org.apache.activemq.protobuf/activemq-protobuf/1.1</bundle>
<bundle>mvn:org.fusesource.mqtt-client/mqtt-client/1.16</bundle>
<bundle>mvn:org.fusesource.hawtdispatch/hawtdispatch-transport/1.22</bundle>
<bundle>mvn:org.fusesource.hawtdispatch/hawtdispatch/1.22</bundle>
<bundle>mvn:org.slf4j/slf4j-api/2.0.9</bundle>
<bundle>mvn:org.eclipse.jetty/jetty-server/9.4.53.v20231009</bundle>
<bundle>mvn:javax.servlet/javax.servlet-api/3.1.0</bundle>
<bundle>mvn:org.eclipse.jetty/jetty-http/9.4.53.v20231009</bundle>
<bundle>mvn:org.eclipse.jetty/jetty-io/9.4.53.v20231009</bundle>
<bundle>mvn:org.eclipse.jetty/jetty-xml/9.4.53.v20231009</bundle>
<bundle>mvn:org.eclipse.jetty/jetty-util/9.4.53.v20231009</bundle>
<bundle>mvn:org.eclipse.jetty/jetty-webapp/9.4.53.v20231009</bundle>
<bundle>mvn:org.eclipse.jetty/jetty-servlet/9.4.53.v20231009</bundle>
<bundle>mvn:org.eclipse.jetty/jetty-security/9.4.53.v20231009</bundle>
<bundle>mvn:org.eclipse.jetty/jetty-util-ajax/9.4.53.v20231009</bundle>
<bundle>wrap:mvn:org.apache.httpcomponents/httpclient/4.5.14</bundle>
<bundle>wrap:mvn:org.apache.httpcomponents/httpcore/4.4.16</bundle>
<bundle>mvn:commons-logging/commons-logging/1.2</bundle>
<bundle>mvn:commons-codec/commons-codec/1.11</bundle>
<bundle>mvn:com.thoughtworks.xstream/xstream/1.4.20</bundle>
<bundle>mvn:io.github.x-stream/mxparser/1.2.2</bundle>
<bundle>wrap:mvn:xmlpull/xmlpull/1.1.3.1</bundle>
<bundle>mvn:org.apache.activemq/activemq-log4j-appender/5.18.3</bundle>
<bundle>mvn:org.apache.activemq/activemq-client/5.18.3</bundle>
<bundle>mvn:org.fusesource.hawtbuf/hawtbuf/1.11</bundle>
<bundle>wrap:mvn:org.apache.activemq/activemq-console/5.18.3</bundle>
<bundle>wrap:mvn:org.apache.activemq/activemq-kahadb-store/5.18.3</bundle>
<bundle>mvn:org.apache.activemq/activeio-core/3.1.4</bundle>
<bundle>mvn:org.apache.geronimo.specs/geronimo-j2ee-management_1.1_spec/1.0.1</bundle>
<bundle>mvn:org.apache.commons/commons-pool2/2.12.0</bundle>
<bundle>mvn:org.apache.xbean/xbean-spring/4.24</bundle>
<bundle>mvn:org.fusesource.hawtbuf/hawtbuf-proto/1.11</bundle>
<bundle>mvn:com.fasterxml.jackson.core/jackson-core/2.15.3</bundle>
<bundle>mvn:com.fasterxml.jackson.core/jackson-annotations/2.15.3</bundle>
<bundle>mvn:com.fasterxml.jackson.core/jackson-databind/2.15.3</bundle>
<bundle>mvn:org.apache.velocity/velocity-engine-core/2.3</bundle>
<bundle>mvn:commons-collections/commons-collections/3.2.2</bundle>
<bundle>mvn:org.apache.commons/commons-lang3/3.12.0</bundle>
<bundle>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.josql/1.5_5</bundle>
<bundle>wrap:mvn:org.jasypt/jasypt/1.9.3</bundle>
<bundle>mvn:commons-daemon/commons-daemon/1.3.4</bundle>
<bundle>mvn:org.apache.activemq/activemq-pool/5.18.3</bundle>
<bundle>mvn:org.apache.activemq/activemq-jms-pool/5.18.3</bundle>
<bundle>mvn:org.apache.geronimo.specs/geronimo-jta_1.1_spec/1.1.1</bundle>
</feature>
</features>
The expected result is
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<features xmlns="http://karaf.apache.org/xmlns/features/v1.6.0" name="features-test">
<repository>mvn:org.apache.activemq/activemq-karaf/5.18.3/xml/features</repository>
<feature name="features-test" description="features-test" version="0.0.1.SNAPSHOT">
<feature version="5.18.3" prerequisite="false" dependency="false">activemq-client</feature>
<feature version="5.18.3" prerequisite="false" dependency="false">activemq-cf</feature>
<feature version="5.18.3" prerequisite="false" dependency="false">activemq</feature>
<feature version="5.18.3" prerequisite="false" dependency="false">activemq-combined-jms-spec</feature>
<bundle>mvn:com.test/test-bundle/0.0.1-SNAPSHOT</bundle>
</feature>
</features>
The cause for this is in the org.apache.karaf.tooling.utils.Dependency31Helper.isFeature() and GenerateDescriptorMojo.processFeatureArtifact() where it is assumed the classifier for all features is "features".
Considering we can use this plugin to generated "none standard" feature classifiers with the parameter , this results in a feature we can not later include with another feature.
Below is the pom.xml that generates the improper feature.xml file above
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.test</groupId>
<artifactId>test-parent</artifactId>
<version>${revision}${changelist}</version>
</parent>
<artifactId>test-feature</artifactId>
<packaging>feature</packaging>
<properties>
<karaf.version>4.4.5</karaf.version>
<activemq.version>5.18.3</activemq.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-karaf</artifactId>
<classifier>features-core</classifier>
<type>xml</type>
<version>${activemq.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.karaf.tooling</groupId>
<artifactId>karaf-maven-plugin</artifactId>
<version>${karaf.version}</version>
<extensions>true</extensions>
<configuration>
<prerequisiteFeatures>
<prerequisiteFeature>activemq-client</prerequisiteFeature>
</prerequisiteFeatures>
</configuration>
</plugin>
</plugins>
</build>
</project>
When using the features-generate-descriptor goal of the karaf-maven-plugin, including a feature dependency that has been defined with a classifier other than "features" doesn't include the this as a dependent feature within the generated feature but rather includes the entire contents of the feature file as bundles.
For example, the ActiveMQ client features are defined within dependency
Including this dependency results in a feature file with all the bundles of the features-core injected into our generated feature
The expected result is
The cause for this is in the org.apache.karaf.tooling.utils.Dependency31Helper.isFeature() and GenerateDescriptorMojo.processFeatureArtifact() where it is assumed the classifier for all features is "features".
Considering we can use this plugin to generated "none standard" feature classifiers with the parameter , this results in a feature we can not later include with another feature.
Below is the pom.xml that generates the improper feature.xml file above