Redirecting the nexus-staging-maven-plugin to an internal repository - maven

I have a webjars project that I'd like to build snapshots and have them deployed locally (within our infrastructure) but have the releases be managed by webjars.org.
https://github.com/webjars/oscar/blob/15.0.0-RC1/pom.xml
The problem I'm facing is that they need the nexus-staging-maven-plugin defined as part of their release process. So I'd like to keep the POM tailored for them as much as possible, and just make our own deviations via command line (or worst case, profile) if possible.
Typically, if doing this from scratch, you'd probably introduce the staging plugin in a profile, but I don't think I have that option. (I might have to make the modification though and discuss it with them.)
I've never used the staging plugin before, so this is my first exposure and it isn't a pleasant one given what I'm trying to do. I feel like I'm fighting the system.
I thought I had something by specifying:
-DsonatypeOssDistMgmtSnapshotsUrl=http://myurl
and that pushes the artifact at the correct location, but then I can't figure out how to supply credentials. (401 unauthorized) I thought specifying the serverId might work, but no.
-DserverId=public-snapshots
http://books.sonatype.com/nexus-book/reference/staging-deployment.html
I then tried creating a profile, where I'd do something like this:
<profile>
<id>disable-staging</id>
<build>
<plugins>
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.5</version>
<configuration combine.self="override">
<executions>
<execution>
<id>injected-nexus-deploy</id>
<phase>none</phase>
</execution>
</executions>
</configuration>
</plugin>
</plugins>
</build>
</profile>
but that doesn't help. The effective-pom shows this:
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.5</version>
<extensions>true</extensions>
<executions>
<execution>
<id>injected-nexus-deploy</id>
<phase>deploy</phase>
<goals>
<goal>deploy</goal>
</goals>
<configuration combine.self="override">
<executions>
<execution>
<id>injected-nexus-deploy</id>
<phase>none</phase>
</execution>
</executions>
</configuration>
</execution>
</executions>
<configuration combine.self="override">
<executions>
<execution>
<id>injected-nexus-deploy</id>
<phase>none</phase>
</execution>
</executions>
</configuration>
</plugin>
and I can't unbind the deploy phase.
I'm wondering if anyone has any ideas on what to do in this type of scenario?

You can use the Nexus Staging Plugin's property skipNexusStagingDeployMojo to achieve this:
mvn clean package deploy:deploy -DskipNexusStagingDeployMojo=true
-DaltDeploymentRepository=snapshots::default::https://my.nexus.host/content/repositories/snapshots-local
It is important to explicitly invoke package and then deploy:deploy, as otherwise (when only invoking mvn deploy) the default execution of the maven-deploy-plugin is suppressed by the Nexus Staging Plugin (even with the skip set to true).

Related

Where does the configuration block of an execution actually go in pom.xml?

It seems a very simple question, but something is not working right.
So given a pom.xml file I wanted to use the properties-maven-plugin. If I copy what is in the docs, meaning this code:
<project>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>write-project-properties</goal>
</goals>
<configuration>
<outputFile>
${project.baseDir}/app.properties
</outputFile>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
And then I run using mvn properties:write-project-properties, I get an error:
Failed to execute goal org.codehaus.mojo:properties-maven-plugin:1.0.0:write-project-properties (default-cli) on project backend: The parameters 'outputFile' for goal org.codehaus.mojo:properties-maven-plugin:1.0.0:write-project-properties are missing or invalid
BUT
when I edit the code above and move the configuration right next to executions and then run the command, everything works (even though IntelliJ underlines the configuration expression with red saying properties 'child' tag should be defined.
<project>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>write-project-properties</goal>
</goals>
</execution>
</executions>
<configuration>
<outputFile>
${project.baseDir}/app.properties
</outputFile>
</configuration>
</plugin>
</plugins>
</build>
</project>
I just randomly stumbled upon this answer here that solved this issue.
Why is this happening and where are the documentations for maven that would prevent me from spending couple hours wasting on a configuration file next time I need something?
The reason is as follows:
The first POM defines an execution for the Maven lifecycle together with its configuration. So it is meant to run when you call something like mvn clean install. With the configuration inside the execution, you just configured that execution (not any other execution, like the one you started from command line).
The second POM has a global configuration for the plugin goal. The execution in the POM does not matter (you can just delete it), but your command line execution will pick up this global configuration.
Does this make the behaviour more understandable?

Deploy a single war to multiple tomcats using tomcat-maven-plugin

I'm trying to deploy a single war project to multiple tomcats using mvn tomcat:deploy. Since these are listener project (aka workers), their overlapping names are irrelevant.
When I have
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tomcat-maven-plugin</artifactId>
<configuration>
<url>`http://192.168.116.54:8080/`manager/text</url>
<server>standaardTomcat</server>
<path>/picalcworker</path>
</configuration>
</plugin>
a single war will be deployed on that server. Though I cannot have multiple 'plugins' of the same groupId artifactId combination, so simply copy this and change the url will result in a warning and only one (the latest) to be deployed.
This plugin further seems to allow:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tomcat-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<id>1</id>
<phase>deploy</phase>
<goals>
<goal>deploy</goal>
</goals>
<configuration>
<url>http://192.168.116.52:8080/manager/text</url>
<server>standaardTomcat</server>
<path>/picalcworker</path>
</configuration>
</execution>
<execution>
<id>2</id>
<phase>deploy</phase>
<goals>
<goal>deploy</goal>
</goals>
<configuration>
<url>http://192.168.116.53:8080/manager/text</url>
<server>standaardTomcat</server>
<path>/picalcworker</path>
</configuration>
</execution>
</executions>
</plugin>
but then mvn tomcat:deploy will try to deploy to localhost, since <configuration><url> was empty in this plugin's root (but I cannot supply a singular url there, since I need multiple). Also possible tomcat7 and tomcat6.
I really like the deploy and undeploy options. Does anybody know how to make this work, or some reasonable alternative?
currently not possible.
Note the plugin is now hosted at Apache see http://tomcat.apache.org/maven-plugin.html .
Can you load a jira for that ? That need a bit of code (maybe you can add a patch :-) )

