Why can't maven find an osgi bundle dependency? - maven

I have declared a OSGi bundle as a dependency in my maven project. ( It just happens to be the felix container. )
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.framework</artifactId>
<version>4.0.2</version>
<type>bundle</type>
<scope>compile</scope>
</dependency>
When I try to build, it says it can't find it.
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Failed to resolve artifact.
Missing:
----------
1) org.apache.felix:org.apache.felix.framework:bundle:4.0.2
Try downloading the file manually from the project website.
But, a quick look in central verifies that this artifact is indeed there. I noticed that if I change it to a "jar" type, it will indeed download the jar ( bundle ) for me. Which got me to thinking, why did I call it a bundle in the first place? Well, I did that because when I was using m2e to lookup the artifact, it called it a "bundle"; in fact, m2e generated those coordinates that I cite above.
Is bundle not a valid maven artifact type? If not, why does m2e call it that?

This is not a glitch in m2e as mentioned in the accepted answer. The problem is that maven doesn't know what the type "bundle" is. So you need to add a plugin that defines it, namely the maven-bundle-plugin. Notice that you also need to set the extensions property to true. So the POM should have something like
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.4.0</version>
<extensions>true</extensions>
</plugin>
The problem with the accepted answer is that it works if the dependency of type bundle is a direct dependency; since it is your pom that declares it, you can just remove the type. However, if your dependency itself has a dependency of type bundle then you are screwed because then one of your transitive dependencies is of type bundle and you cannot just remove the type in it since you are not the owner of that artifact and don't have access to the pom, which again your current execution doesn't understand. it will try to look for repo/your-dependency.bundle
I ran into this problem when using the dependency plugin to copy-dependencies. In that case, the plugin dependency has to go in the plugin itself. You just need the dependency plugin to know about the bundle plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.4.0</version>
<type>maven-plugin</type>
</dependency>
</dependencies>
<extensions>true</extensions>
</plugin>

Related

Maven Wrapper install plugins locally

I'm using Maven Wrapper for the first time and I am trying to run a command './mvnw -B openl:test' locally but I keep getting the error that no plugin found for prefix 'openl' in the current project and in the plugins groups. I looked in the .m2 directory and I do see the openl maven plugin there so I not sure why it's not working. I installed the plugin running './mvnw clean install' after added the dependency to the pom.xml file.
<dependency>
<groupId>org.openl.rules</groupId>
<artifactId>openl-maven-plugin</artifactId>
<version>5.21.9</version>
<scope>test</scope>
</dependency>
Am I missing something?
If you want to use plugins with maven you need to declare it under "plugin" section in pom.xml. In your case it would look like this:
<build>
[...]
<plugins>
[...]
<plugin>
<groupId>org.openl.rules</groupId>
<artifactId>openl-maven-plugin</artifactId>
<version>5.21.9</version>
<extensions>true</extensions>
</plugin>
</plugins>
[...]
</build>

maven versions plugin does not fetch releases with build number

I have a library with version 1.0.0-19 (19 is the Jenkins build number), on next jenkins build the version 1.0.0-20 will be assigend to the library and the artifact will be deployed to a maven repository. Another artifact which is referencing the library in the pom dependency section does not get the last version if I execute versions:use-latest-versions, the dependency version is still 1.0.0-19 instead of 1.0.0-20. Maybe it has to do with the allow* system parameters, there is no property for the build number part.
Any ideas how it could be achieved to get always the last build (1.0.0-19 -> 1.0.0-20)?
Within your pom make sure you are using -
<dependencies>
<dependency>
<groupId>some.artifactory.group</groupId>
<artifactId>artifact-name</artifactId>
<version>1.0.0-19</version>
</dependency>
</dependencies>
<!-- please use the appropriate artifact and groupId -->
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>2.3</version>
</plugin>
</plugins>
</build>
and you are executing the command -
mvn versions:use-latest-releases
Source - http://www.mojohaus.org/versions-maven-plugin/use-latest-releases-mojo.html
Note - Just in case this also involves SNAPSHOTS, do take care of allowSnapshots and use the command as -
mvn versions:use-latest-releases -DallowSnapshots=true

Tycho cannot resolve dependency configured in tycho-surefire-plugin

