Maven calling plugin from command line in parent pom - maven

My project sturcture:
- something-parent
-- something-one
-- something-two
something-parent -> pom.xml:
<packaging>pom</packaging>
<modules>
<module>something-one</module>
<module>something-two</module>
</modules>
<build>
<plugins>
<plugin>
<groupId>io.github.something</groupId>
<artifactId>something-maven-plugin</artifactId>
<version>1.0.0</version>
</plugin>
</plugins>
</build>
Now I want to execute mvn something:help, but I can't: No plugin found for prefix 'something'.
If I remove modules section - it works. It also works in other modules.
It just doesn't work in parent module with modules section. I couldn't find any documentation or literally anything describing this, is this intended? Is there any workaround?
I know io.github.something:something-maven-plugin:1.0.0:help will work, but I need the shortcut version to work.
//Edit1 - I know about settings.xml solution, but it requires manual edit by user, I would like something on a project level
//Edit2 - found out another quirk, it works when I do mvn something:help -N

I understand that you want to use a short name to refer the plugin when calling it from the command line.
To do that, you have to define a plugin group in your settings.xml, as of https://maven.apache.org/settings.html#plugin-groups
In your case it would be:
<pluginGroups>
<pluginGroup>io.github.something</pluginGroup>
</pluginGroups>
This allows you to call:
mvn something:goal

Related

maven fails to recognize jetty is installed

fresh meat newbie on GCP / Maven on
OSX 10.14.3 with Visual Studio Code (latest)
GCP SpringBoot API with Maven
other questions on jetty seem to be further along than me.
the 'flow' below is to reveal steps to get to my question in the title...I think it's important to see how I got to where I am, and if you are so kind to offer help, you would want to know this? ok, here we go...
I downloaded the GCP getting-started-java github example and want to run the bookshelf example.
When I look at the multiple POM files I see that each references a project ID for GCP.
I can't use the same project ID as they are unique, just like GCP bucket names.
So, when I run
gcloud init
and select or create a configuration and make my own project with a unique project id, does that automatically override every POM file definition of project ID? Or do I need to do some maven clean command to change it???
Well... when I RTFM in each folder, it says to
mvn clean jetty:run-exploded -Dbookshelf.bucket=MY-BUCKET
heck even tried:
mvn jetty:run
and I get a build failure that says:
[ERROR] No plugin found for prefix 'jetty' in the current project and in the plugin groups
so... I
brew install jetty
Then to 'get started' jetty says I have to copy the 'plug in' details into my POM file... which one, as there are several??
But when I installed the VS Code plugin, it already updated all POM files; I still get the "No plugin found for prefix 'jetty'" error
I guess I'll stop with that question:
how do I get maven to 'know' that jetty is installed and work with it?
When you use the shorthand plugin goal jetty:run-exploded or jetty:run maven is attempting to find the plugin. This shorthand form will need to resolve the groupId:artifactId:version:goal in order to run.
The long-hand form of that would be ...
$ mvn org.eclipse.jetty:jetty-maven-plugin:9.4.15.v20190215:run
To fix this, just add the plugin to your 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
https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<build>
...
<pluginManagement>
<plugins>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.4.15.v20190215</version>
</plugin>
</plugins>
</pluginManagement>
...
</build>
</project>
The above will always use that specific version of jetty-maven-plugin when you use the shorthand syntax.
Alternatively, and with less control over which version to use, is to setup a pluginGroup in maven's $HOME/.m2/settings.xml
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
https://maven.apache.org/xsd/settings-1.0.0.xsd">
...
<pluginGroups>
<pluginGroup>org.eclipse.jetty</pluginGroup>
</pluginGroups>
...
</settings>

Have Maven fail with a message if a certain profile is used