Can I modify the Maven deploy phase to replace the maven-deploy-plugin with my own plugin?

I'm pretty new to Maven...
What I'm trying to do is skip the maven-deploy-plugin during the deploy phase, while replacing it with my own plugin (i.e. I'm deploying to a non-repository location).
I realize I could do this in multiple other ways, but the boss wants to be able to run:
mvn deploy
To get the results of my current workaround, which is disabling the maven-deploy-plugin (which seems to be disabling the entire deploy phase), and manually specifying the custom upload goal from the command line.
I'm currently failing to succeed in my mission with:
<executions>
<execution>
<phase>deploy</phase>
</execution>
</executions>
in the build/plugins/plugin section containing my plugin specification, since the deploy phase is skipped by:
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.7</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
Thanks!
disabling the maven-deploy-plugin (which seems to be disabling the entire deploy phase)
This is not correct. Disabling maven-deploy-plugin doesn't disable the entire deploy phase. This is how it should be done (looks like you're doing it already):
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
Try this (untested) alternative for disabling the standard deploy plugin:
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.7</version>
<executions>
<execution>
<id>default-deploy</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
I want to build on #yegor256's answer a bit... 8 years, 4 months later!
I found myself here getting into the weeds on some legacy Maven configurations that were full of cruft. Coming from a Maven mindset, albeit some years between now and active hacking, I was re-familiarizing myself with the Maven lifecycle.
TLDR... mvn help:effective-pom is your friend. Use your IDE's tools for viewing the effective POM often (NetBeans makes it easy. I added a keyboard shortcut in IntelliJ.)
In the configuration I was reviewing, the previous developers had created two (2) deploy-file executions, one war, one jar.
<build>
...
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
<executions>
<execution>
<id>deploy-war</id>
<phase>deploy</phase>
<goals>
<goal>deploy-file</goal>
</goals>
<configuration>
... omitted ...
</configuration>
</execution>
<execution>
<id>deploy-jar</id>
<phase>deploy</phase>
<goals>
<goal>deploy-file</goal>
</goals>
<configuration>
... omitted ...
</configuration>
</execution>
</executions>
</plugin>
...
</plugins>
...
</build>
I was aware that these executions would be appended to the default-deploy bound to the deploy phase and observed this behavior in the logs. The default-deploy would run, uploading an empty war file, then the deploy-war would run, uploading, and overwriting, the first war file.
Several options exist.
skip and combine.self="override" (my preference)
As presented, using <skip> as a <configuration> option is viable. It is safe and more portable than setting setting the <phase> to none.
However, it will be inherited by the other executions (certainly as presented). To prevent this, you must explicitly tell your additional <execution> configurations to not inherit.
...
...
<executions>
<execution>
<id>deploy-war</id>
<phase>deploy</phase>
<goals>
<goal>deploy-file</goal>
</goals>
<configuration combine.self="override">
... omitted ...
</configuration>
</execution>
...
...
Override default-deploy
Another option, possibly more verbose and lest esoteric than combine.self="override" is to override the execution of the default-deploy <id> of the plugin.
...
<execution>
<id>default-deploy</id>
<configuration>
<skip>true</skip>
</configuration>
</execution>
...
This will not be inherited by the additional <executions>.
Another option
As #yegor256 notes, but in the additional configurations explicitly state <skip>false</skip> to "reset" the inherited <skip> from the plugin.
HTH.

