What does the --projects flag do in Maven? - maven-2

I have a Maven project which has many a set of customer-specific modules of which one is used. The command to execute this build is as follows:
mvn clean install --projects [targetModule] --also-make
Normally I would use profiles to configure module selection and it appears that the end result is similar in this case. I cannot seem to find any documentation on this --projects flag and its semantics which is making me hesitant to specific a different set of modules. Does anyone know how --projects and/or --also-make works or where I might find documentation on them?

mvn --help gives some information regarding this.
-am,--also-make If project list is specified, also
build projects required by the
list
-pl,--projects <arg> Build specified reactor projects
instead of all projects

Related

How can I tell Hudson to build the modules instead of the jobs?

I have a alot of jobs on Hudson, most of which are really small and consist of just a few modules. But one is big and consist of several modules.
When ever I make a commit to our subversion repository for any of those several modules in that big job, Hudson builds the entire job instead of just the module that have changed.
It doesn't matter if I just scm-polling or a subversion hook, the result is the same.
It seems to me like it would be better if the modules where built instead of the jobs since the other modules in other jobs have dependencies to the modules and not to the jobs.
Can this be configured or do I have to create several jobs instead of the big one? And if so, can I configure the big job to never build when any of it's modules are being triggered but still build when it's own pom.xml is changed?
Thanks.
Hudson has an "Incremental Build" option in the Maven area of the job configuration.
It's hidden in the "Advanced" area.
You could make use of the reactor plugin. For example:
mvn reactor:make-scm-changes
This will only build those modules that have been changed in the SCM. Follow the link for other examples.
Doesn't your compiler offers you the incremental compile option? The java 1.6 compiler usually searches for class and source files and decides using the timestamp to determine whether to use the source or class file. Just leave out the clean goal when building your code.
Another option would be to first run a batch/shell script to determine what files changed and delete the corresponding class files so that the compiler incrementally builds the class files that are missing.

How to configure Apache Buildr to use the same directories as Maven?

By default, Buildr produces output in slightly different places than Maven's default. For example, it puts test classes in target/test/classes instead of target/test-classes, reports in reports/ instead of target/surefire-reports, and JavaDoc into target/doc instead of target/site/apidocs.
Is there a list of all such differences, and how to configure Buildr to use the same output directories as Maven? Would that even be safe to do, e.g., if there is a parallel Maven project that is being migrated from provided that the two never run simultaneously?
You can configure buildr to use different directories from the defaults.
It doesn't seem to me temporarily having both maven and buildr builds in the same directories would cause any problems, but I've never tried it myself. Certainly any problems would be resolvable with a clean build.

QuickBuild: How can I create a builder to open a tarball package (tar.gz) whose name will change with each version?

I'm using PMEase QuickBuild to perform automated builds of our Maven2 projects and a nightly sanity test to ensure nothing is broken.
The test needs to untar packages which are created by the automated Maven2 projects. The problem is that the package names change frequently due to project versions being incremented all the time.
Does anyone know how I can configure QuickBuild to pick up the version (ideally from the POM file of the individual components), if this is possible at all?
I don't know if this is an option for you but it looks like you can do it the other way around. Quoting Build with Maven:
Control build version
If you want to control the build
version from QuickBuild side, please
follow below steps:
Change the POM file and define the project version as
${buildVersion}. Do not forget to
commit the file into your SCM after
change.
Define a build property like below when define the Maven build
step:
buildVersion=${build.version}
There are maybe other options but I must admit that my knowledge (zero) of QuickBuild is very limited
I created a work around to this issue by having QuickBuild execute a shell script which did the untarring by using wildcards, similar to the following (to avoid computing the exact version):
tar xzf filename-*.tar.gz
I couldn't figure out how to do this in QuickBuild, so I offloaded the work to the shell script.

Maven - installing artifacts to a local repository in workspace