Let's say I have a profile "dostuff" defined in a pom.xml that uses a plugin to do some stuff when the user runs mvn -P dostuff:
<profiles>
<profile>
<id>dostuff</id>
<build>
<plugins>
<plugin>
...
</plugin>
<plugins>
</build>
</profile>
<profiles>
The task the profile performs have been replaced by a new non-maven command entirely.
Of course I can just remove the profile, but that has two problems:
It doesn't fail the build, it just produces a warning:
[WARNING] The requested profile "dostuff" could not be activated because
it does not exist.
It doesn't give the user any information that they should use the new command instead.
So, I would like any use of the profile "dostuff" to produce an error with a message telling them to use the new non-maven command instead.
Is that even possible? It's a plus if the solution doesn't require a plugin.
The maven-enforcer-plugin has a built-in rule to require a profile is activated. Perhaps you could write your own rule to ban a profile, using that code as a starting point.
Just put the profile in your pom and use it to show a message and throw an exception. You could e.g. use the Antrun plugin to echo a message.

Maven plugin dependency cannot use parent pom property

I'm hitting a weird edge use case with Maven & curious why it's behaving the way it does.
I'm defining a property in my parent project like so:
<properties>
<some.property.version>1.0.0.0</some.property.version>
</properties>
Now, in a module, I set a version of a dependency for a plugin like so:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>bob</artifactId>
<version>1.0.0.0</version>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>example</artifactId>
<version>${some.property.version}</artifactId>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
This causes Maven to spit out an error:
[ERROR] 'build.plugins.plugin[org.apache.maven.plugins:bob].dependencies.dependency.version' for org.example:example:jar must be a valid version but is '${some.property.version}'. # line 350, column 16
What's bizarre to me is if I move the property being defined down into the module itself, Maven compiles just fine. Is this a bug? Or are there restrictions of visibility to parent pom properties in a plugin for a module?
An insanely fast response from the Apache Maven's distribution list! The parent pom had been refactored, and the module was pointing to the stale parent's artifactId. Kudos to Robert!
Hi,
This makes me wonder if the "right" parent is used, so please double
check the groupId, artifactId and version. If both parent and module
are part of the same multi-module, be sure that the relativePath is
correct (defaults to ../pom.xml) You could also use "mvn
org.apache.maven.plugins:maven-help-plugin:2.2:effective-pom" to
verify that the property is really there with the expected value. If
this is all as expected, then it seems to be a bug.
thanks, Robert

maven release:perform with Perforce does not create target/checkout directory