Maven: How do I enforce property inclusion for a life cycle phase?

I'm using Maven 3.0.3. If someone runs a Maven task that is inclusive of the "verify" phase, I want to ensure that a property, "tomcat.manager.url" is defined, and throw an error if it isn't. However, if someone hasn't run a command that includes verify (e.g. mvn test), I don't want to throw any error.
How do I do this?
Thanks, - Dave
You could set the enforcer plugin (docs) to execute during the "verify" phase with a rule that requires that plugin to be set, the configuration would look something like this:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.0.1</version>
<executions>
<execution>
<id>enforce-property</id>
<goals>
<goal>enforce</goal>
</goals>
<phase>verify</phase>
<configuration>
<rules>
<requireProperty>
<property>tomcat.manager.url</property>
<message>You must set a tomcat manager url</message>
</requireProperty>
</rules>
<fail>true</fail>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Since the plugin will only execute during the verify phase, the check won't happen unless you are running a build that reaches that phase.

In a Maven multi-module project, how can I disable a plugin in one child?

I have a maven multi-module project (boy, I've written that opening way too many times on this site). Almost all the modules (that is, the ones that have code in them) should run the maven-site-plugin to generate reports about code coverage, etc. These have a detailed shared configuration -- which reports to run, which files to cover/exclude for certain plugins, etc.
However, there are a few modules that deal with packaging -- running the assembly plugin to generate a tarball, etc. These gain nothing from running a site report -- there's no code to analyze, no tests to report on.
So I have a lot of modules that need to share plugin configuration, and a few modules that need to not run the plugin, preferably at all. I can do the former (share configuration) if I put the plugin in the <build> section of the parent POM, but I can't seem to turn off the plugin when I need to in this case. I can do the latter (avoid running the plugin) if I push configuration down to each module's own POM, but I can't figure out a good way to share the configuration information in this case.
Is what I want -- shared configuration, for a plugin that's sometimes disabled by a child module -- even possible? If so, how?
By "run the plugin", I'm assuming you mean that the plugin is bound to a lifecycle phase, and you'd like to unbind it in some modules. First, you could consider changing your POM inheritance so that the modules that don't need the plugins have one parent and the ones that do have a different parent. If you don't want to do that, then you can explicitly set the execution phase to "nothing" in a child module. E.g. if you had a parent pom configuration like this:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<id>i-do-something</id>
<phase>initialize</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
... lots of configuration
</configuration>
</execution>
</executions>
</plugin>
Then in a child module, you could do this:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<id>i-do-something</id>
<phase/>
</execution>
</executions>
</plugin>
Because it's the same plugin and the same execution id, it overrides the configuration specified in the parent, and now the plugin isn't bound to a phase in the child project.
Ryan Stewart's answer works if execution that you wish to suppress in the parent pom is tagged with an id. If, however, the parent pom doesn't tag the execution with an id (and, of course, you can't edit that parent pom) then I found that doing the following suppresses the parent pom's action.
First set the phase of the execution to none
Create another execution, give it an id and do in it what you need it to do.
run mvn help:effective-pom to confirm that it has correctly suppressed what you needed suppressed from the parent pom.
Here's an example:
This is how my parent pom looked like:
<plugin>
<artifactId>maven-source-plugin</artifactId>
<version>2.1.2</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
<inherited>true</inherited>
</plugin>
I needed to change the goal to jar-no-fork. Note that the execution in parent pom doesn't have an id that I could use to disable it. So here's what added to my child pom:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<phase>none</phase>
</execution>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
As a result this is how the effective-pom looks like:
<plugin>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<phase>none</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<archive>
<compress>false</compress>
</archive>
</configuration>
</execution>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
<configuration>
<archive>
<compress>false</compress>
</archive>
</configuration>
</execution>
</executions>
<inherited>true</inherited>
<configuration>
<archive>
<compress>false</compress>
</archive>
</configuration>
</plugin>
This ensured that the goal jar never runs and only the goal jar-no-fork executes -- which is what I wanted to achieve.

Resources