I'm working on an Eclipse RCP + Maven project for the first time and I want to run some unit tests on my bundles with JUnit. It seems that the most recommended approach is to create a bundle fragment and use something like Tycho plugin to resolve dependencies. However, when I run mvn clean verify in my master pom, it should run the tests and deploy my application, but I'm get the following error instead:
[ERROR] Cannot resolve project dependencies:
[ERROR] You requested to install 'myproject.app.feature.feature.group 1.0.0' but it could not be found
[ERROR] Failed to execute goal org.eclipse.tycho:tycho-surefire-plugin:0.21.0:test (default-test) on project myproject.app.viewmanager-test: Execution default-test of goal org.eclipse.tycho:tycho-surefire-plugin:0.21.0:test failed: No solution found because the problem is unsatisfiable.: [Unable to satisfy dependency from tycho-extra-1408913392535 0.0.0.1408913392535 to myproject.app.feature.feature.group 1.0.0.; Unable to satisfy dependency from tycho-1408913392552 0.0.0.1408913392552 to myproject.app.feature.feature.group 1.0.0.; No solution found because the problem is unsatisfiable.] -> [Help 1]
I understand that Maven is failing to find 'myproject.app.feature.feature.group 1.0.0' but I don't know where it is getting this from because it seems that the name is wrong.
It might be worth to say that when I run the unit test inside Eclipse (not with Maven) it works.
This is the Tycho configuration in my test fragment:
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-surefire-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<useUIHarness>true</useUIHarness>
<dependencies>
<dependency>
<type>eclipse-feature</type>
<artifactId>myproject.app.feature</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
</configuration>
</plugin>
As suggested here, I'm adding the feature as a dependency because my test fragment requires some other bundles besides its host, so I was expecting this to work.
Any tips? The most similar issue I have found is this one, but both solutions didn't work for me.
Starting with Tycho 0.21.0, there is only limited support for declaring dependencies to reactor projects in the tycho-surefire-plugin: They only work if the test project already has some other dependency to the referenced reactor project. In your use case, where you add a dependency to a feature, this is not the case.
You could make the tycho-surefire-plugin dependencies configuration work again by adding a POM dependency to the feature project:
<dependencies>
<dependency>
<!-- Maven GAV of the feature project -->
<groupId>myproject.groupId</groupId>
<artifactId>myproject.app.feature</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-surefire-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<dependencies>
<dependency>
<type>eclipse-feature</type>
<artifactId>myproject.app.feature</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
</configuration>
</plugin>
</plugins>
</build>
However the recommended way to specify extra test dependencies is to do this in the target-platform-configuration instead of on the tycho-surefire-plugin:
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>target-platform-configuration</artifactId>
<configuration>
<dependency-resolution>
<extraRequirements>
<requirement>
<type>eclipse-feature</type>
<id>myproject.app.feature</id>
<versionRange>1.0.0</versionRange>
</requirement>
</extraRequirements>
</dependency-resolution>
</configuration>
</plugin>
Note: The element names to specify dependencies are different in the target-platform-configuration compared to the tycho-surefire-plugin. So when migrating your configuration, you need to adapt the tag names:
<type> (unchanged)
<artifactId> → <id>
<version> → <versionRange>
Remark: Although the tag names are different, the semantics of the elements are the same: So even though the old name was <version>, the value was always interpreted as a version range. A version range that consists of a single version like 1.0.0 stands for for a version range without upper bound, i.e. version 1.0.0 or later.
I just had essentially the same problem. It seems that with tycho 0.21 dependencies have to be added using the target-platform-configuration plugin. See tycho bug 436617 comment #11 for an example.

dependencies Needed by a mvn plugin are not resolved

I have created a Maven plugin called foo that needs a JAR file say xyz.jar in order to compile and run. In the pom file of plugin project foo I have provided xyz.jar with provided scope in the dependencies section. I do not want to package the xyz.jar file in the plugin.
The plugin foo will be triggered by another project say bar in its install phase. So I added the plugin foo in the <build><plugins><plugin>...</plugin></plugins></build> section of the project bar. Project bar has the dependency of xyz.jar in its <dependencies> section. When I run install goal the classes present in the xyz.jar and which are referred by the plugin foo throw ClassNotFoundException at runtime.
How can I resolve this?
Every plugin and the Maven Project have separated classloaders, that's why it is not working. In general a plugin shouldn't depend on a dependency of the project. So remove the provided scope will solve it. Manipulating the classloader is very tricky.
I do not want to package the xyz.jar file in the plugin.
Well, it is not. It is just a reference.
I can't tell what your plugin is doing. I suggest to have a look at the plugins from Apache Maven or Codehaus Mojo to see how it is done.
Project and plugin dependencies are separated in Maven. If your plugin requires some external jars you need to provide them in <dependencies> section located in the plugin tag (not together with your project dependencies). For example:
<build>
<plugins>
<plugin>
<groupId>...</groupId>
<artifactId>yourPluginArtifactId</artifactId>
<version>...</version>
<dependencies>
<dependency>
<groupId>...</groupId>
<artifactId>xyz</artifactId>
<version>...</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>

