How to create a custom lifecycle mapping to facilitate releases - maven

I've been working with the release plugin, but am trying to automate its solution a little for our needs.
At the moment, all our builds run the following command:
mvn clean initialize release:prepare release:perform
While that's functional, it's not as concise as I would like it. I have a few plugins defined in my super-pom which are activated during the initialize phase and are required before the release plugin is run. Ideally, I would like to see my command as something like:
mvn doMyRelease
which in turn calls the necessary phases/goals of the different plugins.
Additionally, I'd like to create a phase called doMyStage which would do the following:
mvn clean initialize release:prepare release:stage
I figure that a custom plugin with a custom lifecycle is the way to go about this, but I am confused how to accomplish this. From what I read, the lifecycle is mapped to the packaging type. I do not wish to change the packaging type of any of my projects (as their packaging remains correct), but rather just provide a shortcut for the build command line.
I'm also having trouble finding a good tutorial/working maven 3 example for this concept. Most examples I see all refer to a components.xml file, but I read that this has been replaced with a default-bindings.xml descriptor in Maven 3.
I found this article https://developer.jboss.org/wiki/CreatingaCustomLifecycleinMaven?_sscc=t which touches a little on the issue, but like most examples, it requires changing the packaging type to match the lifecycle hint.
Is there a way to accomplish this?

Related

Maven module dependency source instead of repository jars

I have a multi-module project, i.e.
parent
module1
module2
In one dev cycle, I added a class mod1.A to module1. Class mod2.B in module2 depends on it.
I do not have the artifacts in my local .m2/repository. Running this:
$ cd prj/module2
$ mvn -o exec:java -Dexec.mainClass=mod2.B
results in an error along the lines of:
The following artifacts could not be resolved: com.example:module1:jar:1.0-SNAPSHOT
After I install the artifacts via mvn install while in the prj folder, it all works as expected.
However, this presents an issue in at least two ways:
I have to go through the slower install phase instead of the faster compile phase
I have two versions of the same project and conflicting modifications in these. I cannot run the same Java class with their respective modifications, only the currently installed modifications, considering they are both the same SNAPSHOT version
There are workaround for both (skip parts of the build for the first, different snapshot versions for the second), but they are far from usable in practice.
Is there a way to make maven use the local modules, instead of using artifacts from local maven repository?
If I understand your question correctly, it seems like you are living a bit outside the norm here: you have two local "copies" of the project with different modifications, that you want to work with alternately when running "exec:java". And Maven is getting in your way: it expects your local .m2 repository area to be in play, but the version strings in each copy are the same, so you end up with the changes interfering among the copies.
To me, it sounds like what you are trying to do is to test your changes. I suggest you just write an actual JUnit or TestNG test in module2 that tests what you want (it can just call mod2.B Main if you want). Then, from your chosen project directory, you can run mvn test -Dtest=MyTestName. It won't "install" anything and it will find the dependencies the way you want it to.
Otherwise, I can see three options.
Change the version string locally in one of the copies (mvn versions:set -DnewVersion=B-SNAPSHOT can do this for you). That way any "installed" jars from your work on that copy will not be considered by the other copy, and vice-versa. You refer to this as being "far from usable" ... I think it should be fine? These are different versions of the project! They should have different version strings! I strongly recommend this option out of the three. (You can do mvn versions:revert when done if you used :set, or you can rely on version control to undo the change.)
Select a different local repository used by Maven when working on one of the projects, with a command-line flag as per https://stackoverflow.com/a/7071791/58549. I don't really think this is a good solution, since you would have to be very careful about using the right flags every time with both projects. Also you'd end up having to re-download Maven plugins and any other dependencies into your new local repository anyway, which is kind of a waste of time.
Try to avoid using any local repository at all. You seem to be trying to make this option work. I don't think this is a great approach either; you're fighting against Maven's expectations, and it limits your flexibility a lot. Maven will indeed find dependencies from the "reactor" (i.e., the executing mvn process) first, but this means all of the required modules must be available in the reactor to be found, which means you can only run mvn at the top level. So if instead you want to just do "mvn exec:java" inside a single module, mvn needs to find that module's dependencies somewhere ... and that's what the local repo is generally used for.
If you're dead set on going with option 3 (instead of option 1), then I suggest you follow the comments on your question and create a profile that runs your exec selectively against module2 and binds it to a lifecycle phase. But this is in practice very close to just wrapping it with a test.
For IntelliJ users:
I solved this problem using IntelliJ's Run configuration. It has the options Resolve workspace artifacts and Add before launch task -> Build. See this picture for clarification:
Run configuration example
The whole point of modules in Maven is to create decoupling between them. You either build each module independently, so that you can work on one module without touching the other, or include both modules as sub-modules in the parent pom and build the parent, which will resolve dependencies between its sub-modules and trigger their builds.
It looks like you have two options here:
Review the structure of your project. Do you really need to split it into two separate modules, if you change code in both of them simultaneously?
Import the project into a Maven-aware IDE (IntelliJ IDEA is very good at working with Maven), and let the IDE handle the compilation. Once finished and stabilized the code-base, build normally with Maven.

