During the maven release:perform goal, the prepared tag is being checked out from SCM and a build seems to be attempted in a forked maven instance.
I'd like the tests to be skipped at that point, because for whatever reason, they fail (the build involves running a test web-application via cargo, and I believe this just doesn't work well in this environment).
Is there any way to instruct maven to do this?
You can specify arguments to the forked maven instance on the command line:
mvn release:prepare -Darguments="-DskipTests"
mvn release:perform -Darguments="-DskipTests"
or specify a maven-release-plugin configuration in your pom, perhaps under pluginManagement:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<configuration>
<arguments>-DskipTests</arguments>
</configuration>
</plugin>
Related
Let's say I want to install project-local dependencies (jar files) to my local maven repository (~/.m2) prior to compiling the project so I can reference them in my POM just like I would reference any dependency from Maven Central. Currently, I'm using Maven install plugin's install-file goal attached to the 'clean' phase (because my IDE uses it), like so:
<dependencies>
<dependency>
<groupId>group.id</groupId>
<artifactId>artifact.id</artifactId>
<version>artifact.version</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
<executions>
<execution>
<id>install-my-local-dependency</id>
<phase>clean</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<groupId>group.id</groupId>
<artifactId>artifact.id</artifactId>
<version>artifact.version</version>
<file>${project.basedir}/lib/local-dep.jar</file>
<packaging>jar</packaging>
<generatePom>true</generatePom>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
When I execute mvn clean (or its equivalent in the IDE), everything runs as I'd expect:
--- maven-clean-plugin:2.5:clean (default-clean) # MyProject ---
--- maven-install-plugin:2.5.2:install-file (install-...) # MyProject ---
Installing ${project.basedir}/lib/local-dep.jar to ~/.m2/repository/group.id/artifact.id/local-dep.jar
But when I execute mvn clean install instead (or its equivalent in the IDE), I get the following error:
Failed to execute goal on project MyProject: Could not resolve dependencies for project com.example.MyProject:jar:1.0: Could not find artifact group.id:artifact.id:jar:artifact.version in central (https://repo.maven.apache.org/maven2) -> [Help 1]
For some reason, Maven install plugin's install-file goal either does not run in this case, or doesn't run soon enough. Why? The other StackOverflow answers I found explain differences between both commands but in my eyes, they do not explain this particular difference as my project has no modules.
Is there a better way of doing the same thing cross-platform, even on build servers (e.g. Jenkins) and with at least one other dependent project?
Should it be any help, I have the following Maven versions:
CLI: 3.6.0
IDE: 3.3.9
Maven first analyses the pom.xml and then calls the goals/phases. The analysis itself is complicated and has different depths, so I guess that calling clean alone will not make Maven analyse the dependencies, but calling clean install does so. Note that the analysis of the POM only happens once, not again for every goal/phase.
Generally, your approach cannot be recommended. Usually, you put project dependencies into remote Maven repositories, so that they can be resolved through them. If you work inside a company, you should set up a Nexus/Artifactory server that handles your artifacts.
If you want people outside your company to build the artifact, you need to find a provider for Maven repositories. I guess that github/gitlab can help you here. Then you need to add those repositories to the POM.
After spending several hours trying to find out whats the problem I come to the conclusion that I need to know:
How can I force maven to execute the lifecycle phases clean, build and site in exact this order: clean -> build -> site?
Problem / scenario:
I have to multimodule projects with identical moduls:
pSuccess
|-pSuccessClient
|-pSuccessEJB (has pSuccessClient as dependency)
|-pSuccessEAR (has pSuccessEJB as dependency)
and
pFail
|-pFailClient
|-pFailEJB (has pFailClient as dependency)
|-pFailEAR (has pFailEJB as dependency)
Both projects have distribution repositories for snapshots and releases in our central nexus artefact repository but none of them has been deployed to it, meaning the nexus is empty.
When I run mvn clean package site on the pSuccess-project the target directory is deleted (clean-lifecycle), then the modules are all build (build-lifecycle) and finally the reports are generated (site-lifecycle) correctly on the freshly build modules - BUILD SUCCESS! While "debugging" the process I figured out that during the build-lifecycle the needed clientDependency is placed in the lokal maven repository and then used for the EJB, same with the EJB for the EAR module. Working smoothly as expected.
But when I do the same on the pFail-project maven executes the site-lifecycle after the clean-lifecycle and before the build-lifecycle. As you can expect this results in a failed build as maven can't find the needed dependency (Client) for the EJB. This is quite locically as it hasn't been build yet. I can enforce this result every time I run the command. There's not phase of the build-lifecycle be run - no compilation, just nothing. Maven tries to execute the site-lifecycle first. The build is only successfull when I run a mvn clean deploy and then another mvn clean package site, becuase then the artefact is read from the nexus. But again site-lifecycle is executed before build-lifecycle. Note Building the project only via mvn clean package works fine without any problems. All modules are build in the correct order. But when I add the site lifecycle it fails.
I read the maven documentation about lifecycle but I can't figure out why site is run before build. In some questions here on SO I read that plugins, which shall be executed in the same phase, are executed in the order they are listed in the pom.xml. So I checked that too, but the <build> tag is definied before the <reporting> tag.
So why is maven executing the site-lifecycle before the build-lifecycle in one of my project and how can I force maven to execute the lifecycles in the right order: clean -> build -> site ?
P.S: I run all maven commands on command line in windows 7.
edit
I know about the lifecycles and phases, meaning I know what's the differenze between package, install, deploy is - that is not part of the question!
For those who do not believe about the execution order: This is the output when I run mvn clean install site, showing that site-lifecycle is executed before build-lifecycle. It doesn't matter if I run mvn clean package site or mvn clean install site. Again, running single mvn clean package(or install) works fine, but not when I want to generate site too. Then site is executed first.
After digging several more hours I found a solution for my problem:
Both projects use the maven-javadoc-plugin during for reporting
<reporting>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>${maven.javadoc.version}</version>
<!-- DocLint je nach Profil ausschalten (siehe oben) -->
<configuration>
<additionalparam>${javadoc.opts}</additionalparam>
</configuration>
</plugin>
...
</reporting>
In the EJB of the failing project we also use the build-helper-maven-plugin in the generate-sources phase of the build lifecycle.
<build>
...
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
....
</plugin>
...
</build>
It seems that both plugins collide during the generate-sources phase.
After chaning the maven-javadoc-plugin to use the following ReportSet the site generation works fine
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>${maven.javadoc.version}</version>
<!-- Disable DocLint correspondening to java version -->
<configuration>
<additionalparam>${javadoc.opts}</additionalparam>
</configuration>
<reportSets>
<reportSet>
<reports>
<report>javadoc-no-fork</report>
<report>test-javadoc-no-fork</report>
</reports>
</reportSet>
</reportSets>
</plugin>
I still don't really understand why it collades but at least my project is working.
Eventually I generate some Java code with explicite mvn generate-sources which calls CXF plugin defined in pom.xml.
Q: How to configure plugin to make it running when I call it explicitly and not running otherwise?
If I set phase to generate-sources, then mvn generate-sources works, but mvn compile also triggers it (that's unwanted).
If I set phase to none, then mvn generate-sources does nothing (unwanted), but mvn compile does not trigger it (ok).
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>${cxf.version}</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<!--<phase>none</phase>-->
You can run any plugin from command line and as such exclusively it (and not part of a Maven phase, in this case), simply configuring the plugin in your POM (plugins section) with a generic configuration (not nested within any execution sub-section).
As such, the given configuration will be used for any execution. Since the concerned plugin does not have any default binding through any Maven packaging (which instead happens for other plugins, i.e. Maven Compiler or Surefire plugins), then the configuration will be picked up only by your command line execution.
mvn org.apache.cxf:cxf-codegen-plugin:wsdl2java
Would then run the plugin you configured with the required configuration, given in your POM:
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>${cxf.version}</version>
<configuration><!-- HERE YOUR CONFIG --></configuration>
</plugin>
As you can see, there is no execution (and hence no phase) described for the plugin, but a global configuration is supplied. As global, it will be used by your command line execution as well.
This approach is slightly different than what you tried:
mvn generate-sources
When executing generate-sources, you are executing a phase and as such any other preceding phase. However, the preceding phases do not affect your project and as such you would get the same behavior, plus the side effect of also having it as part of the compile phase.
If you really want to have it as part of the generate-sources phase (for whatever reason) and keep on running mvn generate-sources without the side effect described above, then you can wrap it in a profile, adding to your POM:
<profiles>
<profile>
<id>generate-cxf</id>
<build>
<defaultGoal>generate-sources</defaultGoal>
<plugins>
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>${cxf.version}</version>
<executions><!-- HERE YOUR EXECUTIONS--></executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
You could then execute:
mvn generate-sources -Pgenerate-cxf
And it will activate the profile above and as such your plugin and executions but not impacting (side effects) any other phase or the default build.
Moreover, via the defaultGoal element configuration, you can even simply invoke:
mvn -Pgenerate-cxf
And you will have exactly the same behavior (although a bit cryptic I would say).
Last but not least, since Maven 3.3.1, you can invoke just a simple plugin execution (keeping your binding to the none phase this time) from command line (specifying the desired execution id) as following:
mvn org.apache.cxf:cxf-codegen-plugin:VERSION_HERE:wsdl2java:#EXEC_ID_HERE
The command above will only (and only) execute your target execution.
I developed a maven plugin with #aggregator annotation.
If I run
mvn clean compile my:artifact:task package
then it compiles 2 times.
So I insert this fragment into my pom
<plugin>
<groupId>my</groupId>
<artifactId>artifact</artifactId>
<version>1.0.0-SNAPSHOT</version>
<executions>
<execution>
<id>post-classes</id>
<phase>process-classes</phase>
<goals>
<goal>task</goal>
</goals>
</execution>
</executions>
</plugin>
but then it will run on each module (# aggregator is seemingly ignored).
How do I let the plugin run once after compiling?
Edit:
My problem refers to the default lifecycle of eclipse tycho. But there is an major bug so I was very confused.
From this:
For mojos executed directly from the CLI, the mojo will only be executed once and not per each project in the reactor. For mojos bound to a lifecycle phase, the mojo will be executed for each project where the lifecycle binding is present.
You have two options:
If you insist on using the aggregator annotation: remove the lifecycle binding and run it via command line, such as "mvn clean compile my:artifact:task jar:jar". Similar to assembly:assembly which is designed to be invoked directly from the command line, and should never be bound to a build lifecycle phase.
If you insist on binding your plugin to lifecycle, remove the aggregator annotation and follow this article. The idea is to examine the project properties where maven is currently running on.
We have a number of third party dependencies that aren't hosted anywhere. For each of these we have a jar file that we'd like to be able to install and/or deploy to our repository. Some of the jar files have their own dependencies and we also need to declare these.
We've made pom.xml files for each jar file that declare the groupId, artifactId, dependencies, etc. These pom.xml files all have a common parent pom that declares some of the common info (e.g. <repositories> and <distributionManagement>).
I'd like to be able to install or deploy these dependencies with something as simple as mvn install and mvn deploy (or maybe mvn install:install-file and mvn deploy:deploy-file) and have all the necessary properties for these commands (artifactId, repositoryId, etc.) be read from the pom.xml files.
To get this to work, at least for deploying, I tried putting the following in my parent pom:
<build>
<plugins>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.4</version>
<configuration>
<file>${jarfile}</file>
<pomFile>pom.xml</pomFile>
<repositoryId>our-id</repositoryId>
<url>our-url</url>
</configuration>
</plugin>
</plugins>
</build>
and then having each of the child poms define the jarfile property. That allows me to run mvn deploy:deploy-file to deploy all the child pom artifacts. Presumably I could do something similar to get mvn install:install-file to work.
But with this approach, I'm unable to release the parent pom (which I must do since the child poms depend on it), and if I try to mvn release:perform on the parent pom, I get errors like:
Cannot override read-only parameter: pomFile
I feel like I'm probably going about this the wrong way. All I really want to do is:
Put the common code for all the third party jars in one shared parent pom
Write an additional minimal pom for each third party jar
Be able to run something like mvn install or mvn deploy without having to specify all those complicated command line properties
How can I best accomplish that?
Edit: Made it clearer above that ideally I'd like to be able to run something as simple as mvn install or mvn deploy and not have to specify properties on the command line.
When Maven is missing a dependency, it will give you an error in it's output that contains the command line to issue to add the jar to a remote repository. That command line will automatically create a POM for you and upload the two together. Is that not sufficient for your needs?
Using this facility, if I know that I have a dependency with no remote repository representation, I usually just go ahead and define it in my build with the GAV that I want, run the build once, then look at the build errors. Copy out the command for the deployment, then run that command. You'll want to make sure that you have the <repository> elements set up properly in the parent POM plus also set up corresponding <server> elements in your settings.xml with the repository upload password. Other than that, you should be good to go.
I would add that you should check out Nexus before getting to far. It's worth the hassle to set up now! :-)
Ok, I found a solution that allows me to run just mvn install or mvn deploy and have the jar file installed to the local or remote repository. Inspired by a post to the maven-users list and using the build-helper plugin, in the parent pom, I have:
<pluginManagement>
<plugins>
<!-- Attach the jar file to the artifact -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>attach-artifacts</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>${artifactId}-${version}.jar</file>
<type>jar</type>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
And then in the child poms, I have:
<packaging>pom</packaging>
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Some of the pieces of this that initially tripped me up:
The attach-artifact execution should be under <pluginManagement> so it doesn't get executed if you mvn install or mvn deploy the parent pom.
The children need to specify the build-helper-maven-plugin under the build plugins so that code from the parent <pluginManagement> gets run.
The children have to be declared as having <packaging>pom</packaging> because you can't add a jar to an artifact if it has the same name as the artifact.
The only downside I see to this approach is that the artifact gets deployed as type pom instead of type jar. But I haven't seen any real consequences of that.
I meet this problem in my work:
Now I have a target.jar (it has a dependencies list : a.jar, b.jar, c.jar...), I want to use mvn install:install-file to put it into my local repo, but when I run the command blow
mvn install:install-file -Dfile=/Users/username/.../target.jar -DgroupId=com.cnetwork.relevance -DartifactId=target -Dversion=1.0.0
but when I use it I found there are many error, the jar which use target.jar cannot find a.jar, b.jar, c.jar, such as:
com.cnetwork.a does not exist
com.cnetwork.b does not exist
com.cnetwork.c does not exist
Then I went to ~/.m2/repository/.../target/1.0.0/target.pom to find the pom file of the target, but nothing in it!
...
<groupId>com.cnetwork.relevance</groupId>
<artifactId>target</artifactId>
<version>1.0.0</version>
....
# no dependencies about a/b/c.jar !!!
This is what going wrong, the install:file -Dfile -DgroupId -D.. does not add dependencies into pom, I correct the answer by this method
if you already have this maven project source, just install it into local repo
mvn clean install
if you have the jar and the pom of it, install jar with pom
mvn install:install-file -Dfile=/.../.../target.jar -DpomFile=/.../../target.pom
if you don't have a pom with target jar, write one and use upper command.
if you cannot recover the pom file of it, may be you should give up.