Maven dependency plugin - How can I ensure that an artifact is present when using dependency-unpack - maven

I'm wondering if there is a way to enforce the existence of a dependency to unpack when using the dependency-unpack goal of the maven dependency plugin. I'm using the configuration below and the problem is that if there is no dependency specified for "${properties.artifactId}" in the dependencies section of the pom the build goes ahead even though nothing has been unpacked. It invariably fails later at the test stage but it would be so much easier if the build could fail when no dependency is present. So does anyone know of a way that this can be enforced?
Thanks
Piers
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-properties</id>
<phase>generate-resources</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<includeArtifactIds>${properties.artifactId}</includeArtifactIds>
<outputDirectory>${project.build.directory}</outputDirectory>
<includes>${properties.file.name}</includes>
</configuration>
</execution>
</executions>
</plugin>

A couple of executions of the maven-enforcer-plugin should do it. You need one to run before the dependency plugin, to make sure ${properties.artifactId} has a value, then another that runs after the dependency plugin to make sure there are files in the target location. Here's the idea, modify for your requirements.
You may write your own rules too if those available don't quite fit.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>fillInTheVersion</version>
<executions>
<execution>
<id>enforce-config-properties</id>
<phase>validate</phase>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireProperty>
<property>properties.artifactId</property>
<message><![CDATA[### Missing property 'properties.artifactId': the artifact that ....]]></message>
</requireProperty>
</rules>
</configuration>
</execution>
<execution>
<id>enforce-files-exist</id>
<phase>process-resources</phase>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireFilesExist>
<files>
<file>${project.build.directory}/${properties.artifactId}</file>
</files>
<message><![CDATA[### Did not find unpacked artifact ...]]></message>
</requireFilesExist>
</rules>
</configuration>
</execution>
</executions>
</plugin>

Related

Source feature generated by Tycho is not being included in p2 repository

I'm trying to create and include a source feature of my plugins in the generated p2 repository. Currently, the source jars for each plugin get created, as does the source feature to each normal feature. However, those source features then don't get included in the final product, an eclipse update site.
In my parent POM, I have
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-source-plugin</artifactId>
<executions>
<execution>
<id>plugin-source</id>
<goals>
<goal>plugin-source</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.eclipse.tycho.extras</groupId>
<artifactId>tycho-source-feature-plugin</artifactId>
<version>${tycho.version}</version>
<executions>
<execution>
<id>source-feature</id>
<phase>package</phase>
<goals>
<goal>source-feature</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-p2-plugin</artifactId>
<version>${tycho.version}</version>
<executions>
<execution>
<id>attach-p2-metadata</id>
<phase>package</phase>
<goals>
<goal>p2-metadata</goal>
</goals>
</execution>
</executions>
</plugin>
Do I need to add something to the POM of the feature? Of the eclipse-repository? I'm out of ideas.
Gonna answer this myself. I found a solution thanks to this article.
I had to add the generated source feature to the category.xml that describes my update site.
I had tried that before but it didn't work because I made the mistake of writing *.source.feature instead of *.feature.source.

using maven dependency (:copy) plug in not working

I can't seem to figure this out.
I have the following in my pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteReleases>true</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
I plan to have all the dependencies copied to target/lib directory.
Why is not doing it?
My project is evolving, so I do not want specify each individual artifact to copy. I want it to take them all, and place it into a proper place during the "package" (or compile) phase.
I get only my mainProject.jar file in the lib folder.
Please, help. What am I missing?
The correct goal for copying dependencies is copy-dependencies, not compile. Also, if you want to invoke the plugin from the command line with mvn dependency:copy, the configuration section should not be inside the executions. Here is a configuration that should work in all cases:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
</execution>
</executions>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteReleases>true</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</plugin>
As you can see, I'm running the plugin in the 'package' phase, but it also works in the 'compile' phase, unless you want to include the artifact just built by your own project.

Is there a way in maven to assure that a property is set

I just tracked down a difficult maven issue that was caused by a bad property value.
The property is a path to an alternate JVM that is used a run-time by a test.
I would like to make maven fail early by detecting if the path is valid or not.
What might be a way to accomplish this?
I plan to dig into antrun to see if there is a way to make it run first so that it can check, but that seems like overkill.
Question: How can I do this cleanly and simply?
You can use the Enforcer Maven Plugin and its Require Property rule, where you can enforce the existence of a certain property, optionally with a certain value (a matching regex), and fail the build otherwise.
This rule can enforce that a declared property is set and optionally evaluate it against a regular expression.
A simple snippet would be:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4.1</version>
<executions>
<execution>
<id>enforce-property</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireProperty>
<property>basedir</property>
<message>You must set a basedir property!</message>
<regex>.*\d.*</regex>
<regexMessage>The basedir property must contain at least one digit.</regexMessage>
</requireProperty>
</rules>
<fail>true</fail>
</configuration>
</execution>
</executions>
</plugin>
Yes, you can use the maven-enforcer-plugin for this task. This plugin is used to enforce rules during the build and it has a built-in requireFilesExist rule:
This rule checks that the specified list of files exist.
The following configuration will enforce that the file ${project.build.outputDirectory}/foo.txt exists and will fail the build if it does not.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4.1</version>
<executions>
<execution>
<id>enforce-files-exist</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireFilesExist>
<files>
<file>${project.build.outputDirectory}/foo.txt</file>
</files>
</requireFilesExist>
</rules>
<fail>true</fail>
</configuration>
</execution>
</executions>
</plugin>
Use the Require Files Exist rule of the Maven Enforcer plugin.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4.1</version>
<executions>
<execution>
<id>enforce-files-exist</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireFilesExist>
<files>
<file>${property.to.check}</file>
</files>
</requireFilesExist>
</rules>
<fail>true</fail>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

why list the goals of a plugin without binding to a phase?

Please consider this pom excerpt taken from jacoco example ( http://www.eclemma.org/jacoco/trunk/doc/examples/build/pom-it.xml)
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.5-SNAPSHOT</version>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>default-prepare-agent-integration</id>
<goals>
<goal>prepare-agent-integration</goal>
</goals>
</execution>
<execution>
<id>default-report</id>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>default-report-integration</id>
<goals>
<goal>report-integration</goal>
</goals>
</execution>
<execution>
<id>default-check</id>
<goals>
<goal>check</goal>
</goals>
<configuration>
<rules>
<!-- implmentation is needed only for Maven 2 -->
<rule implementation="org.jacoco.maven.RuleConfiguration">
<element>BUNDLE</element>
<limits>
<!-- implmentation is needed only for Maven 2 -->
<limit implementation="org.jacoco.report.check.Limit">
<counter>COMPLEXITY</counter>
<value>COVEREDRATIO</value>
<minimum>0.60</minimum>
</limit>
</limits>
</rule>
</rules>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.16</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.16</version>
<executions>
<execution>
<id>default-integration-test</id>
<goals>
<goal>integration-test</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
Now I know that you can bind a plugin's goal to a maven phase, that is run that goal when maven executes a specific phase.
What is the point of just listing the integration-test goal for the maven failsafe plugin without binding it to something?
The same as for jacoco report and others goal? I don't think you can force the plugin to execute just those listed goals right?
Many thanks
The point is that a plugin can define default life cycle phases where the appropriate goal is bound to (many plugins do this). In this cases you don't need to specify the life cycle phase within the pom file explicitly.
For example the maven-failsafe-plugin has a goal integration-test. This goal has a default binding to the integration-test life cycle phase. Here an excerpt from the documentation:
Description:
Run integration tests using Surefire. Attributes:
Requires a Maven project to be executed.
Requires dependency resolution of artifacts in scope: test.
The goal is thread-safe and supports parallel builds.
Binds by default to the lifecycle phase: integration-test.
That's the reason why you don't need to give a life cylce phase in the configuration like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.18.1</version>
<executions>
<execution>
<id>default-integration-test</id>
<goals>
<goal>integration-test</goal>
</goals>
</execution>
</executions>
</plugin>
The same is meant for the jacoco maven plugin.
If I understand correctly, M2E will execute the plugin goal during workspace full or incremental builds.
The following article may shed some light:
http://eclipse.org/m2e/documentation/m2e-execution-not-covered.html
You are correct that, on command line, you would not be able to specify the goal, since it is a plugin goal and not tied to a phase. This could be an oddball usage specifically for M2E integration.

Maven: Extract dependency resources before test

I have a multimodule Maven project. One subproject hosts XSL/XML resource files. The other project hosts Java code that needs to use these files in its unit tests.
In the dependency's jar, the resources lie in the folder xml-resources.
I found this example and tried to change it for my needs:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>resource-dependencies</id>
<phase>process-test-resources</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<classifier>xml-resources</classifier>
<outputDirectory>${project.build.directory}/classes/xml-resources</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
This doesn't do anything when I run the process-test-resources phase. Am am sure that there are some errors in there - I do not see where I can specify the dependency the resources should be taken from, and <classifier> does not seem to actually specify the source where the resources should be copied from.
I'm lost here, can somebody tell me how to do this right?
Try something like this
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>resource-dependencies</id>
<phase>process-test-resources</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<includeArtifactIds>my-artifact-id</includeArtifactIds>
<includes>foobar.txt, loremipsum.xml</includes>
<outputDirectory>${project.build.directory}/classes/xml-resources</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
Have a look at the unpack-dependencies parameters for detailed explanation or further information.

Resources