Is it possible to force any maven plugin to execute with VM arguments when I do mvn clean install?
More context
I have an old project that I try to mirgate to java 11. During this migration I had trouble with wadl-client-plugin and JAXB showing this error.
schema_reference: Failed to read schema document '...', because 'file' access is not allowed due to restriction set by the accessExternalSchema property.
When I run it like mvn clean install -Djavax.xml.accessExternalSchema=all it works. I need to include somehow -Djavax.xml.accessExternalSchema=all to the plugin execution when I run mvn clean install. I've checked wadl-client-plugin's docs and don't see anything about it. Is it possible to do it somehow in general way? Configuring local JVM is not an option neither as I cannot do it at all machines.
I finally found an answer here
properties-maven-plugin inside my pom did the trick.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<id>set-additional-system-properties</id>
<goals>
<goal>set-system-properties</goal>
</goals>
</execution>
</executions>
<configuration>
<properties>
<property>
<name>javax.xml.accessExternalSchema</name>
<value>all</value>
</property>
</properties>
<outputFile/>
</configuration>
</plugin>
Related
I have a project that consist of 3 different libraries. When I run install script it takes all libraries from repo and run mvn clean install on them. But this version of library already installed in repo. Is there a way to skip install phase if version in pom.xml equal version in my local repo.
I know that I can use local repo and just set dependencies. But my boss want that our project can build only with public repos and without any our repos.
You can bypass like this
-Dmaven.install.skip=true
<profiles>
<profile>
<id>skipInstall</id>
<activation>
<property>
<name>maven.install.skip</name>
<value>true</value>
</property>
</activation>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<id>default-install</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
Last week Olivier Lamy patched this jira.
MINSTALL-73
Most maven plugins can be skipped by specifying something like:
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>X.Y</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
you can also set up build profiles to set properties and use that to determine the value. for example, running the command: mvn -Pexample would select the "example" profile. The POM would then contain:
...
<properties>
<skip.install>false</skip.install>
...
</properties>
...
<profile>
<id>example</id>
<properties>
<skip.install>false</skip.install>
</properties>
</profile>
...
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>X.Y</version>
<configuration>
<skip>${skip.install}</skip>
</configuration>
</plugin>
...
Using these POM additions, the default behavior for the install plugin will be to perform its default goal, but if the example profile is selected, then the install plugin will skip its goal.
Using what I learned from the other answers, this was the cleanest result for me.
In my super pom I added a pluginManagement/plugin to disable default-install and default-test phases when the property deployOnly is set.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
<executions>
<execution>
<id>default-install</id>
<configuration>
<skip>${deployOnly}</skip>
</configuration>
</execution>
<execution>
<id>default-test</id>
<configuration>
<skip>${deployOnly}</skip>
</configuration>
</execution>
</executions>
</plugin>
So on the command line, I can disable install and test phases by adding -DdeployOnly.
mvn clean install #build and test everything
mvn deploy -DdeployOnly #just deploy it
I know that I can use local repo and just set dependencies. But my boss want that our project can build only with public repos and without any our repos.
Are you sure you understood correctly what you boss meant? I interpret the above as "don't install third party libraries in your local repository, use only libraries available in public repositories". This is different from "don't use your local repository" which is basically impossible, that's just not how maven works. I'd try to clarify this point.
Apart from that, I don't get the question which is very confusing (what repo are you talking about? What is the install script doing? Why do you call clean install on libraries? etc).
Extending the other answers, from the future.
Maven plugins have a surprisingly high freedom, how do they run. If they want, they can ignore/override the typical pom.xml settings. Furthermore, also the <configuration><skip>true</skip></configuration> is only a convention, nothing obligates a plugin to follow it, except that most of them is developed so.
My experiments with the recent problem show, that both #Cemo's and #MiloshBoroyevich solution should be utilized, also the plugin requires both to really let us in peace. More concretely, the only working configuration by me was this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
<executions>
<execution>
<id>default-install</id>
<phase>none</phase>
</execution>
</executions>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
One of your options is to put the deployment to another module. I.e. have one pom.xml build the artifact and install it to the local repo, and another pom.xml to deploy it. This separation is quite common in larger projects, where the testsuite is sometimes a separate module or even a project, the packaging happens in several stages, etc.
- pom.xml - myProject-root - type=pom
- pom.xml - myProject-artifact - type=jar
- pom.xml - myProject-deploy - type=pom, does the deployment, skips it's own `install` goal
I am trying to implement semantic versioning in our project. I tested maven semver plugin but that didn't help me so please don't ask me why. I finally ended up using maven groovy. It works like a charm, however, when I install or deploy the maven project the version in repository is the variable name.
This is despite the fact that all the artefacts and jar files are packaged with correct version.
So please look at my pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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>com.mytest.test</groupId>
<artifactId>test-tag</artifactId>
<version>${revision}</version>
<description>Test</description>
<properties>
<ChangeType>TO_BE_SET</ChangeType>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.gmaven</groupId>
<artifactId>gmaven-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<providerSelection>2.0</providerSelection>
<properties>
<script>git describe --abbrev=0 --tags</script>
</properties>
<source>
def tagIt = 'git tag -a vXXXX -m "Auto tagged"'
def changeType = project.properties.ChangeType
def command = project.properties.script
def process = command.execute()
process.waitFor()
def describe = process.in.text.trim()
println "Setting revision to: " + describe
if(!describe.startsWith("v")) {
describe = "1.0.1"
} else {
describe = describe.substring(1)
}
project.properties.setProperty('revision', describe)
</source>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>default-compile</id>
<phase>none</phase>
</execution>
<execution>
<id>default-testCompile</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>default-testResources</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>default-jar</id>
<phase>package</phase>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>default-test</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
the version is ${revision} a variable name that is being set in groovy script. What groovy code does is getting the last tag from GIT and and then set it to the property 'revision'.
The final jar file has the correct version extracted but when installed into repository, the folder name and jar name are like:
m2\repository\com\mytest\test\test-tag\${revision}\test-tag-${revision}.jar
I tried to default 'revision' to a value using:
<properties>
<revision>1.0.1</revision>
</properties>
but then groovy code setting the value has no effect.
I also tried different phase for the maven groovy plugin, no luck. Have I missed anything? Can anyone please help me on this?
I'd like to mention that as vatbub and StefanHeimberg mentioned I can use versions:set to set the version but this requires me to do an extra commit to GIT which I am trying to avoid, wondering if I can achieve this by writing a maven plugin instead?
With Maven you can set the version at build time with
mvn versions:set -DnewVersion=${bamboo.inject.version}
as #vatbub already commented in your question.
In addition to this i wrote a Shell script that can be used in build pipeline to generate the version according to the maven project version and add the build number from the build server.
https://gist.github.com/StefanHeimberg/c19d7665e8df087845c036fe8b88c4f2
The Script reads the maven project version, add a the build number and writes a text file with all the new numbers that can be used.
The next step is to inject this text file in the Build Pipeline and call the versions plugin as stated above
pom.xml:
something like
<project>
<groupId>ch.stefanheimberg.example</groupId>
<artifactId>your-awesome-app</artifactId>
<version>5.1.2-SNAPSHOT</version>
</project>
or
<project>
<groupId>ch.stefanheimberg.example</groupId>
<artifactId>your-awesome-app</artifactId>
<version>5.1-SNAPSHOT</version>
</project>
Step 1:
./generate_version_txt.sh ${bamboo.buildNumber}
Step 2:
Inject generated version.txt in the build system that all the properties can be used in all tasks / plugins, etc...
In my case Bamboo CI ready the version.txt file and declares the content of the file as environment variables under the bamboo.inject. prefix.
For example ${bamboo.inject.long_version}
Step 3:
Update Maven Project version
mvn versions:set -DnewVersion=${bamboo.inject.version}
Step 4:
Run Maven Build
mvn clean verify
Step 5:
Run Docker build
for example use it also as docker tag version. etc...
docker build --build-arg version=${bamboo.inject.version} --tag your-awesome-app:${bamboo.inject.version} .
Example Dockerfile:
FROM jboss/wildlfy
ARG version
ADD target/your-awesome-app-${version}.war /opt/jboss/wildfly/standalone/deployments/
I know that can be a problem / not possible in your case with the groovy script. but perhaps it is an other view at your problem. and possibly also another solution for it.
(sorry for my english. but i hope it is understandable what i mean)
I ran into a similar problem and ended up using the maven flatten plugin to ensure that all variables are removed from the POMs before being deployed. This remove all references to the string ${revision} and replace by the actual value at build time, without interfering with the original POMs.
Sonatype has a repository that I want to deploy a jar file to, and they ask for separate files for application, sources, and javadocs:
Example:
example-application-1.4.7.pom
example-application-1.4.7.jar
example-application-1.4.7-sources.jar
example-application-1.4.7-javadoc.jar
In Scala SBT, I have a command called "package" that generates the jar file for the project, but that only generates "example-application-1.4.7.jar".
Question: What should I do to generate the other two jar files?
In Maven, in order to get the additional -sources and -javadoc artifacts, add to your POM file the following:
<build>
<plugins>
<!-- additional plugin configurations, if any.. -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.3</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Note the snippet above:
We are invoking the Maven Source Plugin to create an additional jar files for sources
We are invoking the Maven Javadoc Plugin to create an additional jar files for javadoc
Executing
mvn clean package
You will find these two additional jars in the target folder.
The .pom file instead is generated during the install phase, but it is not placed under the target folder. Basically, it is a copy of your pom.xml file, with a different extension and used by Maven during the dependency mediation process to check which transitive dependencies are required by the concerned artifact.
Executing
mvn clean install
Maven will install the artifact in your local cache (in your machine), under path_to_cache/.m2/repository/your_groupId/your_artifactId/your_version/. In this folder, you will also find the .pom file, which normally you don't need to distribute (it is created automatically by Maven).
Further note: you probably don't want to generate these additional jar files at each and every build, so to speed up normal builds and have them only on demand, you could wrap the snippet above in a Maven profile.
You can achieve this by removing the snippet above from your build section and add a further section at the end of your pom:
<profiles>
<profile>
<id>prepare-distribution</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.3</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
So that normal builds would not create these jars anymore, but when executing the following:
mvn clean install -Pprepare-distribution
You would instead get them back. the -P option is actually activating on demand the profile defined with the id prepare-distribution.
With Maven 3 a default profile already comes as part of the super pom which perform exactly the same actions (sources and javadoc artifact), hence no need to add anything to your existing project. Simply run:
mvn clean install -Prelease-profile
Or, to activate it via a property
mvn clean install -DperformRelease=true
However, as also specified in the super pom, this profile may be removed in future releases (although there since first Maven 3 version till version 3.3.9 so far)
NOTE: The release profile will be removed from future versions of the super POM
The main reason behind this warning is most probably to push for the usage of the Maven Release Plugin, which indirectly makes use of this profile via the useReleaseProfile option of the release:perform goal.
As highlighted by comments, if you are not familiar with maven (especially via console) I would definitely recommend to
Go through the official Maven in 5 minutes documentation for a quick but worthy look.
Play with Maven from the command line, is there where Maven gives you its best. IDE integrations are great, but command line is the real turning point.
Then play with the POM customization above, to get familiar with some concepts and behaviors, first directly as part of your default build, then moved to a profile.
Then, and only then, move to the Maven Release Plugin usage. I recommend it as last step because you would already have acquired more confidence and understanding and see it as less magic and more reasonable approach.
I'm using Travis-CI to provide continuous integration builds for a few Java open source projects I'm working on.
Normally this works smoothly, but I have a problem when the POM specifies GPG signing, e.g.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
This causes the Travis build to fail - apparently because it does not have a passphrase available while running mvn install. See this build for an example.
What is the best way to configure Maven and/or Travis to skip GPG signing for CI test builds, but still perform GPG signing when I do a proper release build?
Disable GPG signing by adding the following line to your .travis.yml file:
install: mvn install -DskipTests -Dgpg.skip
Example: https://github.com/stefanbirkner/system-rules/blob/master/.travis.yml
You need to create a profile & make sure you run that only when you do the release build.
Remove the current plugin, and add it in a profile like this:
<profiles>
<profile>
<id>release-sign-artifacts</id>
<activation>
<property>
<name>performRelease</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
And then when you actually need to do a release, add the property to your mvn command:
mvn -DperformRelease=true ...
I found a slightly simpler way to do it with the profile as described above. Instead of using a new property value, you can use the gpg.passphrase property which will need to be provided anyway when doing signing. The modified property section is as follows:
<activation>
<property>
<name>gpg.passphrase</name>
</property>
</activation>
Notice, that no value is required since you want this profile to activate if any value is set for that property.
The corresponding command line then looks like this:
mvn <command> -Dgpg.passphrase=myverysupersecretpassphrase
You can test this out by running it the following two ways:
mvn install
No signed artifacts get generated, and:
mvn install -Dgpg.passphrase=myverysupersecretpassphrase
Signed artifacts get created.
To do the actual signed release of the artifacts do the following:
mvn release:perform -Darguments=-Dgpg.passphrase=myverysupersecretpassphrase
The indirection is needed for the release action because it doesn't propagate the command line arguments directly to the spawned process (see http://maven.apache.org/plugins/maven-gpg-plugin/usage.html).
We are using the maven release plugin on hudson and trying to automate the release process.
The release:prepare works fine. When we try to do the release:perform , it fails because it tries to upload a source artifact twice to the repository.
Things that I tried,
removing the profile which does include the maven source plugin from the super pom ( did not work)
specifying the goals on hudson for release as -P!attach-source release:prepare release:perform. Which I thought will exclude the source plugin from getting executed. (did not work).
tried specifying the plugin phase to some non existent phase in the super pom.(Did not work)
tried specifying the plugin configuration, forReleaseProfile as false. ( guess what?? Did not work too)
It still spits out this error.
[INFO] [DEBUG] Using Wagon implementation lightweight from default mapping for protocol http
[INFO] [DEBUG] Using Wagon implementation lightweight from default mapping for protocol http
[INFO] [DEBUG] Checking for pre-existing User-Agent configuration.
[INFO] [DEBUG] Adding User-Agent configuration.
[INFO] [DEBUG] not adding permissions to wagon connection
[INFO] Uploading: http://xx.xx.xx.xx:8081/nexus/content/repositories/releases//com/yyy/xxx/hhh/hhh-hhh/1.9.40/hhh-hhh-1.9.40-sources.jar
[INFO] 57K uploaded (xxx-xxx-1.9.40-sources.jar)
[INFO] [DEBUG] Using Wagon implementation lightweight from default mapping for protocol http
[INFO] [DEBUG] Using Wagon implementation lightweight from default mapping for protocol http
[INFO] [DEBUG] Checking for pre-existing User-Agent configuration.
[INFO] [DEBUG] Adding User-Agent configuration.
[INFO] [DEBUG] not adding permissions to wagon connection
[INFO] Uploading: http://xx.xxx.xx.xx:8081/nexus/content/repositories/releases//com/xxx/xxxx/xxx/xxx-xxx/1.9.40/xxx-xxx-1.9.40-sources.jar
[INFO] [DEBUG] Using Wagon implementation lightweight from default mapping for protocol http
[INFO] [INFO] ------------------------------------------------------------------------
[INFO] [ERROR] BUILD ERROR
[INFO] [INFO] ------------------------------------------------------------------------
[INFO] [INFO] Error deploying artifact: Authorization failed: Access denied to: http://xx.xxx.xx.xx:8081/nexus/content/repositories/releases/com/xxx/xxx/xxx/xxx-config/1.9.40/xxx-xxx-1.9.40-sources.jar
Any help regarding this will be really appreciated.
Try running mvn -Prelease-profile help:effective-pom.
You will find that you have two execution sections for maven-source-plugin
The output will look something like this:
<plugin>
<artifactId>maven-source-plugin</artifactId>
<version>2.0.4</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
<execution>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
To fix this problem, find everywhere you have used maven-source-plugin and make sure that you use the "id" attach-sources so that it is the same as the release profile. Then these sections will be merged.
Best practice says that to get consistency you need to configure this in the root POM of your project in build > pluginManagement and NOT in your child poms. In the child pom you just specify in build > plugins that you want to use maven-source-plugin but you provide no executions.
In the root pom.xml:
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<!-- This id must match the -Prelease-profile id value or else sources will be "uploaded" twice, which causes Nexus to fail -->
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
In the child pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
</plugins>
</build>
I know this question is old but it was google hit #1 today so I'll add my answer appropriate for recent versions of maven 3.
The symptom is that sources and javadoc jars are deployed twice when doing a release build with some versions of maven 3. If you're using maven to deploy your artifacts to a Sonatype Nexus repository that only allows a release artifact to be uploaded once (which is totally reasonable behavior), the build fails when the second upload attempt is rejected. Argh!
Maven versions 3.2.3 thru 3.3.9 have bugs - see https://issues.apache.org/jira/browse/MNG-5868 and https://issues.apache.org/jira/browse/MNG-5939. Those versions generate and deploy sources and javadoc jars twice when doing a release.
If I read the Maven issue tracker correctly, those bugs are not scheduled for fix as of this writing (the burned 3.4.0 release probably affected these).
Instead of a complex tweak to my pom, my simple workaround was to fall back to Maven version 3.2.1.
Just having hit the same problem, I analyzed it a bit. mvn release:perform evaluates the release.properties file, then checks out the tag in a temporary directory and invokes there something like
/usr/bin/mvn -D maven.repo.local=... -s /tmp/release-settings5747060794.xml
-D performRelease=true -P set-envs,maven,set-envs deploy
I tried to reproduce this – manually checked out the tag produced by release:prepare and invoked this:
mvn -D performRelease=true -P set-envs,maven,set-envs deploy
I got the same result: It was trying to upload the -sources.jar twice.
As noted by qualidafial in a comment, setting performRelease=false instead omits one of the two attachments of the same file.
I don't really have an idea how the deploy plugin (or any other plugin) uses this property.
We can provide this parameter as a configuration to the maven-relase-plugin:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<useReleaseProfile>false</useReleaseProfile>
</configuration>
</plugin>
</plugins>
</build>
I now added the <useReleaseProfile>false</useReleaseProfile> line to all the POMs, and it looks like releasing now works without an error message.
I have been struggeling with this issue for a while and have finally been able to resolve it in our infrastructure. The answers here didn't help me, as we didn't have multiple executions of the source plugin goals and the configuration seemed fine to us.
What we did miss out was to bind the execution of the source plugin to a phase. Extending the example by Bae, including the line <phase>install</phase> to the execution resolved the issue for us:
<plugin>
<artifactId>maven-source-plugin</artifactId>
<version>2.0.4</version>
<executions>
<execution>
<id>attach-sources</id>
<phase>install</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
I suspect the solution lies in this answer here; different plugins seem to be invoking the jar goal / the attach-sources execution. By binding our execution to a certain phase, we force our plugin only to be run in this phase.
This was happening to me when running
mvn install deploy
I avoided the problem by instead running
mvn deploy
(which implies install). In my case only one artifact was being attempted to be uploaded twice, and that was a secondary artifact (maven-jar-plugin was setup to build a secondary jar in addition to the one built by the default-jar execution).
TL;DR
Disable execution with id attach-sources fixes this problem, if you cannot modify your parent poms.
--
This answer is a supplementary for #Bae's answer:
https://stackoverflow.com/a/10794985/3395456
My problem is the same, when running mvn -Prelease-profile help:effective-pom, I have two execution sections for maven-source-plugin
<plugin>
<artifactId>maven-source-plugin</artifactId>
<version>2.0.4</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
<execution>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
The top voted answer just recommends a best practice to remove unnamed (anonymous) execution to avoid duplicated binding. But what if I cannot remove it, because I cannot change the parent pom?
There is one way to disable one execution, not the anonymous one, but the one with id attach-source. And it also works for uploading xx-javadoc.jar twice.
So under my pom.xml, I can explictly override the plugins settings, by disabling the execution with id attach-source.
<!-- Fix uploading xx-source.jar and xx-javadoc.jar twice to Nexus -->
<!-- try to disable attach-sources, attach-javadocs execution (bind its phase to none) -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<id>attach-javadocs</id>
<phase>none</phase>
</execution>
</executions>
<inherited>true</inherited>
</plugin>
References:
Is it possible to override executions in maven pluginManagement?
I don't think the probem is in the release plugin, I think you've got the xxx-sources.jar attached two times - that's why the duplicate upload. Why is there a duplicate attachment is hard to tell without seeing the POM. Try running mvn -X and checking the log for who attaches xxx-source.jar another time.
In any case, a good workaround on Nexus would be having a staging repository where you can upload releases several times - and when everything's ready you just close/promote the staging repo. Check the Sonatype OSS setup for an example.
I had the same problem. Basically, the error message is issued when an artifacts is sent to Nexus twice. This may be twice to the same Nexus repository or even across different repositories within the same Nexus.
However, the reasons for such a misconfiguration may vary. In my case, the artifacts were uploaded correctly during a mvn clean deploy build step in Jenkins, but then failed when a second deploy had been attempted. This second deploy had been configured in a Jenkins post build step "Publish artifacts in Maven repository".
Maven plugins in parent and child poms should not have execution. As per standard convention, define all plugin with execution/goals in parent pom in plugin management section. Child pom should not redefine above details, but mention only the plugin (with artifactId, and version) that needs to be executed.
I had similar issue with maven-assembly-plugin with parent pom as below:
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<configuration>
<descriptors>
<descriptor>src/assembly/assembly.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
And Child pom had maven-assembly-plugin as below:
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-5</version>
<configuration>
<finalName>xyz</finalName>
<descriptors>
<descriptor>src/assembly/assembly.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>xyz-distribution</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Removing the <executions> from child pom rectified the issue.
The effective pom had 2 executions performed causing the duplicate install to Nexus repo.
FWIW this issue was breaking our build for a while and the answer was none-of-the-above.
Instead I had foolishly set the seemingly innocuous appendAssemblyId to false in a maven-assembly-plugin for an artifact that gets attached (read deployed, released) with our main artifact. E.g.:
<execution>
<id>ci-groovy-distrib</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptorRefs>
<descriptorRef>my-extra-assembly</descriptorRef>
</descriptorRefs>
<!-- This is the BUG: the assemblyID MUST be appended
because it is the classifier that distinguishes
this attached artifact from the main one!
-->
<appendAssemblyId>false</appendAssemblyId>
<!-- NOTE: Changes the name of the zip in the build target directory
but NOT the artifact that gets installed, deployed, releaseed -->
<finalName>my-extra-assembly-${project.version}</finalName>
</configuration>
</execution>
In summary:
the assembly plugin uses the assemblyId as the classifier for the artifact, hence an essential part of it's unique GAV coordinates in maven terms (actually it's more like GAVC coordinates - C is the classifier).
the name of the file installed, deployed, or released is actually built from these coordinates. It is not the same as the filename you see in your target directory. That's why your local build looks good, but your release will fail.
The stupid element only determines the local build artifact name and plays no part in the rest of it. It's a complete red-herring.
Summary of the summary:
The 400 error from Nexus was because our extra attached artifact was being uploaded over top of the main artifact, since it had the same name as the main artifact, because it had the same GAVC coordinates as the main artifact, because I removed the only distinguishing coordinate: the classifier derived automatically from the assemblyId.
The investigation to find this was a long and tortuous path the answer was right there all along in the docs for maven-assembly:
appendAssemblyId
boolean
Set to false to exclude the assembly id
from the assembly final name, and to create the resultant assembly
artifacts without classifier. As such, an assembly artifact having the
same format as the packaging of the current Maven project will replace
the file for this main project artifact.
Default value is: true.
User property is: assembly.appendAssemblyId.
From http://maven.apache.org/plugins/maven-assembly-plugin/single-mojo.html#attach
The extra bold is mine. The docs should have a big flashing warning here: "Set this to false and abandon all hope"
I got some help from this answer about a different problem maven-assembly-plugin: How to use appendAssemblyId
The explanation there from tunaki really helped.
I faced similar issue. Artifacts were getting deployed twice and the resultant build was failing.
Checked and found that the issue was in Jenkins Script. The settings.xml was called twice. Like:
sh "mvn -s settings.xml clean deploy -s settings.xml deploy -U .....
which caused the issue.
Updated this line and it worked like a charm:
sh "mvn clean deploy -s settings.xml -U .....
with nexus thix configuratio nworked for me
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<configuration>
<useReleaseProfile>false</useReleaseProfile>
</configuration>
</plugin>
I configured the maven release plug-in with releaseProfile=false and dont execute the source artifacts profile. Which did the trick.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.1</version>
<configuration>
<arguments>-P!source-artifacts</arguments>
<useReleaseProfile>false</useReleaseProfile>
<goals>-Dmaven.test.skip=true deploy</goals>
</configuration>
</plugin>
</plugins>
</build>