I'd like to have a way in which 'mvn install' puts files in a repository folder under my source (checkout) root, while using 3rd party dependencies from ~/.m2/repository.
So after 'mvn install', the layout is:
/work/project/
repository
com/example/foo-1.0.jar
com/example/bar-1.0.jar
foo
src/main/java
bar
src/main/java
~/.m2/repository
log4j/log4j/1.2/log4j-1.2.jar
(In particular, /work/project/repository does not contain log4j)
In essense, I'm looking for a way of creating a composite repository that references other repositories
My intention is to be able to have multiple checkouts of the same source and work on each without overwriting each other in the local repository with 'install'. Multiple checkouts can be because of working on different branches in cvs/svn but in my case it is due to cloning of the master branch in git (in git, each clone is like a branch). I don't like the alternatives which are to use a special version/classifier per checkout or to reinstall (rebuild) everything each time I switch.
Maven can search multiple repositories (local, remote, "fake" remote) to resolve dependencies but there is only ONE local repository where artifacts get installed during install. It would be a real nightmare to install artifacts into specific locations and to maintain this list without breaking anything, that would just not work, you don't want to do this.
But, TBH, I don't get the point. So, why do you want to do this? There might be alternative and much simpler solutions, like installing your artifacts in the local repository and then copying them under your project root. Why wouldn't this work? I'd really like to know the final intention though.
UPDATE: Having read the update of the initial question, the only solution I can think of (given that you don't want to use different versions/tags) would be to use two local repositories and to switch between them (very error prone though).
To do so, either use different user accounts (as the local repository is user specific by default).
Or update your ~/.m2/settings.xml each time you want to switch:
<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
http://maven.apache.org/xsd/settings-1.0.0.xsd">
<localRepository>${user.home}/.m2/repository</localRepository>
<!--localRepository>${user.home}/.m2/repository2</localRepository-->
...
</settings>
Or have another settings.xml and point on it using the --settings option:
mvn install --settings /path/to/alternate/settings.xml
Or specify the alternate location on the command line using the -Dmaven.repo.local option:
mvn -Dmaven.repo.local=/path/to/repo
These solutions are all error prone as I said and none of them is very satisfying. Even if you might have very good reasons to work on several branches in parallel, your use case (not rebuilding everything) is not very common. Here, using distinct user accounts migh be the less worse solution IMO.
This is INDEED possible with the command line, and in fact is quite useful. For example, if you want to create an additional repo under your Eclipse project, you just do:
mvn install:install-file -DlocalRepositoryPath=repo \
-DcreateChecksum=true -Dpackaging=jar \
-Dfile=%2 -DgroupId=%3 -DartifactId=%4 -Dversion=%5
It's the "localRepositoryPath" parameter that will direct your install to any local repo you want.
I have this in a batch file that I run from my project root, and it installs the file into a "repo" directory within my project (hence the % parameters). So why would you want to do this? Well, let's you say you are professional services consultant, and you regularly go into customer locations where you are forced to use their security hardened laptops. You copy your self-contained project to their laptop from a USB stick, and presto, you can do your maven build no problem.
Generally, if you are using YOUR laptop, then it makes sense to have a single local repo that has everything in it. But to you who got cocky and said things like "why would you want to do that", I have some news...the world is a bigger place with more options than you might realize. If you are using laptops that are NOT yours, and you need to build your project on that laptop, get the resulting artifact, and then remove your project directory (and the local repo you just used), this is the way to go.
As to why you would want to have 2 local repos, the default .m2/repository is where the companies standard stuff goes, and the local "in project" repo is where YOUR stuff goes.
This is not possible with the command line client but you can create more complex repository layouts with a Maven repository server like Nexus.
The reason why it's not possible is that Maven allows to nest projects and most of them will reference each other, so installing each artifact in a different repository would lead to lots of searches on your local hard disk (or to failed builds when you start a build in a sub-project).
FYI: symlinks work in Windows7 and above so this kind of thing is easy to achieve if all your code goes in the same place in the local repo, i.e /com/myco/.
type mklink for details
I can see that you do not want to use special versions or classifiers but that is one of the best solutions to solve this problem. I work on the same project but different versions and each mvn install takes half an hour to build. The best option is to change the pom version appended with the change name, for example 1.0.0-SNAPSHOT-change1 that I'm working on thereby having multiple versions of the same project but with different code base.
It has made my life very easy in the long run. It helps run multiple builds at the same time without issues. Even during SCM push, we can skip the pom file from staging so there can always be 2 versions for you to work on.
In case you have a huge project with multiple sub-modules and want to change all the versions together, you can use the below command to do just that
mvn versions:set -DnewVersion=1.0.0-SNAPSHOT-change1 -DprocessAllModules
And once done, you can revert using
mvn versions:revert
I know this might be not what you are looking for, but it might help someone who wants to do this.

How to display a list of available goals?

I'm rather new to Maven and I often find myself wanting to see what's actually there in terms of goals.
So, is there a command which lists all available goals for e.g. a given prefix?
Since Maven is an open system of plugins, the best answer is probably "Google" ;-). If you mean all build lifecycle phases, they are static, and can be found at http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html and at other places.
Then, for a given plugin, the help plugin can be used to get the possible goals and all their parameters:
mvn help:describe -DgroupId=org.apache.maven.plugins \
-DartifactId=maven-war-plugin \
-Ddetail=true
But this doesn't really answer your question, especially the "for a given prefix" part. For this, the best solution might be to use **auto completion with BASH (**not sure it will be exhaustive though). See for example the Guide to Maven 2.x auto completion using BASH. To get bash completion working under Windows, you'll need CYGWIN. See Maven Tab Auto Completion in Bash for detailed setup steps (and a "better" working auto completion script).
A shorter way
As an alternative, you can also use the -Dplugin parameter to display the list of available goals.
mvn help:describe -Dplugin=org.apache.maven.plugins:maven-war-plugin\
-Ddetail=true
See Maven help plugin.
More and more Maven plugins propose an help goal as alternative to the verbose
mvn help:describe command.
You can read from the Maven doc:
Recent Maven plugins have generally an help goal to have in the
command line the description of the plugin, with their parameters and
types
That is really more natural and pleasant to use.
It works of course for Maven core plugins.
Some examples :
to list goals of the dependency plugin :
mvn dependency:help
to have detail about the javadoc goal of the javadoc plugin :
mvn javadoc:help -Ddetail -Dgoal=javadoc
And it works also for third party plugins.
For example, to list goals of the spring-boot-maven-plugin :
mvn org.springframework.boot:spring-boot:help
[INFO] Spring Boot Maven Plugin 2.0.0.RELEASE Spring Boot Maven
Plugin
This plugin has 6 goals:
spring-boot:build-info
Generate a build-info.properties file based the content of the
current MavenProject.
spring-boot:help
Display help information on spring-boot-maven-plugin. Call mvn
spring-boot:help -Ddetail=true -Dgoal= to display
parameter details.
spring-boot:repackage
Repackages existing JAR and WAR archives so that they can be
executed from the command line using java -jar. With layout=NONE can
also be used simply to package a JAR with nested dependencies (and
no main class, so not executable).
.....
Or to get detailed information about the build goal of the dockerfile-maven-plugin :
mvn com.spotify:dockerfile-maven-plugin:help -Ddetail -Dgoal=build
[INFO] Dockerfile Maven Plugin 1.3.6
Adds support for building Dockerfiles in Maven
dockerfile:build
Available parameters:
- archive
The archive configuration to use for the Docker info JAR. This can be used
to embed additional information in the JAR.
....
You could note that the syntax to get a detailed output of the help and to focus on a specific goal (-Ddetail -Dgoal=myGoal) is exactly the same as this used for the core maven plugins.
Of course some esoteric plugins may not provide the help goal but in most of well designed plugins this is present.