Maven WAR dependency

I am writing a project for acceptance testing and for various reasons this is dependent on another project which is packaged as a WAR. I have managed to unpack the WAR using the maven-dependency-plugin, but I cannot get my project to include the unpacked WEB-INF/lib/*.jar and WEB-INF/classes/* to be included on the classpath so the build fails. Is there a way to include these files into the classpath, or is there a better way of depending on a WAR?
Many thanks.
There's another option since maven-war-plugin 2.1-alpha-2. In your WAR project:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<attachClasses>true</attachClasses>
</configuration>
</plugin>
This creates a classes artifact which you can use in the acceptance tests project with:
<dependency>
<groupId>your-group-id</groupId>
<artifactId>your-artifact-id</artifactId>
<version>your-version</version>
<classifier>classes</classifier>
</dependency>
Indeed, by design, Maven doesn't resolve transitive dependencies of a war declared as dependency of a project. There is actually an issue about that, MNG-1991, but it won't be solved in Maven 2.x and I'm not sure that I don't know if overlays allow to workaround this issue. My understanding of the suggested solution is to duplicate the dependencies, for example in a project of type pom.
(EDIT: After some more digging, I found something interesting in this thread that I'm quoting below:
I have been helping out with the development of the AppFuse project over
the last month where we make heavy use of the war overlay feature in the
Maven war plugin. It is a really nifty feature!
To get max power with war overlays I have developed the Warpath plugin
that allows projects to use war artifacts as fully fledged dependencies.
In brief:
1) The contents of the /WEB-INF/classes directory in the war dependency
artifacts can be included in the project's classpath for normal compile,
etc tasks.
2) Transitive dependencies from the war dependency artifacts become
available for use by other plugins, e.g. compile and ear - so no more
having to include all the dependencies when creating skinny wars!
The plugin has now been actively used in the AppFuse project for the
last few months, and I feel it is at a point where it is both usable and
stable.
Would the war plugin team be interested in including the warpath
functionality inside the war plugin? It would seem to be the most
natural place to host it.
So, I don't have any experience with it, but the maven warpath plugin actually looks nice and simple and is available in the central repo. To use it,include the following plugin configuration element in your pom.xml file:
[...]
<build>
<plugins>
<plugin>
<groupId>org.appfuse</groupId>
<artifactId>maven-warpath-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<extensions>true</extensions>
<executions>
<execution>
<goals>
<goal>add-classes</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
And add the war dependencies you want included in the classpath as warpath type dependencies:
[...]
<dependencies>
<dependency>
<groupId>org.appfuse</groupId>
<artifactId>appfuse-web</artifactId>
<version>2.0</version>
<type>war</type>
</dependency>
<dependency>
<groupId>org.appfuse</groupId>
<artifactId>appfuse-web</artifactId>
<version>2.0</version>
<type>warpath</type>
</dependency>
</dependencies>
[...]
Both the war and warpath dependency types are needed: the war type is used by the Maven war plugin to do the war overlay, the warpath type is used by the Warpath plugin to determine the correct list of artifacts for inclusion in the project classpath.
I'd give it a try.)
Use overlays. First, your test project need to have also packaging war.
Declare dependency of war project you want to test:
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>your-project-arftifactId</artifactId>
<version>${project.version}</version>
<type>war</type>
<scope>test</scope>
</dependency>
then configure maven-war-plugin overlay:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webResources>
<resource>
<directory>${basedir}/src/main/webresources</directory>
<filtering>true</filtering>
</resource>
</webResources>
<overlays>
<overlay/>
<overlay>
<groupId>your.group</groupId>
<artifactId>your-project-artifactId</artifactId>
</overlay>
</overlays>
</configuration>
</plugin>
In the above example in test project I overwrite webresources configuration files (like conxtext etc.).
EDIT: This solution wasn't tested with Maven 3.
Good point, Justin. That got me actually solving my problem, namely: including a war into an assembly AND including all its transitive dependencies.
I could not duplicate the war-dependency as 'jar' as you suggested since the assembly plugin would not find a jar referenced by that groupId/artefactId, but
duplicating the war-dependency as type pom
works!
The war and its transitive dependencies are not included in the assembly.
To exclude the (now also appearing) pom file I had to add an exclude element like this:
<excludes>
<exclude>*:pom</exclude>
</excludes>
into my assembly.xml file.
I think this could also be a workaround for the original question of this thread.
If you list the dependency on the war project as a jar dependency it seems to pickup the required jars/resources. I'm using Maven 2.2 + m2eclipse.

Resources