How to skip a maven build step without modifying the pom itself?

We have a maven based Java EE project controlled by the customer. For internal reasons, we cannot execute one of the build steps, but the rest works fine and produces the jar we want.
Since editing the pom file would require taking care when committing to customer's SVN and copying the pom file would require taking care to sync changes comming from there, we are looking for a way to skip this specific step in the build section during the maven call itself, so to say mvn clean install but-leave-out-this-build-plugin-step, is there any?
Edit:
The plugin in question is the rpm-maven-plugin, which prevents the build from running on Windows. We found information how to make it work which won't really fit in our current setup. And since we cannot modify the customer's pom, I was looking for a way to trigger the skipping externally. But maybe there are other ways to just ignore/skip/fake this step?
It depends on what plugin you want to skip. Many plugins have ability to be skipped via system property (-Dblabla).
For deploy plugin it is -Dmaven.deploy.skip=true, for surefire -DskipTests=true.
Read plugin documentation, maybe you can find skip property
The rpm plugin hase a property disabled, unfortunately it is not accessible by a property. So, if setting this property in the customer's pom (or asking for editing it) with a default value of false is an option, this may be the solution.

mvn --resume-from downloads snapshots

I have a multi-module maven project with 5 modules. The modules are tiered such that a few depend on the first that builds (it's my model classes) and some depend on the second ones that build (those are core application classes). The final one that builds is a Spring WebMVC app which depends on all the other modules.
The problem I'm having is in Maven's --resume-from flag. It apparently doesn't do what I want. I must me misunderstanding what the word "resume" means in this context as I would expect it to, well, resume something.
If I run mvn verify and it fails at the rest-api sub-module, it tells me I can resume by running mvn --resume-from :rest-api verify. When I do that though, it downloads snapshots of the other modules from my project which rest-api depends on. That is so incredibly not what I want that it's comical. I wanted it to re-use the in-place jars it just built like 5 seconds ago inside this local checkout of the project!
Does anyone know what the nature of my misunderstanding is here? Am I misusing inter-module dependencies? Am I totally misunderstanding what --resume-from means? Is there some other argument to do what I want?
Use mvn install instead of mvn verify, as only after the install phase, Maven will be able to pull it from your local repo.
You probably also want the --also-make-dependents option.
See this blog for the full story.

maven lifecycle configuration

I'm playing with maven plugins, specifically i'm trying to develop a custom maven plugin for eclipse. All goes well, it builds from console ... etc until:`
"Plugin execution not covered by lifecycle configuration"
appears. I research and find this:
http://wiki.eclipse.org/M2E_plugin_execution_not_covered;
obviously i do not want to ignore the plugin's execution, the execute instruction does not seem to work, as for the delegate to project configurator, i am not able to find
AbstractJavaProjectConfigurator.java.
I've searched in org.eclipse.jdt , core and source but there is no reference to what i am searching, best match i could find was here:
http://git.eclipse.org/c/m2e/m2e-core.git/tree/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt
All in one, what i want to achive is this: "Starting with m2e 1.1, maven plugin developers are able to provide lifecycle mapping metadata as part of the plugin itself." as stated in the first link i inserted. Any help would be greatly appreciated.
To simply bypass the mojo execution or telling m2e to simply execute your mojo via maven embedder you need the following:
a proper lifecycle mapping as explained in your link. Reference: https://github.com/php-maven/maven-php-plugin/blob/master/ide-plugins/eclipse/tags/2.0.3/org.phpmaven.eclipse.core/lifecycle-mapping-metadata.xml
However I put it in the root of the eclipse project to be able to debug it (finding those extra resources sometimes failes if you put them in src folders).
A build properties to embedd it into build: https://github.com/php-maven/maven-php-plugin/blob/master/ide-plugins/eclipse/tags/2.0.3/org.phpmaven.eclipse.core/build.properties
Activation via dependencies and extension:
Hope this helps. I was confused about the project configurator too. But the above example does not require any project configurator.

maven - choose plugin phase from command line

i'm not a maven expert. in my maven2 project i have a couple of report plugins (dependency, tattletale etc). some of them are bound to 'pre-site' phase, some to 'site' phase. this way i have a nice report on my site.
but sometimes, when tests don't pass i need this report to check what's wrong. is there any way to run the same plugins (in correct order) after compile or even after dependency resolution? i just want to skip all the findubs, checkstyle etc that are run at site phase and quickly have this single report to check why my project doesn't compile or why tests fail
i'm looking for something like:
mvn -P tattletale-report compile
but any other reasonable way will do
I don't know this plugin in particular but calling goals on the jetty plugin, it works with
mvn jetty:run-exploded
to give an example. Not knowing the plugin, i'd said
mvn tattletale:report
should work. Usually the plugin documentation should give you the right goals and commands. But hacking some words in Google, it appears to be a little more complicated.

Resources