How to skip building of the pom in multi-module project - maven-3

I'm trying to optimize my build process (in development) in term of time to build the whole tree of maven multi-module project. Some of the POM are actually aggregation of sources/libraries that rarelly (and typically) never change. So specific sub-questions are
Is it possible to somehow configure maven to not build pom if there are no changes in sources specified in POM:project/build/sourceDirectory attribute?
Or is it possible to (at least) conditionally disable maven-bundle-plugin? - it takes most of the time.
Google could not find anything relevant Q#1. Typical solution does not work for #2 - when i try to specify 'executions' for maven-bundle-plugin (like this)
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>${maven-bundle-plugin.version}</version>
<extensions>true</extensions>
<executions>
<execution>
<id>osgi-bundle</id>
<phase>bundle</phase>
<goals>
<goal>bundle</goal>
</goals>
i receive this error in output
[bundle:bundle]
Bundle artifact-id:bundle-id:bundle:0.1.0-SNAPSHOT : The JAR is empty: dot
Error(s) found in bundle configuration
Any help is appreciated. I'm aware about following:
* Disable a Maven plugin defined in a parent POM
(maven-bundle-plugin can't work with 'executions' tag)
* Skip execution of a maven plugin if a file does not exist (maven-bundle-plugin does not have skip confiuration option)
* How to skip lifecycle phase in multi maven module (the same as previous)
* If entire maven-bundle-plugin is moved into profile, maven does not recognize packaging=bundle.

Finally I have to admit that (C) Eugene Kuleshov - "Maven generally don't track sources/changes, so it is always a full build."
But, returning back to Java after 5+ on .NET and 5+ years erlier on C++, it looks weird for me that such a common feature like incremental build is not support by widely used tool having a history of 10+ years. So I could not spend my time on waiting to rebuild each and every unchanged module in my multi-module project and decided to make customized version of Maven 3.0.4 :)
Feel free to grab it here http://code.google.com/p/maven-onchange-activator/, try and report issues.

Maven generally don't track sources/changes, so it is always a full build. However to disable any plugin you could move it into profile and then enable/disable the whole profile, e.g. either conditionally or from the command line.

You should check things like
mvn -am
in relationship with
mvn -pl ...
so doing a build like:
mvn -am -pl SubModule clean package
will build only those modules which have been changed and which needed to be built as a result of a dependency to the change module.

I would suggest switching to Gradle.
Gradle has such support out of the box (no configuration needed) and conversion from Maven should be easy.

Related

Jenkins: maven release plugin ignores dependency classifier

I want to release a module via Jenkins that uses a dependency which is not only distinguished by its version but also by a custom classifier passed as a system property at build time. The effective pom printed in the console output shows that the correct classifier is used
<dependency>
<groupId>de.test</groupId>
<artifactId>common-module</artifactId>
<version>0.0.4-SNAPSHOT</version>
<classifier>custom</classifier>
<scope>provided</scope>
</dependency>
However, when the release plugins' prepare goal runs, the build breaks due to a compilation error because of missing classes which are only available in the dependency version that uses the custom classifier. Printing the properties with the maven-antrun-plugin reveals that the release plugin is using the version without classifier.
[INFO] [echoproperties] de.test\:common-module\:jar=/var/lib/****/.m2/repository/de/test/common-module/0.0.4-SNAPSHOT/common-module-0.0.4-SNAPSHOT.jar
[INFO] [echoproperties] maven.dependency.de.test.common-module.jar.path=/var/lib/****/.m2/repository/de/test/common-module/0.0.4-SNAPSHOT/common-module-0.0.4-SNAPSHOT.jar
I would expect the release plugin to pickup the jar named common-module-0.0.4-SNAPSHOT-custom.jar which is definitely available in the maven repository. Doesn't the release plugin support classifiers?
Problem solved. I found out that there are two issues. First, the module was also part of a transitive dependency, so maven tried to download a version without classifier that doesn't exist prior to the version containing the classifier. Second, the classifier was not passed to the maven release plugin. To pass system variables to the plugin one has to use the arguments option, so the actual command should be clean install -Darguments="-Dmy-classifier=custom" -Dmy-classifier=custom -B release:prepare release:perform. The system variable declaration must be redundant, one for the pom dependency and another for the release plugin.

How do I make the compile of one maven 3 project depend on the install of another?

I have a directory with a pom.xml and several subdirectories with their own pom.xml files
One subdirectory is local called thirdparty. It contains several jar files and installs them to the local maven repo when a mvn install is executed. These are needed by the mvn compile phase of the other artifacts. The root pom.xml simply executes the same step on each child pom.xml.
I'd like to modify the root pom.xml so that mvn compile will do an install on the third party folder before executing the other folders. I tried this in the maven-compiler-plugin:
<executions>
<execution>
<id>thirdparty</id>
<phase>install</phase>
</execution>
</executions>
I see nothing in the documentation about specifying a phase in a dependency element.
To make sure I have this straight, it sounds like you have an aggregator pom, AGG, and some submodules, A and B, where A is nothing but some third-party jars that have to be installed in the local repo before B will compile. If that's true, then two possibilities spring to mind:
1) Do away with A and instead install the third party jars into an appropriate standalone repo, like a local Nexus server, and add that repo to your pom. That would be the "Maven" way of doing it.
2) Add a dependency on A to B's <dependencies>. In A, configure the install plugin with an execution per jar that needs to be installed, and bind these executions to the compile phase. Then when you run compile on AGG, it will first run compile on A, which will install all the jars, followed by compile on B. Note that this will have the side effect of producing an A.jar, which will be a dependency of B, because maven assumes that every module produces exactly one artifact of some type. You might be forced to add at least one class or resource so that A.jar can actually be built. Not sure about that one. Alternately, you could experiment with setting A's packaging to "pom".
I believe you are using Maven in a wrong way.
Such kind of 3rd party dependencies should be put to local repository (or your internal Maven repository) before you run the compilation work, and dependencies in your project should be setup accordingly. "Installation of 3rd party artifacts" shouldn't be part of the build process.
And, in Maven world, we rarely have 3rd party libs exists as part of the source code. In fact one of the reason for using Maven is to get rid of such kind of libs in source code.
Sounds like you want a couple of dependancies. Look into the depends element.

