Is there "skip weaving flag" in Maven? (exclude AspectJ) - performance

I build our multi-project application with Maven(lots of pom.xml-s). We recently introduced AspectJ, however I suspect AspectJ contributes to performance problems. In order to be sure, I'd like to build the application this time without AspectJ and see how it performs. But I would not really like to remove all AspectJ related stuff from pom.xml, so it would be handy if there was some kind of flag or something that could exclude AspectJ from build. Is there any?
Update: this does not seem to have any effect: -Dmaven.aspectj.skip=true

If you want to disable the aspectj-maven-plugin temporarily, you could add a profile to the parent pom.xml which deregisters the executions of the plugin (by assigning them to phase none). Could look like this (add your own execution IDs if you have some):
<profile>
<id>noAspectJ</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<executions>
<execution>
<id>compile</id>
<phase>none</phase>
</execution>
<execution>
<id>test-compile</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
A simple maven cmd activates this:
mvn clean install -PnoAspectJ

Related

Remove -SNAPSHOT from project version in pom

I have a pom with the following GAV
<groupId>com.company.services</groupId>
<artifactId>test-branch-2</artifactId>
<version>1.0.21-SNAPSHOT</version>
I want to remove -SNAPSHOT from this using maven in batch mode, so I can do it with Jenkins and not have to specify anything manually.
I've looked at the documentation for version:set but all the options offer me an interactive prompt and ask me to type a name for the version.
I would prefer the versions plugin, not the release plugin.
Since version 2.10 of the Versions Maven Plugin you can simply do:
mvn versions:set -DremoveSnapshot
If you really don't want to use the Maven Release Plugin (for whatever reason), here is how I succeed on dropping the SNAPSHOT suffix (hanbdled as a classifier) from a maven POM in a standard way (that is, no scripting, no custom maven plugin).
Given the following profile:
<profile>
<id>drop-snapshot</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.11</version>
<executions>
<execution>
<id>parse-version</id>
<phase>validate</phase>
<goals>
<goal>parse-version</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<id>set-version</id>
<phase>validate</phase>
<goals>
<goal>set</goal>
</goals>
<configuration>
<newVersion>${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}</newVersion>
</configuration>
</execution>
<execution>
<id>upgrade-pom</id>
<phase>validate</phase>
<goals>
<goal>commit</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
And simply executing: mvn validate -Pdrop-snapshot
The version of an example pom passed from 0.0.1-SNAPSHOT to 0.0.1.
How it actually works:
The build-helper-maven-plugin, parse-version goal, will parse the current version of the POM and set it in a set of properties having by default parsedVersion as a prefix and majorVersion, minorVersion, incrementalVersion as suffixes (check the documentation, you will also have classifier and buildNumber). Hence, after its execution we can then use in our POM the properties like ${parsedVersion.majorVersion} and so on.
The versions-maven-plugin, set goal, will then use these properties to build the new version you actually want (in this case dropping the SNAPSHOT, because we excluded the ${parsedVersion.classifier} property).
Lastly, the versions-maven-plugin, commit goal, will make these changes effective.
Similar to A_Di-Matteo's approach with build-helper, but without the need for additional plugins configuration:
mvn build-helper:parse-version versions:set \
-DnewVersion=\${parsedVersion.majorVersion} \
.\${parsedVersion.minorVersion} \
.\${parsedVersion.incrementalVersion \
.\${parsedVersion.buildNumber} \
versions:commit
This will replace your 1.0.0.0-SNAPSHOT with 1.0.0.0 in the pom.xml.
Add the following to your POM:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.11</version>
<configuration>
<name>newVersion</name>
<value>${project.version}</value>
<regex>-SNAPSHOT</regex>
<failIfNoMatch>false</failIfNoMatch>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>2.2</version>
</plugin>
</plugins>
</build>
You can now remove the -SNAPSHOT part of your project's version with:
mvn build-helper:regex-property versions:set -N
The -N tells Maven to only proces the root project in case you have modules defined in your POM. This is not strictly necessary but prevents the build-helper plugin from running unnecessarily against the submodules. The versions plugin runs only on the root project in any case, and traverses all modules automatically. Consider using the reactorModuleConvergence rule of the maven-enforcer plugin to make sure multi-module projects are handled correctly.
You can run mvn versions:commit to remove the backup POM(s) generated by versions:set. Alternatively you can add <generateBackupPoms>false</generateBackupPoms> to the configuration of the versions plugin.

Is it possible to specify a dependency on a particular maven phase?

I am using the maven-docbkx-plugin to generate HTML and PDF output from docbook sources. I have several books, and these link to each other using olinks.
The olink database is generated in one maven phase (generate-resources), and the actual HTML and PDF generation, which looks up this database is executed in a subsequent maven phase (compile).
I have divided the maven project into a multi-module project, as each book has tens of included sub-documents. The docbkx-maven-plugin configuration is all done in the parent, then it is just the top-level docbook source that needs to be specified in the child POM.
But ... this does not work dependency-wise, as each module requires that the generate-resources of every other module has been run before it runs its compile phase, so that it can access the olink database of each of the other books.
Is there a way to do this in maven? Or will I need to re-structure into two maven projects (which will break the modularity of this project considerably, as all of the configuration will need to be declared in each project)?
The structure of the parent POM is:
...
<build>
<plugins>
<pluginManagenent>
<plugin>
<groupId>com.agilejava.docbkx</groupId>
<artifactId>docbkx-maven-plugin</artifactId>
<version>2.0.14</version>
<executions>
<execution>
<id>xrefdb</id>
<phase>generate-resources</phase>
<configuration>
...
</configuration>
<goals>
<goal>generate-html</goal>
</goals>
</execution>
<execution>
<id>html</id>
<phase>compile</phase>
<configuration>
...
</configuration>
<goals>
<goal>generate-html</goal>
</goals>
</execution>
</executions>
</plugin>
</pluginManagement>
</plugins>
</build>
</project>
And the modules:
<project>
...
<build>
<plugins>
<plugin>
<groupId>com.agilejava.docbkx</groupId>
<artifactId>docbkx-maven-plugin</artifactId>
<version>2.0.14</version>
<configuration>
...
</configuration>
</plugin>
</plugins>
</build>
</project>
I've done a bit more research on this, and from what I have read, what I am asking is not possible (but I would be happy to be advised otherwise). I have split my project into two, and given them a common parent from which they can draw their common configuration.
Another way I've solved this problem is to use maven profiles. I perform the first pass of all the modules in the first profile, then perform the second pass in a second profile.
It means the project has to be run twice to build all of its artifacts, but it is much more maintainable than spreading the sources over multiple projects.

maven release:prepare junit

I have a need to only run a specific jUnit when the mvn release:prepare is executed. I don't want this to run under mvn install or any other goal as this jUnit is designed to see if the developer has executed a database activity first.
Is there any way to either have the junit know, by parameter(?), that the process under execution is release:prepare?
Or, is there a way to define within the pom.xml that this jUnit only runs on that goal?
I've been doing some searching on this and I cannot seem to find a solution as I'm not that good at maven as of yet. Any help is appreciated!
I haven't done exactly what you want but the key is to use the <executions> section under the SureFire :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
... exclude the test from normal execution ...
</configuration>
<executions>
<execution>
<id>release-phase</id>
<phase>release-prepare</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
... fill this in to include the tests you want ...
</configuration>
</execution>
</executions>
<plugin>
You will also want to exclude that test in the normal <configuration> section.
There is some related information HERE
Others are close... but no cigar.
When Maven runs a release, there are no special phases for the release process. What you want to do is add a profile that is configured to include the test you want, e.g.
<profiles>
<profile>
<id>release-preflight-checks</id>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>release-preflight-checks</id>
<goals>
<goal>test</goal>
</goals>
<configuration>
.. include your test here
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
Then you need to configure surefire by default to not execute your preflight check
<build>
<plugins>
...
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
.. exclude your test here
</configuration>
</plugin>
...
</plugins>
</build>
And then finally, you need to tell Maven that this profile should be active only during release:prepare's forked execution
<build>
<plugins>
...
<plugin>
<artifactId>maven-release-plugin</artifactId>
<configuration>
...
<preparationGoals>clean verify -P+release-preflight-checks</preparationGoals>
...
</configuration>
</plugin>
...
</plugins>
</build>
Note: it is vitally important to have the + in front of the profile name so that you are adding the profile to the list of active profiles otherwise your release:prepare step will not be validating that the build works with the release profile active and you can have a subsequent release:perform fail.
Note: A less complex route would be to just put the surefire configuration into the release profile that you are using (by default that has the id of release but that is more error prone as you could change that via the parent pom - e.g. if you decide to push your project to central, the sonatype-oss-parent changes the release profile to sonatype-release - and then you won't see the build being failed as the test would not be executed until you change your pom to match new the release profile's id... using the -P+release-preflight-checks ensures that the profile is always active for release:prepare and additionally has the benefit of meeting the requesters original requirement completely - i.e. only runs for release:prepare and doesn't run for release:perform which would be the case if the execution was added to the release profile)

How do I disable the maven-compiler-plugin?

I have a maven project that uses the aspectj-compiler-plugin. I use intertype declarations so there are references to Aspect code in my Java code. Because of this, the maven-compiler-plugin fails to compile since it does not compile the aspect code.
My question is: how do I disable the maven-compiler-plugin from running because it is not doing anything useful?
There are several ways that I can get this project compiling, but they are sub-optimal:
Add exclusion filters to the maven-compiler-plugin. The plugin will still run, but it will not try to compile anything. Problem is that this breaks the ajdt project configurator in Eclipse
Move all java code to the aspectj folders. This doesn't feel right either.
You can disable the a plugin by set the phase of the plugin to none.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>default-compile</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
In Maven 3, the following will do this, for example disabling the clean plugin:
<build>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>2.4.1</version>
<executions>
<execution>
<id>default-clean</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
The same technique can be used for any other plugin defined in the super-POM, the packaging type, or the parent POM. The key point is that you must copy the <id> shown by help:effective-pom, and change the <phase> to an invalid value (e.g. "none"). If you don't have the <id> (as e.g. in Jintian DENG's original answer – it has since been edited to add one), it will not work, as you have discovered.
Either configure the skipMain parameter:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<skipMain>true</skipMain>
</configuration>
</plugin>
</plugins>
</build>
Or pass the maven.main.skip property:
mvn install -Dmaven.main.skip=true
The reason maven-compiler-plugin executes in the first place is because you trigger one of the default lifecycle bindings. For example if you're packaging jar using mvn package, it will trigger compile:compile at compile phase.
Maybe try not to use the default lifecycle, but use mvn aspectj:compile instead.
http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html has more information about maven default lifecycle bindings

Plugin.xml configuration of phase doesn't seem to work for my custom maven plugin

I'm playing around with writing a maven plugin for the first time. I've written a simple plugin with a goal that writes a hello world message to the output. I've also used the #phase annotation to create a default binding to the install lifecycle phase. This shows up in my plugin.xml as install element of my mojo element.
My understanding is that I can now simply add this to my build.plugins section, without specifying any execution, and my plugin goal will execute during the install phase. This doesn't happen though. Here's the configuration that doesn't create any exeuction of my goal:
<build>
<plugins>
<plugin>
<groupId>com.emc.chad</groupId>
<artifactId>hello-plugin</artifactId>
<version>0.0.1-SNAPSHOT</version>
</plugin>
</plugins>
</build>
However, if I change this to specify an execution explicitly, it works:
<plugin>
<groupId>com.emc.chad</groupId>
<artifactId>hello-plugin</artifactId>
<version>0.0.1-SNAPSHOT</version>
<executions>
<execution>
<id>test</id>
<phase>install</phase>
<goals>
<goal>hello</goal>
</goals>
<configuration>
</configuration>
</execution>
</executions>
</plugin>
I understand why this works of course, but shouldn't the first work as well, considering my plugin.xml phase specification?

Resources