I can not make the maven-release plugin work with Perforce. The release:prepare seems to work correctly: a Perforce label is created and it contains the correct files. Yet when I run release:perform it fails because the target/checkout directory is empty.
I've done some experiments. If I only sync to my pom.xml and then run
mvn scm:checkout
then my other files are checked out into the P4 root directory just as if I had done a
p4 sync ...
Yet Maven outputs
[INFO] Checkout working directory: /home/chris/perforce/pips/target/checkout
[INFO] sync -f //depot/pips/...
Maven thinks it's checking out the target/checkout but it is not. I dug into the P4Maven code a little bit and noticed this in P4Executor.java
public String getRepoPath(P4ScmProviderRepository repo, File basedir) {
// Handles a case where executing release:prepare on a module with an
// invalid SCM location. The release.properties contains the invalid URL
// for checkout during release:perform and the basedir is not the module
// root. So, the trailing target/checkout directory must be removed.
if (basedir.toString().replace('\\', '/').endsWith("/target/checkout")) {
String dir = basedir.toString();
basedir = new File(dir.substring(0, dir.length()
- "/target/checkout".length()));
if (getLogger().isDebugEnabled()) {
logger.debug("Fixing checkout URL: " + basedir);
}
}
This code is pretty clear. P4Maven won't check things out to target/checkout. If you tell it to checkout to target/checkout it will simply remove the "target/checkout" and checkout to the root directory. This is consistent with what I see being done. I also see the "Fixing checkout URL" message when I run release:perform
How then do people work around this?
Below is my pom.xml. I am using
Perforce Server version: P4D/LINUX26X86_64/2014.2/935585 (2014/09/16). p4d is running locally. Authentication is disabled and I don't need a password.
Nexus 2.10.0-02 running locally.
Ubuntu Linux.
Maven 3.2.3
java 1.7.0_55
Thanks.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.ap
ache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.icap</groupId>
<artifactId>pips</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>pips</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<scm>
<connection>scm:p4:192.168.1.8:1666://depot/pips</connection>
<developerConnection>scm:p4:192.168.1.8:1666://depot/pips</developerConnection>
</scm>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-scm-plugin</artifactId>
<version>1.4</version>
<dependencies>
<dependency>
<groupId>com.perforce</groupId>
<artifactId>p4maven</artifactId>
<version>[2011,2012)</version>
</dependency>
</dependencies>
<configuration>
<connectionType>connection</connectionType>
<username>chelck</username>
<includes>**</includes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.1</version>
<dependencies>
<!-- P4Maven -->
<dependency>
<groupId>com.perforce</groupId>
<artifactId>p4maven</artifactId>
<version>[2011,2012)</version>
</dependency>
</dependencies>
<configuration>
<connectionType>connection</connectionType>
<username>chelck</username>
<includes>**</includes>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<fork>true</fork>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<distributionManagement>
<repository>
<id>deployment</id>
<name>Internal Releases</name>
<url>http://localhost:8081/nexus/content/repositories/releases/</url>
</repository>
<snapshotRepository>
<id>deployment</id>
<name>Internal Releases</name>
<url>http://localhost:8081/nexus/content/repositories/snapshots/</url>
</snapshotRepository>
</distributionManagement>
</project>
I have struggled for several days on perforce / maven / release integration and finally got it working. Here are my findings, they might help you and others with similar issues.
Do not use the perforce plugin as described on perforce.com (http://www.perforce.com/perforce/r11.1/manuals/p4maven/index.html). Although it is the first link to come out of a search on google, my understanding is that this plugin is outdated.
In your configuration, if you refer to scm:p4:... you are using the com.perforce plugin. Instead, use org.apache.maven.scm/maven-scm-provider-perforce which uses scm:perforce:... syntax. Your <scm> should look like this:
<properties>
<p4path>//perforce-path/toyour/project</p4path>
</properties>
<scm>
<connection>scm:perforce:yourp4server:1666:${p4path}</connection>
<developerConnection>scm:perforce:yourp4server:1666:${p4path}</developerConnection>
<url>perforce:yourp4server:1666:${p4path}</url>
</scm>
The newer plugin does not require username/password, it will use your active P4 credentials.
I am using maven 3.2.5 and did not have to specify any plugin dependency. The built-in scm recognized the :perforce: scm and downloaded maven-scm-provider-perforce 1.9.2 which is the latest as of this writing. You can make sure you are using an up to date plugin by deleting the maven-scm-provider-perforce folder in .m2\repository\org\apache\maven\scm and then doing a mvn scm:status - it will download the missing plugin and you can see which one it picked.
Here is my maven-release-plugin definition:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.1</version>
</plugin>
I do not have a maven-scm-plugin definition in my pom (I used the default settiings from the superpom).
Test on a non-module project.
You should be able to do the following without error:
- mvn scm:status to check that your scm setup is working correctly
- mvn release:prepare
- mvn release:perform
If you get errors, rollback (mvn release:rollback), make sure everything is back to normal, and rerun with mvn -X to get more details.
In my case, a non-modular project worked without much trouble.
Test on the parent of a reactor project.
There are a few things that were not obvious to me at first and that I found out:
When the is defined in the parent pom, the child module name gets appended to the path for the child module. If your child is not physically under the parent (in my case, it was beside), you need to redefine a configuration in the child pom. In my case, I was using a property (p4path above), simply changing its value was not enough. This was counter-intuitive since the parent pom is normally just a "include", and I expected the parent definitions to be "copy-pasted" in the child module, but in this particular case, it is modified to include the module name at the end of the scm path when it is copy-pasted. [More on modules that do not sit under the parent directory below]
A temporary client spec is created by the perforce scm plugin. This was also counter intuitive, I expected the scm plugin to use my current client-spec. Instead, it will create a new one on the fly, and populate it with the path you provided only and name it username-hostname-MavenSCM-localpath. I was initially surprised by that and tried to change it so it would use by client-spec by customizing the maven.scm.perforce.clientspec.name property, this behaviour was actually correct. With this temporary client-spec, the plugin can limit the lookup for changes, the submit and tagging to this directory. It also makes it easy to track what was done by this plugin in the perforce history.
Creation of the temporary client spec will fail if the modules are not under the parent directory. As I described above, my modules were sitting beside the parent. My <module> tag in the parent pom referred to them using <module>../mymodule</module> which worked fine in eclipse for everything else. The scm perforce plugin includes modules in the client spec by appending the path to the module to the path of the parent. Since Maven resolves the ../ to an absolute path, the client spec ends up containing something like this: //perforce-path/toyour/project/C:\Path\To\Your\Project/mymodule/ and the client spec fails. I could not find a work around for this issue other than moving my modules under their parent. Since the client spec was invalid, I had no file being checked-out under target/checkout. You will get the content of your generated client spec on the console by using mvn -X when invoking release:perform.
Moral of the story: You want to make sure that all your modules sit under their parent directory. When you do this, everything becomes simple and magical: you can leave the declaration in your parent pom and the module path gets magically appended for the module scm paths. You can refer to your modules using <module>mymodule</module> which gets correctly appended in the client-spec. Tagging of the parent in perforce ends up also tagging the modules since they are contained within.

maven update pom property

I'm looking for a way to update pom property to given value, i.e. my pom.xml contains:
<properties>
<abc.def>aaaaa</abc.def>
<properties>
now i want to call :
mvn some_plugin:some_goal -Dabc.def=XYZ
and finally my pom.xml should looks like
<properties>
<abc.def>XYZ</abc.def>
<properties>
I was reading about maven-release-plugin & versions-maven-plugin but i do not see there any matching goal.
Thank you in advance for any reply.
mvn versions:update-properties -Dproperties=[XYZ] -DincludeProperties={abc.def}
Read more here.
and here.
In short:
In versions-maven-plugin, the update-properties goal sets properties to the latest versions of specific artifacts.
includeProperties is a comma separated list of properties to update.
properties are any restrictions that apply to specific properties.
The accepted answer does not work for arbitrary values since it performs sanity checks (links to the documentation for set-property goal since for some reason the documentation for update-properties does not mention this).
To set some arbitrary value on a property use set-property since - as documented - it skips sanity checks:
mvn versions:set-property -Dproperty=your.property -DnewVersion=some_value
Ok, i found some case of solution. I'm using maven-replacer-plugin where:
my properties definition in pom.xml :
<properties>
<abc.def>aaaaa</abc.def>
<properties>
my plugin configuration :
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>replacer</artifactId>
<version>1.5.2</version>
<configuration>
<file>pom.xml</file>
<replacements>
<replacement>
<token>${abc.def}</token>
<value>${replacer.abc.def}</value>
</replacement>
</replacements>
</configuration>
</plugin>
and finally my maven invocation :
mvn replacer:replace -Dreplacer.abc.def=XYZ
It works for me but I don know is there any better way to achieve it with maven-relase-plugin and/or versions-maven-plugin as #khmarbaise and #Conan said.
I agree with #khmarbaise above, the versions-maven-plugin will do just this, or you could move to the Maven Release Plugin if you want a much heftier approach to managing your versions, but you could also just run a script to sed the pom.xml file using Jenkins' BUILD_NUMBER environment variable, which is a quicker and dirtier approach.

Resources