A typical misconception in Maven is that if you want to build a project in a special way, or parameterize it somehow, profiles are the thing for you. My opinion is that..
Profiles are POM smell.
While I know they have their uses, I have abused profiles heavily in the past, and seen others do this too. What might start off as a simple little trick to get some desired build eventually leads to:
The point of a POM is that the output of the build, the artifact, should always be the same thing.
If you want to build *a different thing*, you probably should build another project. Andrew Spencer recently wrote a nice article about best practices in Maven profiles. If you want more advice you should have a look.
An example from the other day: I wanted to build a sub-set of the modules in a rather large multi-module project. In order to speed up the build, I wanted to exclude the modules with static contents (texts and resources):
Instead of making a quickbuild-profile, I made an adjacent fastbuild-pom.xml that extends the original, but excludes the static modules:
This build I can invoke in the CI-server:
mvn clean install -f fastbuild-pom.xml
So, not too much duplication of the original pom, and very unobtrusive.
Remember that in 95% of the cases you want to create profiles, there is probably a better tool for what you are trying to do. I think the best cases for profiles are read in their activation docs: Making it possible to build the project on different JDK's, or different OS. Then again, the whole point of Java is to be platform-independent, so this seldom an issue.
Profiles are POM smell.
While I know they have their uses, I have abused profiles heavily in the past, and seen others do this too. What might start off as a simple little trick to get some desired build eventually leads to:
- One profile for each testing category (unit, database, web-tests, etc)
- One profile for each environment/stage configuration (testing, live, etc)
- (Hint: Use a tool that supports stage-aware configuration)
- One profile for each artifact assembly (exclude module X when deploying in certain environments)
The point of a POM is that the output of the build, the artifact, should always be the same thing.
If you want to build *a different thing*, you probably should build another project. Andrew Spencer recently wrote a nice article about best practices in Maven profiles. If you want more advice you should have a look.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> | |
<modelVersion>4.0.0</modelVersion> | |
<parent> | |
<groupId>com.tfnico.examples</groupId> | |
<artifactId>foo</artifactId> | |
<version>1.0-SNAPSHOT</version> | |
<relativePath>./pom.xml</relativePath> | |
</parent> | |
<name>Fast build</name> | |
<groupId>com.tfnico.examples</groupId> | |
<artifactId>foo-fastbuild</artifactId> | |
<version>1.0-SNAPSHOT</version> | |
<packaging>pom</packaging> | |
<modules> | |
<module>foo-core</module> | |
<module>foo-web</module> | |
<!-- Here there are just two projects, | |
the parent/normal foo project has more, | |
but we don't need to build them in the | |
fast build --> | |
</modules> | |
</project> |
Instead of making a quickbuild-profile, I made an adjacent fastbuild-pom.xml that extends the original, but excludes the static modules:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> | |
<modelVersion>4.0.0</modelVersion> | |
<parent> | |
<groupId>com.tfnico.examples</groupId> | |
<artifactId>foo</artifactId> | |
<version>1.0-SNAPSHOT</version> | |
<relativePath>./pom.xml</relativePath> | |
</parent> | |
<name>Fast build</name> | |
<groupId>com.tfnico.examples</groupId> | |
<artifactId>foo-fastbuild</artifactId> | |
<version>1.0-SNAPSHOT</version> | |
<packaging>pom</packaging> | |
<modules> | |
<module>foo-core</module> | |
<module>foo-web</module> | |
<!-- Here there are just two projects, | |
the parent/normal foo project has more, | |
but we don't need to build them in the | |
fast build --> | |
</modules> | |
</project> |
This build I can invoke in the CI-server:
mvn clean install -f fastbuild-pom.xml
So, not too much duplication of the original pom, and very unobtrusive.
Remember that in 95% of the cases you want to create profiles, there is probably a better tool for what you are trying to do. I think the best cases for profiles are read in their activation docs: Making it possible to build the project on different JDK's, or different OS. Then again, the whole point of Java is to be platform-independent, so this seldom an issue.
Comments
Post a Comment