Unresolved sibling dependency when building one module

I have a maven multi-module project whose parent POM states:
<modules>
<module>ui</module>
<module>controller</module> <!-- Depends on ui module -->
</modules>
The following runs fine:
project-root> mvn clean package
However problems arise if I try:
project-root/controller> mvn clean package
The error reports the ui artifact as an unresolved dependency.
Yes, I realize that this question has been asked before. However it has no clear answer (the accepted answer for that instance is only a workaround). This behavior is explained away as a difference between dependency resolution and reactor builds. A post about Maven 3 suggests that it is resolved in that released. I am using Maven 3.0.3 and see no relief. Maven 3.0.4's release notes don't suggest a change in this behavior.
How do you handle such a situation? Is the only recourse to do a build from the project-root every time?
The problem you are faced with is that you try to call a build from a sibling, in which case the dependency resolution will be done against your local repository.
There are several solutions to your problem. The first one is to go to your root and do a mvn install. Afterwards, you should be able to go to your controller and do mvn clean package. But I recommend to go to your root and build specifically the controller module:
mvn -pl controller clean package
But the prerequisite is to do an mvn install before that.

Excluding grails-plugin dependencies using the POM

Gents, ladies...
Here is the issue :
I am integrating a grails application within a complex and heterogeneous system that uses maven to build and fetch dependencies.
Fair enough, there are a few different ways to add a plugin, but I would like to have all the dependencies managed by maven, as the conflicts and scopes in the dependency trees would then be solved by maven.
This will install the hibernate plugin at validation time, and resolve its dependencies
<execution>
<id>Hibernate plugin</id>
<phase>validate</phase>
<goals>
<goal>install-plugin</goal>
</goals>
<configuration>
<pluginName>hibernate</pluginName>
<pluginVersion>${grails.version}</pluginVersion>
</configuration>
</execution>
Apparently, there is no way to specify exclusions directly in the execution configuration to prevent it from resolving its dependencies (in the dependencies.groovy script) independently.
I tried
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.11.0.GA</version>
<scope>provided</scope>
</dependency>
The dependency will not appear in the lib dir of the WEB-INF folder in the target build dir. However it is still packaged in the war archive.
Remember the aim is to use maven for all things relating to dependencies.
But anyway since it seems there is no hope of excluding it using the pom, I try using the BuildConfig with :
case Environment.PRODUCTION :
build( "org.grails.plugins:hibernate:1.3.7" ) {
excludes "javassist"
}
break
This was a last resort, and it works. Specifying the build here, will effectively override the dependencies that come from the groovy script.
So my question is, is there anyway to override these dependencies using maven ?
Obviously I verified that the dependency I was trying to scope in provided isn't included anywhere else (it is excluded from grails-gorm).
Is there an easy way to solve this ?
UPDATE :
To prevent the war from resolving jar dependencies, there is a --nojars flag, but the war goal of the grails war mojo doesn't allow the passing of args. The exec mojo does, however there is only one execution spec possible for an instance of this plugin, and no lifecycle phase can be specified for the exec mojo.
I think you were on the right track in your first attempt to mark the dependency as provided. The part that you missed is probably that you did not disable the grails dependency management. You do that by setting pom true in BuildConfig.groovy and remove all other dependencies, like this:
grails.project.dependency.resolution = {
pom true
// inherit Grails' default dependencies
inherits("global") {
}
}
Once this is done, maven will handle all depencencies.
EDIT: I just realized that this was a really old post so pom true may not have been introduced in the Grails version you were using then. I think it came in 2.2 or something like that.

Maven 3.0.3 - how to check dependency conflict reason

Is there an easy way to check what is the reason of dependency conflict in maven 3.0.3? It was easy with maven 2.x by using debug mode (-X switch). Since maven 3.0.3, -X doesn't show dependencies resolution problems.
Maven just produce conflict info without giving the underlying source reason.
With Maven (>= 3.0.0) I use the Sonatype m2eclipse plugin with Eclipse or alternative the latest Spring Tool Suite to graphically visualize the dependency tree and therefore solve any conflict problem. Once the Maven project get imported into the IDE open the POM with the 'Maven POM Editor' and see the 'Dependency Hierarchy' and 'Dependency Graph' tabs.
To import the Maven Project, go to File / Import Project / Maven / Existing Maven Projects.
In order to use your recently downloaded Maven 3.X.Y version instead of the default Eclipse-embedded Maven installation, go to Windows / Preferences / Maven / Installations and Add an external Maven home location. Additionally you shall enable the 'Show advanced tabs in the POM editor' in the section Windows / Preferences / Maven / POM Editor.
For those who use IntelliJ, I recommend Maven Helper plugin. You have a specific section for conflicts, and it even allow you to exclude for resolving conflicts.
In general, you can use mvn dependency:tree > "output.txt" and search in the output file the problematic dependency and see what import it.

Resources