I'm using ServiceMix 6.1.0 (containing Karaf 3.0.5) and I have a Maven project. I want to create a Karaf Archive (.kar) using karaf-maven-plugin
.
I understood the goal of using a Karaf Archive : retrieving every dependencies so that the .kar can be deployed in an offline environment. Well... I thought I had understood... After creating .kar and deploying it, I get an error :
Error executing command: Can't install feature karafMavenPlugin/0.0.0:
Could not start bundle mvn:org.testng/testng/6.8.8 in feature(s) karafMavenPlugin-0.0.1-SNAPSHOT:
Unresolved constraint in bundle org.testng [371]:
Unable to resolve 371.0:
missing requirement [371.0] osgi.wiring.package; (osgi.wiring.package=org.junit)
Here is the pom.xml
:
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>karafMavenPlugin</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>kar</packaging>
<name>TestKarafMavenPlugin</name>
<build>
<plugins>
<!-- Plugin to create .kar -->
<plugin>
<groupId>org.apache.karaf.tooling</groupId>
<artifactId>karaf-maven-plugin</artifactId>
<version>3.0.5</version>
<extensions>true</extensions>
<configuration>
<aggregateFeatures>true</aggregateFeatures>
<includeTransitiveDependency>true</includeTransitiveDependency>
</configuration>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings
only. It has no influence on the Maven build itself. -->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>
org.apache.karaf.tooling
</groupId>
<artifactId>
karaf-maven-plugin
</artifactId>
<versionRange>
[3.0.5,)
</versionRange>
<goals>
<goal>
features-generate-descriptor
</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore></ignore>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<dependencies>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.8.8</version>
</dependency>
</dependencies>
</project>
Here is the feature.xml
generated :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.1" name="karafMavenPlugin">
<feature name="karafMavenPlugin" version="0.0.1-SNAPSHOT" description="TestKarafMavenPlugin">
<bundle>mvn:org.testng/testng/6.8.8</bundle>
<bundle>wrap:mvn:org.beanshell/bsh/2.0b4</bundle>
<bundle>mvn:com.beust/jcommander/1.27</bundle>
</feature>
</features>
Why is the JUnit dependency not retrieved ?
My guess would be that karaf-maven-plugin
does not retrieve dependencies in pom.xml
which are <optional>
or <provided>
. Indeed, JUnit is a TestNG's dependency and here is the TestNG's pom.xml
(only dependencies) :
<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 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<packaging>jar</packaging>
<name>TestNG</name>
<version>6.8.8</version>
<description>TestNG is a testing framework.</description>
<url>http://testng.org</url>
<dependencies>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.7.0</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.beanshell</groupId>
<artifactId>bsh</artifactId>
<version>2.0b4</version>
<!--
<scope>provided</scope>
-->
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.beust</groupId>
<artifactId>jcommander</artifactId>
<version>1.27</version>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.12</version>
<optional>true</optional>
</dependency>
</dependencies>
</project>
We can see that every dependencies who are not <optional>
and not <provided>
are retrieved by karaf-maven-plugin
.
So... Am I wrong ? Is it an expected behavior ? If it is the case, is there a way to indicate to the karaf-maven-plugin
to download every dependencies ?
As described in the maven documentation about scope :
provided
This is much like compile, but indicates you expect the JDK or a container to provide the dependency at runtime. For example, when building a web application for the Java Enterprise Edition, you would set the dependency on the Servlet API and related Java EE APIs to scope provided because the web container provides those classes. This scope is only available on the compilation and test classpath, and is not transitive.
'provided' is not transitive : when asking for maven dependencies through api, the provided dependencies are not retrieved.
So, in order to work with karaf-maven-plugin, you have to explicitly add this dependency in the pom.