Pls Subscribe this channel Subscribe ® Registered teknosys.in
Get link
Facebook
X
Pinterest
Email
Other Apps
Build Profiles
Get link
Facebook
X
Pinterest
Email
Other Apps
-
49---->
Prev : Chapter 5. Build Profiles
TOC
Next : 5.2. Portability through Maven Profiles
5.1. What Are They For?
Profiles allow for the ability to customize a particular build for a particular environment; profiles enable portability between different build environments.
What do we mean by different build environments? Two example build environments are production and development. When you are working in a development environment, your system might be configured to read from a development database instance running on your local machine while in production, your system is configured to read from the production database. Maven allows you to define any number of build environments (build profiles) which can override any of the settings in the pom.xml. You could configure your application to read from your local, development instance of a database in your "development" profile, and you can configure it to read from the production database in the "production" profile. Profiles can also be activated by the environment and platform, you can customize a build to run differently depending the Operating System or the installed JDK version. Before we talk about using and configuring Maven profiles, we need to define the concept of Build Portability.
5.1.1. What is Build Portability
A build?s "portability" is a measure of how easy it is to take a particular project and build it in different environments. A build which works without any custom configuration or customization of properties files is more portable than a build which requires a great deal of work to build from scratch. The most portable projects tend to be widely used open source projects like Apache Commons or Apache Velocity which ship with Maven builds which require little or no customization. Put simply, the most portable project builds tend to just work, out of the box, and the least portable builds require you to jump through hoops and configure platform specific paths to locate build tools. Before we show you how to achieve build portability, let?s survey the different kinds of portability we are talking about.
Non-Portable Builds
The lack of portability is exactly what all build tools are made to prevent - however, any tool can be configured to be non-portable (even Maven). A non-portable project is buildable only under a specific set of circumstances and criteria (e.g., your local machine). Unless you are working by yourself and you have no plans on ever deploying your application to another machine, it is best to avoid non-portability entirely. A non-portable build only runs on a single machine, it is a "one-off". Maven is designed to discourage non-portable builds by offering the ability to customize builds using profiles.
When a new developer gets the source for a non-portable project, they will not be able to build the project without rewriting large portions of a build script.
Environment Portability
A build exhibits environment portability if it has a mechanism for customizing behavior and configuration when targeting different environments. A project that contains a reference to a test database in a test environment, for example, and a production database in a production environment, is environmentally portable. It is likely that this build has a different set of properties for each environment. When you move to a different environment, one that is not defined and has no profile created for it, the project will not work. Hence, it is only portable between defined environments.
When a new developer gets the source for an environmentally portable project, they will have to run the build within a defined environment or they will have to create a custom environment to successfully build the project.
Organizational (In-House) Portability
The center of this level of portability is a project?s requirement that only a select few may access internal resources such as source control or an internally-maintained Maven repository. A project at a large corporation may depend on a database available only to in-house developers, or an open source project might require a specific level of credentials to publish a web site and deploy the products of a build to a public repository.
If you attempt to build an in-house project from scratch outside of the in-house network (for example, outside of a corporate firewall), the build will fail. It may fail because certain required custom plugins are unavailable, or project dependencies cannot be found because you don?t have the appropriate credentials to retrieve dependencies from a custom remote repository. Such a project is portable only across environments in a single organization.
Wide (Universal) Portability
Anyone may download a widely portable project?s source, compile, and install it without customizing a build for a specific environment. This is the highest level of portability; anything less requires extra work for those who wish to build your project. This level of portability is especially important for open source projects, which depend on the ability for would-be contributors to easily download and build from source.
Any developer could download the source for a widely portable project.
5.1.2. Selecting an Appropriate Level of Portability
Clearly, you?ll want to avoid creating the worst-case scenario: the non-portable build. You may have had the misfortune to work or study at an organization that had critical applications with non-portable builds. In such organizations, you cannot deploy an application without the help of a specific individual on a specific machine. In such an organization, it is also very difficult to introduce new project dependencies or changes without coordinating the change with the single person who maintains such a non-portable build. Non-portable builds tend to grow in highly political environments when one individual or group needs to exert control over how and when a project is built and deployed. "How do we build the system? Oh, we?ve got to call Jack and ask him to build it for us, no one else deploys to production." That is a dangerous situation which is more common that you would think. If you work for this organization, Maven and Maven profiles provide a way out of this mess.
On the opposite end of the portability spectrum are widely portable builds. Widely portable builds are generally the most difficult build systems to attain. These builds restrict your dependencies to those projects and tools that may be freely distributed and are publicly available. Many commercial software packages might be excluded from the most-portable builds because they cannot be downloaded before you have accepted a certain license. Wide portability also restricts dependencies to those pieces of software that may be distributed as Maven artifacts. For example, if you depend upon Oracle JDBC drivers, your users will have to download and install them manually; this is not widely portable as you will have to distribute a set of environment setup instructions for people interested in building your application. On the other hand, you could use a JDBC driver which is available from the public Maven repositories like MySQL or HSQLDB.
As stated previously, open source projects benefit from having the most widely portable build possible. Widely portable builds reduce the inefficiencies associated with contributing to a project. In an open source project (such as Maven) there are two distinct groups: end-users and developers. When an end-user uses a project like Maven and decides to contribute a patch to Maven, they have to make the transition from using the output of a build to running a build. They have to first become a developer, and if it is difficult to learn how to build a project, this end-user has a disincentive to take the time to contribute to a project. In a widely portable project, an end-user doesn?t have to follow a set or arcane build instructions to start becoming a developer, they can download the source, modify the source, build, and submit a contribution without asking someone to help them set up a build environment. When the cost of contributing source back to an open-source project is lower, you?ll see an increase in source code contributions, especially casual contributions which can make the difference between a project?s success and a project?s failure. One side-effect of Maven?s adoption across a wide group of open source projects is that it has made it easier for developers to contribute code to various open source projects.
Prev : Chapter 5. Build Profiles
TOC
Next : 5.2. Portability through Maven Profiles
Nexus Professional
Access a live demo of the Pro Suite Install a trial version of Nexus Professional on your own machine Purchase a license for Nexus Professional
Recent Posts
Last Chance To Register: Insight for CI Demo
Insight for CI Demo: Additional Session Added
When Licenses Meet Reality, the Result is Often Confusing
How does Insight handle conflicting OSS licenses?
New Webinar: Gain Visibility & Control At Build Time with Insight for CI
50---->
Prev : 4.3. Common Lifecycle Goals
TOC
Next : 5.1. What Are They For?
Chapter 5. Build Profiles
5.1. What Are They For?
5.1.1. What is Build Portability
5.1.2. Selecting an Appropriate Level of Portability
5.2. Portability through Maven Profiles
5.2.1. Overriding a Project Object Model
5.3. Profile Activation
5.3.1. Activation Configuration
5.3.2. Activation by the Absence of a Property
5.4. Listing Active Profiles
5.5. Tips and Tricks
5.5.1. Common Environments
5.5.2. Protecting Secrets
5.5.3. Platform Classifiers
5.6. Summary
Prev : 4.3. Common Lifecycle Goals
TOC
Next : 5.1. What Are They For?
Nexus Professional
Access a live demo of the Pro Suite Install a trial version of Nexus Professional on your own machine Purchase a license for Nexus Professional
Recent Posts
Last Chance To Register: Insight for CI Demo
Insight for CI Demo: Additional Session Added
When Licenses Meet Reality, the Result is Often Confusing
How does Insight handle conflicting OSS licenses?
New Webinar: Gain Visibility & Control At Build Time with Insight for CI
51---->
Prev : 4.2. Package-specific Lifecycles
TOC
Next : Chapter 5. Build Profiles
4.3. Common Lifecycle Goals
Many of the packaging lifecycles have similar goals. If you look at the goals bound to the WAR and JAR lifecycles, you?ll see that they differ only in the package phase. The package phase of the WAR lifecycle calls war:war and the package phase of the JAR lifecycle calls jar:jar. Most of the lifecycles you will come into contact with share some common lifecycle goals for managing resources, running tests, and compiling source code. In this section, we?ll explore some of these common lifecycle goals in detail.
4.3.1. Process Resources
The process-resources phase "processes" resources and copies them to the output directory. If you haven?t customized the default directory locations defined in the Super POM, this means that Maven will copy the files from ${basedir}/src/main/resources to ${basedir}/target/classes or the directory defined in ${project.build.outputDirectory}. In addition to copying the resources to the output directory, Maven can also apply a filter to the resources that allows you to replace tokens within resource file. Just like variables are referenced in a POM using ${...} notation, you can reference variables in your project?s resources using the same syntax. Coupled with build profiles, such a facility can be used to produce build artifacts which target different deployment platforms. This is something that is common in environments which need to produce output for development, testing, staging, and production platforms from the same project. For more information about build profiles, see Chapter 5, Build Profiles.
To illustrate resource filtering, assume that you have a project with an XML file in src/main/resources/META-INF/service.xml. You want to externalize some configuration variables to a properties file. In other words, you might want to reference a JDBC URL, username, and password for your database, and you don?t want to put these values directly into the service.xml file. Instead, you would like to use a properties file to capture all of the configuration points for your program. Doing this will allow you to consolidate all configuration into a single properties file and make it easier to change configuration values when you need to target a new deployment environment. First, take a look at the contents of service.xml in src/main/resources/META-INF.
Using Properties in Project Resources.
${jdbc.url} ${jdbc.username} ${jdbc.password}
This XML file uses the same property reference syntax you can use in the POM. In fact, the first variable referenced is the project variable which is also an implicit variable made available in the POM. The project variable provides access to POM information. The next three variable references are jdbc.url, jdbc.username, and jdbc.password. These custom variables are defined in a properties file src/main/filters/default.properties.
default.properties in src/main/filters.
jdbc.url=jdbc:hsqldb:mem:mydb
jdbc.username=sa
jdbc.password=
To configure resource filtering with this default.properties file, we need to specify two things in a project?s POM: a list of properties files in the filters element of the build configuration, and a flag to Maven that the resources directory is to be filtered. The default Maven behavior is to skip filtering and just copy the resources to the output directory; you?ll need to explicitly configure resource filter, or Maven will skip the step altogether. This default ensures that Maven?s resource filtering feature doesn?t surprise you out of nowhere and clobbering any ${...} references you didn?t want it to replace.
Filter Resources (Replacing Properties).
src/main/filters/default.properties
src/main/resources true
As with all directories in Maven, the resources directory does not need to be in src/main/resources. This is just the default value defined in the Super POM. You should also note that you don?t need to consolidate all of your resources into a single directory. You can always separate resources into separate directories under src/main. Assume that you have a project which contains hundreds of XML documents and hundreds of images. Instead of mixing the resources in the src/main/resources directory, you might want to create two directories src/main/xml and src/main/images to hold this content. To add directories to the list of resource directories, you would add the following resource elements to your build configuration.
Configuring Additional Resource Directories.
... src/main/resources
src/main/xml
src/main/images
...
When you are building a project that produces a console application or a command-line tool, you?ll often find yourself writing simple shell scripts that need to reference the JAR produced by a build. When you are using the assembly plugin to produce a distribution for an application as a ZIP or TAR, you might place all of your scripts in a directory like src/main/command. In the following POM resource configuration, you?ll see how we can use resource filtering and a reference to the project variable to capture the final output name of the JAR. For more information about the Maven Assembly plugin, see Chapter 8, Maven Assemblies.
If you run mvn process-resources in this project, you will end up with two files, run.sh and run.bat, in ${basedir}. We?ve singled out these two files in a resource element, configuring filtering, and set the targetPath to be ${basedir}. In a second resource element, we?ve configured the default resources path to be copied to the default output directory without any filtering. Filtering Script Resources shows you how to declare two resource directories and supply them with different filtering and target directory preferences. The project from Filtering Script Resources would contain a run.bat file in src/main/command with the following content:
@echo off
java -jar ${project.build.finalName}.jar %*
After running mvn process-resources, a file named run.bat would appear in ${basedir} with the following content:
@echo off
java -jar simple-cmd-2.3.1.jar %*
The ability to customize filtering for specific subsets of resources is another reason why complex projects with many different kinds of resources often find it advantageous to separate resources into multiple directories. The alternative to storing different kinds of resources with different filtering requirements in different directories is to use a more complex set of include and exclude patterns to match all resource files which match a certain pattern.
4.3.2. Compile
Most lifecycles bind the Compiler plugin?s compile goal to the compile phase. This phase calls out to compile:compile which is configured to compile all of the source code and copy the bytecode to the build output directory. If you haven?t customized the values defined in the Super POM, compile:compile is going to compile everything from src/main/java to target/classes. The Compiler plugin calls out to javac and uses default source and target settings of 1.3 and 1.1. In other words, the compiler plugin assumes that your Java source conforms to Java 1.3 and that you are targeting a Java 1.1 JVM. If you would like to change these settings, you?ll need to supply the target and source configuration to the Compiler plugin in your project?s POM as shown in Setting the Source and Target Versions for the Compiler Plugin.
Setting the Source and Target Versions for the Compiler Plugin.
...
... maven-compiler-plugin 1.5 1.5
...
...
Notice we are configuring the Compiler plugin, and not the specific compile:compile goal. If we were going to configure the source and target for just the compile:compile goal, we would place the configuration element below an execution element for the compile:compile goal. We?ve configured the target and source for the plugin because compile:compile isn?t the only goal we?re interested in configuring. The Compiler plugin is reused when Maven compiles tests using the compile:testCompile goal, and configuring target and source at the plugin level allows us to define it once for all goals in a plugin.
If you need to customize the location of the source code, you can do so by changing the build configuration. If you wanted to store your project?s source code in src/java instead of src/main/java and if you wanted build output to go to classes instead of target/classes, you could always override the default sourceDirectory defined by the Super POM.
Overriding the Default Source Directory.
... src/java classes
...
Warning
While it might seem necessary to bend Maven to your own idea of project directory structure, we can?t emphasize enough that you should sacrifice your own ideas of directory structure in favor of the Maven defaults. This isn?t because we?re trying to brainwash you into accepting the Maven Way, but it will be easier for people to understand your project if it adheres to the most basic conventions. Just forget about this. Don?t do it.
4.3.3. Process Test Resources
The process-test-resources phase is almost indistinguishable from the process-resources phase. There are some trivial differences in the POM, but most everything the same. You can filter test resources just as you filter regular resources. The default location for test resources is defined in the Super POM as src/test/resources, and the default output directory for test resources is target/test-classes as defined in ${project.build.testOutputDirectory}.
4.3.4. Test Compile
The test-compile phase is almost identical to the compile phase. The only difference is that test-compile is going to invoke compile:testCompile to compile source from the test source directory to the test build output directory. If you haven?t customized the default directories from the Super POM, compile:testCompile is going to compile the source in src/test/java to the target/test-classes directory.
As with the source code directory, if you want to customize the location of the test source code and the output of test compilation, you can do so by overriding the testSourceDirectory and the testOutputDirectory. If you wanted to store test source in src-test/ instead of src/test/java and you wanted to save test bytecode to classes-test/ instead of target/test-classes, you would use the following configuration.
Overriding the Location of Test Source and Output.
... src-test classes-test
...
4.3.5. Test
Most lifecycles bind the test goal of the Surefire plugin to the test phase. The Surefire plugin is Maven?s unit testing plugin, the default behavior of Surefire is to look for all classes ending in *Test in the test source directory and to run them as JUnit tests. The Surefire plugin can also be configured to run TestNG unit tests.
After running mvn test, you should also notice that the Surefire produces a number of reports in target/surefire-reports. This reports directory will have two files for each test executed by the Surefire plugin: an XML document containing execution information for the test, and a text file containing the output of the unit test. If there is a problem during the test phase and a unit test has failed, you can use the output of Maven and the contents of this directory to track down the cause of a test failure. This surefire-reports/ directory is also used during site generation to create an easy to read summary of all the unit tests in a project.
If you are working on a project that has some failing unit tests, but you want the project to produce output, you?ll need to configure the Surefire plugin to continue a build even if it encounters a failure. The default behavior is to stop a build whenever a unit test failure is encountered. To override this behavior, you?ll need to set the testFailureIgnore configuration property on the Surefire plugin to true.
If you would like to skip tests altogether, you can do so by executing the following command:
$ mvn install -Dmaven.test.skip=true
The maven.test.skip variable controls both the Compiler and the Surefire plugin, if you pass in maven.test.skip you?ve told Maven to ignore tests altogether.
4.3.6. Install
The install goal of the Install plugin is almost always bound to the install lifecycle phase. This install:install goal simply installs a project?s main artifact to the local repository. If you have a project with a groupId of org..mavenbook, an artifactId of simple-test, and a version of 1.0.2, the install:install goal is going to copy the JAR file from target/simple-test-1.0.2.jar to ~/.m2/repository/org//mavenbook/simple-test/1.0.2/simple-test-1.0.2.jar. If the project has POM packaging, this goal will copy the POM to the local repository.
4.3.7. Deploy
The deploy goal of the Deploy plugin is usually bound to the deploy lifecycle phase. This phase is used to deploy an artifact to a remote Maven repository, this is usually required to update a remote repository when you are performing a release. The deployment procedure can be as simple as copying a file to another directory or as complex as transferring a file over SCP using a public key. Deployment settings usually involve credentials to a remote repository, and, as such, deployment settings are usually not stored in a pom.xml. Instead, deployment settings are more frequently found in an individual user?s ~/.m2/settings.xml. For now, all you need to know is that the deploy:deploy goal is bound to the deploy phase and it takes care of transporting an artifact to a published repository and updating any repository information which might be affected by such a deployment.
Prev : 4.2. Package-specific Lifecycles
TOC
Next : Chapter 5. Build Profiles
Nexus Professional
Access a live demo of the Pro Suite Install a trial version of Nexus Professional on your own machine Purchase a license for Nexus Professional
Recent Posts
Last Chance To Register: Insight for CI Demo
Insight for CI Demo: Additional Session Added
When Licenses Meet Reality, the Result is Often Confusing
How does Insight handle conflicting OSS licenses?
New Webinar: Gain Visibility & Control At Build Time with Insight for CI
52---->
Prev : 4.2. Package-specific Lifecycles
TOC
Next : Chapter 5. Build Profiles
4.3. Common Lifecycle Goals
Many of the packaging lifecycles have similar goals. If you look at the goals bound to the WAR and JAR lifecycles, you?ll see that they differ only in the package phase. The package phase of the WAR lifecycle calls war:war and the package phase of the JAR lifecycle calls jar:jar. Most of the lifecycles you will come into contact with share some common lifecycle goals for managing resources, running tests, and compiling source code. In this section, we?ll explore some of these common lifecycle goals in detail.
4.3.1. Process Resources
The process-resources phase "processes" resources and copies them to the output directory. If you haven?t customized the default directory locations defined in the Super POM, this means that Maven will copy the files from ${basedir}/src/main/resources to ${basedir}/target/classes or the directory defined in ${project.build.outputDirectory}. In addition to copying the resources to the output directory, Maven can also apply a filter to the resources that allows you to replace tokens within resource file. Just like variables are referenced in a POM using ${...} notation, you can reference variables in your project?s resources using the same syntax. Coupled with build profiles, such a facility can be used to produce build artifacts which target different deployment platforms. This is something that is common in environments which need to produce output for development, testing, staging, and production platforms from the same project. For more information about build profiles, see Chapter 5, Build Profiles.
To illustrate resource filtering, assume that you have a project with an XML file in src/main/resources/META-INF/service.xml. You want to externalize some configuration variables to a properties file. In other words, you might want to reference a JDBC URL, username, and password for your database, and you don?t want to put these values directly into the service.xml file. Instead, you would like to use a properties file to capture all of the configuration points for your program. Doing this will allow you to consolidate all configuration into a single properties file and make it easier to change configuration values when you need to target a new deployment environment. First, take a look at the contents of service.xml in src/main/resources/META-INF.
Using Properties in Project Resources.
${jdbc.url} ${jdbc.username} ${jdbc.password}
This XML file uses the same property reference syntax you can use in the POM. In fact, the first variable referenced is the project variable which is also an implicit variable made available in the POM. The project variable provides access to POM information. The next three variable references are jdbc.url, jdbc.username, and jdbc.password. These custom variables are defined in a properties file src/main/filters/default.properties.
default.properties in src/main/filters.
jdbc.url=jdbc:hsqldb:mem:mydb
jdbc.username=sa
jdbc.password=
To configure resource filtering with this default.properties file, we need to specify two things in a project?s POM: a list of properties files in the filters element of the build configuration, and a flag to Maven that the resources directory is to be filtered. The default Maven behavior is to skip filtering and just copy the resources to the output directory; you?ll need to explicitly configure resource filter, or Maven will skip the step altogether. This default ensures that Maven?s resource filtering feature doesn?t surprise you out of nowhere and clobbering any ${...} references you didn?t want it to replace.
Filter Resources (Replacing Properties).
src/main/filters/default.properties
src/main/resources true
As with all directories in Maven, the resources directory does not need to be in src/main/resources. This is just the default value defined in the Super POM. You should also note that you don?t need to consolidate all of your resources into a single directory. You can always separate resources into separate directories under src/main. Assume that you have a project which contains hundreds of XML documents and hundreds of images. Instead of mixing the resources in the src/main/resources directory, you might want to create two directories src/main/xml and src/main/images to hold this content. To add directories to the list of resource directories, you would add the following resource elements to your build configuration.
Configuring Additional Resource Directories.
... src/main/resources
src/main/xml
src/main/images
...
When you are building a project that produces a console application or a command-line tool, you?ll often find yourself writing simple shell scripts that need to reference the JAR produced by a build. When you are using the assembly plugin to produce a distribution for an application as a ZIP or TAR, you might place all of your scripts in a directory like src/main/command. In the following POM resource configuration, you?ll see how we can use resource filtering and a reference to the project variable to capture the final output name of the JAR. For more information about the Maven Assembly plugin, see Chapter 8, Maven Assemblies.
If you run mvn process-resources in this project, you will end up with two files, run.sh and run.bat, in ${basedir}. We?ve singled out these two files in a resource element, configuring filtering, and set the targetPath to be ${basedir}. In a second resource element, we?ve configured the default resources path to be copied to the default output directory without any filtering. Filtering Script Resources shows you how to declare two resource directories and supply them with different filtering and target directory preferences. The project from Filtering Script Resources would contain a run.bat file in src/main/command with the following content:
@echo off
java -jar ${project.build.finalName}.jar %*
After running mvn process-resources, a file named run.bat would appear in ${basedir} with the following content:
@echo off
java -jar simple-cmd-2.3.1.jar %*
The ability to customize filtering for specific subsets of resources is another reason why complex projects with many different kinds of resources often find it advantageous to separate resources into multiple directories. The alternative to storing different kinds of resources with different filtering requirements in different directories is to use a more complex set of include and exclude patterns to match all resource files which match a certain pattern.
4.3.2. Compile
Most lifecycles bind the Compiler plugin?s compile goal to the compile phase. This phase calls out to compile:compile which is configured to compile all of the source code and copy the bytecode to the build output directory. If you haven?t customized the values defined in the Super POM, compile:compile is going to compile everything from src/main/java to target/classes. The Compiler plugin calls out to javac and uses default source and target settings of 1.3 and 1.1. In other words, the compiler plugin assumes that your Java source conforms to Java 1.3 and that you are targeting a Java 1.1 JVM. If you would like to change these settings, you?ll need to supply the target and source configuration to the Compiler plugin in your project?s POM as shown in Setting the Source and Target Versions for the Compiler Plugin.
Setting the Source and Target Versions for the Compiler Plugin.
...
... maven-compiler-plugin 1.5 1.5
...
...
Notice we are configuring the Compiler plugin, and not the specific compile:compile goal. If we were going to configure the source and target for just the compile:compile goal, we would place the configuration element below an execution element for the compile:compile goal. We?ve configured the target and source for the plugin because compile:compile isn?t the only goal we?re interested in configuring. The Compiler plugin is reused when Maven compiles tests using the compile:testCompile goal, and configuring target and source at the plugin level allows us to define it once for all goals in a plugin.
If you need to customize the location of the source code, you can do so by changing the build configuration. If you wanted to store your project?s source code in src/java instead of src/main/java and if you wanted build output to go to classes instead of target/classes, you could always override the default sourceDirectory defined by the Super POM.
Overriding the Default Source Directory.
... src/java classes
...
Warning
While it might seem necessary to bend Maven to your own idea of project directory structure, we can?t emphasize enough that you should sacrifice your own ideas of directory structure in favor of the Maven defaults. This isn?t because we?re trying to brainwash you into accepting the Maven Way, but it will be easier for people to understand your project if it adheres to the most basic conventions. Just forget about this. Don?t do it.
4.3.3. Process Test Resources
The process-test-resources phase is almost indistinguishable from the process-resources phase. There are some trivial differences in the POM, but most everything the same. You can filter test resources just as you filter regular resources. The default location for test resources is defined in the Super POM as src/test/resources, and the default output directory for test resources is target/test-classes as defined in ${project.build.testOutputDirectory}.
4.3.4. Test Compile
The test-compile phase is almost identical to the compile phase. The only difference is that test-compile is going to invoke compile:testCompile to compile source from the test source directory to the test build output directory. If you haven?t customized the default directories from the Super POM, compile:testCompile is going to compile the source in src/test/java to the target/test-classes directory.
As with the source code directory, if you want to customize the location of the test source code and the output of test compilation, you can do so by overriding the testSourceDirectory and the testOutputDirectory. If you wanted to store test source in src-test/ instead of src/test/java and you wanted to save test bytecode to classes-test/ instead of target/test-classes, you would use the following configuration.
Overriding the Location of Test Source and Output.
... src-test classes-test
...
4.3.5. Test
Most lifecycles bind the test goal of the Surefire plugin to the test phase. The Surefire plugin is Maven?s unit testing plugin, the default behavior of Surefire is to look for all classes ending in *Test in the test source directory and to run them as JUnit tests. The Surefire plugin can also be configured to run TestNG unit tests.
After running mvn test, you should also notice that the Surefire produces a number of reports in target/surefire-reports. This reports directory will have two files for each test executed by the Surefire plugin: an XML document containing execution information for the test, and a text file containing the output of the unit test. If there is a problem during the test phase and a unit test has failed, you can use the output of Maven and the contents of this directory to track down the cause of a test failure. This surefire-reports/ directory is also used during site generation to create an easy to read summary of all the unit tests in a project.
If you are working on a project that has some failing unit tests, but you want the project to produce output, you?ll need to configure the Surefire plugin to continue a build even if it encounters a failure. The default behavior is to stop a build whenever a unit test failure is encountered. To override this behavior, you?ll need to set the testFailureIgnore configuration property on the Surefire plugin to true.
If you would like to skip tests altogether, you can do so by executing the following command:
$ mvn install -Dmaven.test.skip=true
The maven.test.skip variable controls both the Compiler and the Surefire plugin, if you pass in maven.test.skip you?ve told Maven to ignore tests altogether.
4.3.6. Install
The install goal of the Install plugin is almost always bound to the install lifecycle phase. This install:install goal simply installs a project?s main artifact to the local repository. If you have a project with a groupId of org..mavenbook, an artifactId of simple-test, and a version of 1.0.2, the install:install goal is going to copy the JAR file from target/simple-test-1.0.2.jar to ~/.m2/repository/org//mavenbook/simple-test/1.0.2/simple-test-1.0.2.jar. If the project has POM packaging, this goal will copy the POM to the local repository.
4.3.7. Deploy
The deploy goal of the Deploy plugin is usually bound to the deploy lifecycle phase. This phase is used to deploy an artifact to a remote Maven repository, this is usually required to update a remote repository when you are performing a release. The deployment procedure can be as simple as copying a file to another directory or as complex as transferring a file over SCP using a public key. Deployment settings usually involve credentials to a remote repository, and, as such, deployment settings are usually not stored in a pom.xml. Instead, deployment settings are more frequently found in an individual user?s ~/.m2/settings.xml. For now, all you need to know is that the deploy:deploy goal is bound to the deploy phase and it takes care of transporting an artifact to a published repository and updating any repository information which might be affected by such a deployment.
Prev : 4.2. Package-specific Lifecycles
TOC
Next : Chapter 5. Build Profiles
Nexus Professional
Access a live demo of the Pro Suite Install a trial version of Nexus Professional on your own machine Purchase a license for Nexus Professional
Recent Posts
Last Chance To Register: Insight for CI Demo
Insight for CI Demo: Additional Session Added
When Licenses Meet Reality, the Result is Often Confusing
How does Insight handle conflicting OSS licenses?
New Webinar: Gain Visibility & Control At Build Time with Insight for CI
53---->
Prev : 4.2. Package-specific Lifecycles
TOC
Next : Chapter 5. Build Profiles
4.3. Common Lifecycle Goals
Many of the packaging lifecycles have similar goals. If you look at the goals bound to the WAR and JAR lifecycles, you?ll see that they differ only in the package phase. The package phase of the WAR lifecycle calls war:war and the package phase of the JAR lifecycle calls jar:jar. Most of the lifecycles you will come into contact with share some common lifecycle goals for managing resources, running tests, and compiling source code. In this section, we?ll explore some of these common lifecycle goals in detail.
4.3.1. Process Resources
The process-resources phase "processes" resources and copies them to the output directory. If you haven?t customized the default directory locations defined in the Super POM, this means that Maven will copy the files from ${basedir}/src/main/resources to ${basedir}/target/classes or the directory defined in ${project.build.outputDirectory}. In addition to copying the resources to the output directory, Maven can also apply a filter to the resources that allows you to replace tokens within resource file. Just like variables are referenced in a POM using ${...} notation, you can reference variables in your project?s resources using the same syntax. Coupled with build profiles, such a facility can be used to produce build artifacts which target different deployment platforms. This is something that is common in environments which need to produce output for development, testing, staging, and production platforms from the same project. For more information about build profiles, see Chapter 5, Build Profiles.
To illustrate resource filtering, assume that you have a project with an XML file in src/main/resources/META-INF/service.xml. You want to externalize some configuration variables to a properties file. In other words, you might want to reference a JDBC URL, username, and password for your database, and you don?t want to put these values directly into the service.xml file. Instead, you would like to use a properties file to capture all of the configuration points for your program. Doing this will allow you to consolidate all configuration into a single properties file and make it easier to change configuration values when you need to target a new deployment environment. First, take a look at the contents of service.xml in src/main/resources/META-INF.
Using Properties in Project Resources.
${jdbc.url} ${jdbc.username} ${jdbc.password}
This XML file uses the same property reference syntax you can use in the POM. In fact, the first variable referenced is the project variable which is also an implicit variable made available in the POM. The project variable provides access to POM information. The next three variable references are jdbc.url, jdbc.username, and jdbc.password. These custom variables are defined in a properties file src/main/filters/default.properties.
default.properties in src/main/filters.
jdbc.url=jdbc:hsqldb:mem:mydb
jdbc.username=sa
jdbc.password=
To configure resource filtering with this default.properties file, we need to specify two things in a project?s POM: a list of properties files in the filters element of the build configuration, and a flag to Maven that the resources directory is to be filtered. The default Maven behavior is to skip filtering and just copy the resources to the output directory; you?ll need to explicitly configure resource filter, or Maven will skip the step altogether. This default ensures that Maven?s resource filtering feature doesn?t surprise you out of nowhere and clobbering any ${...} references you didn?t want it to replace.
Filter Resources (Replacing Properties).
src/main/filters/default.properties
src/main/resources true
As with all directories in Maven, the resources directory does not need to be in src/main/resources. This is just the default value defined in the Super POM. You should also note that you don?t need to consolidate all of your resources into a single directory. You can always separate resources into separate directories under src/main. Assume that you have a project which contains hundreds of XML documents and hundreds of images. Instead of mixing the resources in the src/main/resources directory, you might want to create two directories src/main/xml and src/main/images to hold this content. To add directories to the list of resource directories, you would add the following resource elements to your build configuration.
Configuring Additional Resource Directories.
... src/main/resources
src/main/xml
src/main/images
...
When you are building a project that produces a console application or a command-line tool, you?ll often find yourself writing simple shell scripts that need to reference the JAR produced by a build. When you are using the assembly plugin to produce a distribution for an application as a ZIP or TAR, you might place all of your scripts in a directory like src/main/command. In the following POM resource configuration, you?ll see how we can use resource filtering and a reference to the project variable to capture the final output name of the JAR. For more information about the Maven Assembly plugin, see Chapter 8, Maven Assemblies.
If you run mvn process-resources in this project, you will end up with two files, run.sh and run.bat, in ${basedir}. We?ve singled out these two files in a resource element, configuring filtering, and set the targetPath to be ${basedir}. In a second resource element, we?ve configured the default resources path to be copied to the default output directory without any filtering. Filtering Script Resources shows you how to declare two resource directories and supply them with different filtering and target directory preferences. The project from Filtering Script Resources would contain a run.bat file in src/main/command with the following content:
@echo off
java -jar ${project.build.finalName}.jar %*
After running mvn process-resources, a file named run.bat would appear in ${basedir} with the following content:
@echo off
java -jar simple-cmd-2.3.1.jar %*
The ability to customize filtering for specific subsets of resources is another reason why complex projects with many different kinds of resources often find it advantageous to separate resources into multiple directories. The alternative to storing different kinds of resources with different filtering requirements in different directories is to use a more complex set of include and exclude patterns to match all resource files which match a certain pattern.
4.3.2. Compile
Most lifecycles bind the Compiler plugin?s compile goal to the compile phase. This phase calls out to compile:compile which is configured to compile all of the source code and copy the bytecode to the build output directory. If you haven?t customized the values defined in the Super POM, compile:compile is going to compile everything from src/main/java to target/classes. The Compiler plugin calls out to javac and uses default source and target settings of 1.3 and 1.1. In other words, the compiler plugin assumes that your Java source conforms to Java 1.3 and that you are targeting a Java 1.1 JVM. If you would like to change these settings, you?ll need to supply the target and source configuration to the Compiler plugin in your project?s POM as shown in Setting the Source and Target Versions for the Compiler Plugin.
Setting the Source and Target Versions for the Compiler Plugin.
...
... maven-compiler-plugin 1.5 1.5
...
...
Notice we are configuring the Compiler plugin, and not the specific compile:compile goal. If we were going to configure the source and target for just the compile:compile goal, we would place the configuration element below an execution element for the compile:compile goal. We?ve configured the target and source for the plugin because compile:compile isn?t the only goal we?re interested in configuring. The Compiler plugin is reused when Maven compiles tests using the compile:testCompile goal, and configuring target and source at the plugin level allows us to define it once for all goals in a plugin.
If you need to customize the location of the source code, you can do so by changing the build configuration. If you wanted to store your project?s source code in src/java instead of src/main/java and if you wanted build output to go to classes instead of target/classes, you could always override the default sourceDirectory defined by the Super POM.
Overriding the Default Source Directory.
... src/java classes
...
Warning
While it might seem necessary to bend Maven to your own idea of project directory structure, we can?t emphasize enough that you should sacrifice your own ideas of directory structure in favor of the Maven defaults. This isn?t because we?re trying to brainwash you into accepting the Maven Way, but it will be easier for people to understand your project if it adheres to the most basic conventions. Just forget about this. Don?t do it.
4.3.3. Process Test Resources
The process-test-resources phase is almost indistinguishable from the process-resources phase. There are some trivial differences in the POM, but most everything the same. You can filter test resources just as you filter regular resources. The default location for test resources is defined in the Super POM as src/test/resources, and the default output directory for test resources is target/test-classes as defined in ${project.build.testOutputDirectory}.
4.3.4. Test Compile
The test-compile phase is almost identical to the compile phase. The only difference is that test-compile is going to invoke compile:testCompile to compile source from the test source directory to the test build output directory. If you haven?t customized the default directories from the Super POM, compile:testCompile is going to compile the source in src/test/java to the target/test-classes directory.
As with the source code directory, if you want to customize the location of the test source code and the output of test compilation, you can do so by overriding the testSourceDirectory and the testOutputDirectory. If you wanted to store test source in src-test/ instead of src/test/java and you wanted to save test bytecode to classes-test/ instead of target/test-classes, you would use the following configuration.
Overriding the Location of Test Source and Output.
... src-test classes-test
...
4.3.5. Test
Most lifecycles bind the test goal of the Surefire plugin to the test phase. The Surefire plugin is Maven?s unit testing plugin, the default behavior of Surefire is to look for all classes ending in *Test in the test source directory and to run them as JUnit tests. The Surefire plugin can also be configured to run TestNG unit tests.
After running mvn test, you should also notice that the Surefire produces a number of reports in target/surefire-reports. This reports directory will have two files for each test executed by the Surefire plugin: an XML document containing execution information for the test, and a text file containing the output of the unit test. If there is a problem during the test phase and a unit test has failed, you can use the output of Maven and the contents of this directory to track down the cause of a test failure. This surefire-reports/ directory is also used during site generation to create an easy to read summary of all the unit tests in a project.
If you are working on a project that has some failing unit tests, but you want the project to produce output, you?ll need to configure the Surefire plugin to continue a build even if it encounters a failure. The default behavior is to stop a build whenever a unit test failure is encountered. To override this behavior, you?ll need to set the testFailureIgnore configuration property on the Surefire plugin to true.
If you would like to skip tests altogether, you can do so by executing the following command:
$ mvn install -Dmaven.test.skip=true
The maven.test.skip variable controls both the Compiler and the Surefire plugin, if you pass in maven.test.skip you?ve told Maven to ignore tests altogether.
4.3.6. Install
The install goal of the Install plugin is almost always bound to the install lifecycle phase. This install:install goal simply installs a project?s main artifact to the local repository. If you have a project with a groupId of org..mavenbook, an artifactId of simple-test, and a version of 1.0.2, the install:install goal is going to copy the JAR file from target/simple-test-1.0.2.jar to ~/.m2/repository/org//mavenbook/simple-test/1.0.2/simple-test-1.0.2.jar. If the project has POM packaging, this goal will copy the POM to the local repository.
4.3.7. Deploy
The deploy goal of the Deploy plugin is usually bound to the deploy lifecycle phase. This phase is used to deploy an artifact to a remote Maven repository, this is usually required to update a remote repository when you are performing a release. The deployment procedure can be as simple as copying a file to another directory or as complex as transferring a file over SCP using a public key. Deployment settings usually involve credentials to a remote repository, and, as such, deployment settings are usually not stored in a pom.xml. Instead, deployment settings are more frequently found in an individual user?s ~/.m2/settings.xml. For now, all you need to know is that the deploy:deploy goal is bound to the deploy phase and it takes care of transporting an artifact to a published repository and updating any repository information which might be affected by such a deployment.
Prev : 4.2. Package-specific Lifecycles
TOC
Next : Chapter 5. Build Profiles
Nexus Professional
Access a live demo of the Pro Suite Install a trial version of Nexus Professional on your own machine Purchase a license for Nexus Professional
Recent Posts
Last Chance To Register: Insight for CI Demo
Insight for CI Demo: Additional Session Added
When Licenses Meet Reality, the Result is Often Confusing
How does Insight handle conflicting OSS licenses?
New Webinar: Gain Visibility & Control At Build Time with Insight for CI
54---->
Prev : 4.2. Package-specific Lifecycles
TOC
Next : Chapter 5. Build Profiles
4.3. Common Lifecycle Goals
Many of the packaging lifecycles have similar goals. If you look at the goals bound to the WAR and JAR lifecycles, you?ll see that they differ only in the package phase. The package phase of the WAR lifecycle calls war:war and the package phase of the JAR lifecycle calls jar:jar. Most of the lifecycles you will come into contact with share some common lifecycle goals for managing resources, running tests, and compiling source code. In this section, we?ll explore some of these common lifecycle goals in detail.
4.3.1. Process Resources
The process-resources phase "processes" resources and copies them to the output directory. If you haven?t customized the default directory locations defined in the Super POM, this means that Maven will copy the files from ${basedir}/src/main/resources to ${basedir}/target/classes or the directory defined in ${project.build.outputDirectory}. In addition to copying the resources to the output directory, Maven can also apply a filter to the resources that allows you to replace tokens within resource file. Just like variables are referenced in a POM using ${...} notation, you can reference variables in your project?s resources using the same syntax. Coupled with build profiles, such a facility can be used to produce build artifacts which target different deployment platforms. This is something that is common in environments which need to produce output for development, testing, staging, and production platforms from the same project. For more information about build profiles, see Chapter 5, Build Profiles.
To illustrate resource filtering, assume that you have a project with an XML file in src/main/resources/META-INF/service.xml. You want to externalize some configuration variables to a properties file. In other words, you might want to reference a JDBC URL, username, and password for your database, and you don?t want to put these values directly into the service.xml file. Instead, you would like to use a properties file to capture all of the configuration points for your program. Doing this will allow you to consolidate all configuration into a single properties file and make it easier to change configuration values when you need to target a new deployment environment. First, take a look at the contents of service.xml in src/main/resources/META-INF.
Using Properties in Project Resources.
${jdbc.url} ${jdbc.username} ${jdbc.password}
This XML file uses the same property reference syntax you can use in the POM. In fact, the first variable referenced is the project variable which is also an implicit variable made available in the POM. The project variable provides access to POM information. The next three variable references are jdbc.url, jdbc.username, and jdbc.password. These custom variables are defined in a properties file src/main/filters/default.properties.
default.properties in src/main/filters.
jdbc.url=jdbc:hsqldb:mem:mydb
jdbc.username=sa
jdbc.password=
To configure resource filtering with this default.properties file, we need to specify two things in a project?s POM: a list of properties files in the filters element of the build configuration, and a flag to Maven that the resources directory is to be filtered. The default Maven behavior is to skip filtering and just copy the resources to the output directory; you?ll need to explicitly configure resource filter, or Maven will skip the step altogether. This default ensures that Maven?s resource filtering feature doesn?t surprise you out of nowhere and clobbering any ${...} references you didn?t want it to replace.
Filter Resources (Replacing Properties).
src/main/filters/default.properties
src/main/resources true
As with all directories in Maven, the resources directory does not need to be in src/main/resources. This is just the default value defined in the Super POM. You should also note that you don?t need to consolidate all of your resources into a single directory. You can always separate resources into separate directories under src/main. Assume that you have a project which contains hundreds of XML documents and hundreds of images. Instead of mixing the resources in the src/main/resources directory, you might want to create two directories src/main/xml and src/main/images to hold this content. To add directories to the list of resource directories, you would add the following resource elements to your build configuration.
Configuring Additional Resource Directories.
... src/main/resources
src/main/xml
src/main/images
...
When you are building a project that produces a console application or a command-line tool, you?ll often find yourself writing simple shell scripts that need to reference the JAR produced by a build. When you are using the assembly plugin to produce a distribution for an application as a ZIP or TAR, you might place all of your scripts in a directory like src/main/command. In the following POM resource configuration, you?ll see how we can use resource filtering and a reference to the project variable to capture the final output name of the JAR. For more information about the Maven Assembly plugin, see Chapter 8, Maven Assemblies.
If you run mvn process-resources in this project, you will end up with two files, run.sh and run.bat, in ${basedir}. We?ve singled out these two files in a resource element, configuring filtering, and set the targetPath to be ${basedir}. In a second resource element, we?ve configured the default resources path to be copied to the default output directory without any filtering. Filtering Script Resources shows you how to declare two resource directories and supply them with different filtering and target directory preferences. The project from Filtering Script Resources would contain a run.bat file in src/main/command with the following content:
@echo off
java -jar ${project.build.finalName}.jar %*
After running mvn process-resources, a file named run.bat would appear in ${basedir} with the following content:
@echo off
java -jar simple-cmd-2.3.1.jar %*
The ability to customize filtering for specific subsets of resources is another reason why complex projects with many different kinds of resources often find it advantageous to separate resources into multiple directories. The alternative to storing different kinds of resources with different filtering requirements in different directories is to use a more complex set of include and exclude patterns to match all resource files which match a certain pattern.
4.3.2. Compile
Most lifecycles bind the Compiler plugin?s compile goal to the compile phase. This phase calls out to compile:compile which is configured to compile all of the source code and copy the bytecode to the build output directory. If you haven?t customized the values defined in the Super POM, compile:compile is going to compile everything from src/main/java to target/classes. The Compiler plugin calls out to javac and uses default source and target settings of 1.3 and 1.1. In other words, the compiler plugin assumes that your Java source conforms to Java 1.3 and that you are targeting a Java 1.1 JVM. If you would like to change these settings, you?ll need to supply the target and source configuration to the Compiler plugin in your project?s POM as shown in Setting the Source and Target Versions for the Compiler Plugin.
Setting the Source and Target Versions for the Compiler Plugin.
...
... maven-compiler-plugin 1.5 1.5
...
...
Notice we are configuring the Compiler plugin, and not the specific compile:compile goal. If we were going to configure the source and target for just the compile:compile goal, we would place the configuration element below an execution element for the compile:compile goal. We?ve configured the target and source for the plugin because compile:compile isn?t the only goal we?re interested in configuring. The Compiler plugin is reused when Maven compiles tests using the compile:testCompile goal, and configuring target and source at the plugin level allows us to define it once for all goals in a plugin.
If you need to customize the location of the source code, you can do so by changing the build configuration. If you wanted to store your project?s source code in src/java instead of src/main/java and if you wanted build output to go to classes instead of target/classes, you could always override the default sourceDirectory defined by the Super POM.
Overriding the Default Source Directory.
... src/java classes
...
Warning
While it might seem necessary to bend Maven to your own idea of project directory structure, we can?t emphasize enough that you should sacrifice your own ideas of directory structure in favor of the Maven defaults. This isn?t because we?re trying to brainwash you into accepting the Maven Way, but it will be easier for people to understand your project if it adheres to the most basic conventions. Just forget about this. Don?t do it.
4.3.3. Process Test Resources
The process-test-resources phase is almost indistinguishable from the process-resources phase. There are some trivial differences in the POM, but most everything the same. You can filter test resources just as you filter regular resources. The default location for test resources is defined in the Super POM as src/test/resources, and the default output directory for test resources is target/test-classes as defined in ${project.build.testOutputDirectory}.
4.3.4. Test Compile
The test-compile phase is almost identical to the compile phase. The only difference is that test-compile is going to invoke compile:testCompile to compile source from the test source directory to the test build output directory. If you haven?t customized the default directories from the Super POM, compile:testCompile is going to compile the source in src/test/java to the target/test-classes directory.
As with the source code directory, if you want to customize the location of the test source code and the output of test compilation, you can do so by overriding the testSourceDirectory and the testOutputDirectory. If you wanted to store test source in src-test/ instead of src/test/java and you wanted to save test bytecode to classes-test/ instead of target/test-classes, you would use the following configuration.
Overriding the Location of Test Source and Output.
... src-test classes-test
...
4.3.5. Test
Most lifecycles bind the test goal of the Surefire plugin to the test phase. The Surefire plugin is Maven?s unit testing plugin, the default behavior of Surefire is to look for all classes ending in *Test in the test source directory and to run them as JUnit tests. The Surefire plugin can also be configured to run TestNG unit tests.
After running mvn test, you should also notice that the Surefire produces a number of reports in target/surefire-reports. This reports directory will have two files for each test executed by the Surefire plugin: an XML document containing execution information for the test, and a text file containing the output of the unit test. If there is a problem during the test phase and a unit test has failed, you can use the output of Maven and the contents of this directory to track down the cause of a test failure. This surefire-reports/ directory is also used during site generation to create an easy to read summary of all the unit tests in a project.
If you are working on a project that has some failing unit tests, but you want the project to produce output, you?ll need to configure the Surefire plugin to continue a build even if it encounters a failure. The default behavior is to stop a build whenever a unit test failure is encountered. To override this behavior, you?ll need to set the testFailureIgnore configuration property on the Surefire plugin to true.
If you would like to skip tests altogether, you can do so by executing the following command:
$ mvn install -Dmaven.test.skip=true
The maven.test.skip variable controls both the Compiler and the Surefire plugin, if you pass in maven.test.skip you?ve told Maven to ignore tests altogether.
4.3.6. Install
The install goal of the Install plugin is almost always bound to the install lifecycle phase. This install:install goal simply installs a project?s main artifact to the local repository. If you have a project with a groupId of org..mavenbook, an artifactId of simple-test, and a version of 1.0.2, the install:install goal is going to copy the JAR file from target/simple-test-1.0.2.jar to ~/.m2/repository/org//mavenbook/simple-test/1.0.2/simple-test-1.0.2.jar. If the project has POM packaging, this goal will copy the POM to the local repository.
4.3.7. Deploy
The deploy goal of the Deploy plugin is usually bound to the deploy lifecycle phase. This phase is used to deploy an artifact to a remote Maven repository, this is usually required to update a remote repository when you are performing a release. The deployment procedure can be as simple as copying a file to another directory or as complex as transferring a file over SCP using a public key. Deployment settings usually involve credentials to a remote repository, and, as such, deployment settings are usually not stored in a pom.xml. Instead, deployment settings are more frequently found in an individual user?s ~/.m2/settings.xml. For now, all you need to know is that the deploy:deploy goal is bound to the deploy phase and it takes care of transporting an artifact to a published repository and updating any repository information which might be affected by such a deployment.
Prev : 4.2. Package-specific Lifecycles
TOC
Next : Chapter 5. Build Profiles
Nexus Professional
Access a live demo of the Pro Suite Install a trial version of Nexus Professional on your own machine Purchase a license for Nexus Professional
Recent Posts
Last Chance To Register: Insight for CI Demo
Insight for CI Demo: Additional Session Added
When Licenses Meet Reality, the Result is Often Confusing
How does Insight handle conflicting OSS licenses?
New Webinar: Gain Visibility & Control At Build Time with Insight for CI
55---->
Prev : 4.2. Package-specific Lifecycles
TOC
Next : Chapter 5. Build Profiles
4.3. Common Lifecycle Goals
Many of the packaging lifecycles have similar goals. If you look at the goals bound to the WAR and JAR lifecycles, you?ll see that they differ only in the package phase. The package phase of the WAR lifecycle calls war:war and the package phase of the JAR lifecycle calls jar:jar. Most of the lifecycles you will come into contact with share some common lifecycle goals for managing resources, running tests, and compiling source code. In this section, we?ll explore some of these common lifecycle goals in detail.
4.3.1. Process Resources
The process-resources phase "processes" resources and copies them to the output directory. If you haven?t customized the default directory locations defined in the Super POM, this means that Maven will copy the files from ${basedir}/src/main/resources to ${basedir}/target/classes or the directory defined in ${project.build.outputDirectory}. In addition to copying the resources to the output directory, Maven can also apply a filter to the resources that allows you to replace tokens within resource file. Just like variables are referenced in a POM using ${...} notation, you can reference variables in your project?s resources using the same syntax. Coupled with build profiles, such a facility can be used to produce build artifacts which target different deployment platforms. This is something that is common in environments which need to produce output for development, testing, staging, and production platforms from the same project. For more information about build profiles, see Chapter 5, Build Profiles.
To illustrate resource filtering, assume that you have a project with an XML file in src/main/resources/META-INF/service.xml. You want to externalize some configuration variables to a properties file. In other words, you might want to reference a JDBC URL, username, and password for your database, and you don?t want to put these values directly into the service.xml file. Instead, you would like to use a properties file to capture all of the configuration points for your program. Doing this will allow you to consolidate all configuration into a single properties file and make it easier to change configuration values when you need to target a new deployment environment. First, take a look at the contents of service.xml in src/main/resources/META-INF.
Using Properties in Project Resources.
${jdbc.url} ${jdbc.username} ${jdbc.password}
This XML file uses the same property reference syntax you can use in the POM. In fact, the first variable referenced is the project variable which is also an implicit variable made available in the POM. The project variable provides access to POM information. The next three variable references are jdbc.url, jdbc.username, and jdbc.password. These custom variables are defined in a properties file src/main/filters/default.properties.
default.properties in src/main/filters.
jdbc.url=jdbc:hsqldb:mem:mydb
jdbc.username=sa
jdbc.password=
To configure resource filtering with this default.properties file, we need to specify two things in a project?s POM: a list of properties files in the filters element of the build configuration, and a flag to Maven that the resources directory is to be filtered. The default Maven behavior is to skip filtering and just copy the resources to the output directory; you?ll need to explicitly configure resource filter, or Maven will skip the step altogether. This default ensures that Maven?s resource filtering feature doesn?t surprise you out of nowhere and clobbering any ${...} references you didn?t want it to replace.
Filter Resources (Replacing Properties).
src/main/filters/default.properties
src/main/resources true
As with all directories in Maven, the resources directory does not need to be in src/main/resources. This is just the default value defined in the Super POM. You should also note that you don?t need to consolidate all of your resources into a single directory. You can always separate resources into separate directories under src/main. Assume that you have a project which contains hundreds of XML documents and hundreds of images. Instead of mixing the resources in the src/main/resources directory, you might want to create two directories src/main/xml and src/main/images to hold this content. To add directories to the list of resource directories, you would add the following resource elements to your build configuration.
Configuring Additional Resource Directories.
... src/main/resources
src/main/xml
src/main/images
...
When you are building a project that produces a console application or a command-line tool, you?ll often find yourself writing simple shell scripts that need to reference the JAR produced by a build. When you are using the assembly plugin to produce a distribution for an application as a ZIP or TAR, you might place all of your scripts in a directory like src/main/command. In the following POM resource configuration, you?ll see how we can use resource filtering and a reference to the project variable to capture the final output name of the JAR. For more information about the Maven Assembly plugin, see Chapter 8, Maven Assemblies.
If you run mvn process-resources in this project, you will end up with two files, run.sh and run.bat, in ${basedir}. We?ve singled out these two files in a resource element, configuring filtering, and set the targetPath to be ${basedir}. In a second resource element, we?ve configured the default resources path to be copied to the default output directory without any filtering. Filtering Script Resources shows you how to declare two resource directories and supply them with different filtering and target directory preferences. The project from Filtering Script Resources would contain a run.bat file in src/main/command with the following content:
@echo off
java -jar ${project.build.finalName}.jar %*
After running mvn process-resources, a file named run.bat would appear in ${basedir} with the following content:
@echo off
java -jar simple-cmd-2.3.1.jar %*
The ability to customize filtering for specific subsets of resources is another reason why complex projects with many different kinds of resources often find it advantageous to separate resources into multiple directories. The alternative to storing different kinds of resources with different filtering requirements in different directories is to use a more complex set of include and exclude patterns to match all resource files which match a certain pattern.
4.3.2. Compile
Most lifecycles bind the Compiler plugin?s compile goal to the compile phase. This phase calls out to compile:compile which is configured to compile all of the source code and copy the bytecode to the build output directory. If you haven?t customized the values defined in the Super POM, compile:compile is going to compile everything from src/main/java to target/classes. The Compiler plugin calls out to javac and uses default source and target settings of 1.3 and 1.1. In other words, the compiler plugin assumes that your Java source conforms to Java 1.3 and that you are targeting a Java 1.1 JVM. If you would like to change these settings, you?ll need to supply the target and source configuration to the Compiler plugin in your project?s POM as shown in Setting the Source and Target Versions for the Compiler Plugin.
Setting the Source and Target Versions for the Compiler Plugin.
...
... maven-compiler-plugin 1.5 1.5
...
...
Notice we are configuring the Compiler plugin, and not the specific compile:compile goal. If we were going to configure the source and target for just the compile:compile goal, we would place the configuration element below an execution element for the compile:compile goal. We?ve configured the target and source for the plugin because compile:compile isn?t the only goal we?re interested in configuring. The Compiler plugin is reused when Maven compiles tests using the compile:testCompile goal, and configuring target and source at the plugin level allows us to define it once for all goals in a plugin.
If you need to customize the location of the source code, you can do so by changing the build configuration. If you wanted to store your project?s source code in src/java instead of src/main/java and if you wanted build output to go to classes instead of target/classes, you could always override the default sourceDirectory defined by the Super POM.
Overriding the Default Source Directory.
... src/java classes
...
Warning
While it might seem necessary to bend Maven to your own idea of project directory structure, we can?t emphasize enough that you should sacrifice your own ideas of directory structure in favor of the Maven defaults. This isn?t because we?re trying to brainwash you into accepting the Maven Way, but it will be easier for people to understand your project if it adheres to the most basic conventions. Just forget about this. Don?t do it.
4.3.3. Process Test Resources
The process-test-resources phase is almost indistinguishable from the process-resources phase. There are some trivial differences in the POM, but most everything the same. You can filter test resources just as you filter regular resources. The default location for test resources is defined in the Super POM as src/test/resources, and the default output directory for test resources is target/test-classes as defined in ${project.build.testOutputDirectory}.
4.3.4. Test Compile
The test-compile phase is almost identical to the compile phase. The only difference is that test-compile is going to invoke compile:testCompile to compile source from the test source directory to the test build output directory. If you haven?t customized the default directories from the Super POM, compile:testCompile is going to compile the source in src/test/java to the target/test-classes directory.
As with the source code directory, if you want to customize the location of the test source code and the output of test compilation, you can do so by overriding the testSourceDirectory and the testOutputDirectory. If you wanted to store test source in src-test/ instead of src/test/java and you wanted to save test bytecode to classes-test/ instead of target/test-classes, you would use the following configuration.
Overriding the Location of Test Source and Output.
... src-test classes-test
...
4.3.5. Test
Most lifecycles bind the test goal of the Surefire plugin to the test phase. The Surefire plugin is Maven?s unit testing plugin, the default behavior of Surefire is to look for all classes ending in *Test in the test source directory and to run them as JUnit tests. The Surefire plugin can also be configured to run TestNG unit tests.
After running mvn test, you should also notice that the Surefire produces a number of reports in target/surefire-reports. This reports directory will have two files for each test executed by the Surefire plugin: an XML document containing execution information for the test, and a text file containing the output of the unit test. If there is a problem during the test phase and a unit test has failed, you can use the output of Maven and the contents of this directory to track down the cause of a test failure. This surefire-reports/ directory is also used during site generation to create an easy to read summary of all the unit tests in a project.
If you are working on a project that has some failing unit tests, but you want the project to produce output, you?ll need to configure the Surefire plugin to continue a build even if it encounters a failure. The default behavior is to stop a build whenever a unit test failure is encountered. To override this behavior, you?ll need to set the testFailureIgnore configuration property on the Surefire plugin to true.
If you would like to skip tests altogether, you can do so by executing the following command:
$ mvn install -Dmaven.test.skip=true
The maven.test.skip variable controls both the Compiler and the Surefire plugin, if you pass in maven.test.skip you?ve told Maven to ignore tests altogether.
4.3.6. Install
The install goal of the Install plugin is almost always bound to the install lifecycle phase. This install:install goal simply installs a project?s main artifact to the local repository. If you have a project with a groupId of org..mavenbook, an artifactId of simple-test, and a version of 1.0.2, the install:install goal is going to copy the JAR file from target/simple-test-1.0.2.jar to ~/.m2/repository/org//mavenbook/simple-test/1.0.2/simple-test-1.0.2.jar. If the project has POM packaging, this goal will copy the POM to the local repository.
4.3.7. Deploy
The deploy goal of the Deploy plugin is usually bound to the deploy lifecycle phase. This phase is used to deploy an artifact to a remote Maven repository, this is usually required to update a remote repository when you are performing a release. The deployment procedure can be as simple as copying a file to another directory or as complex as transferring a file over SCP using a public key. Deployment settings usually involve credentials to a remote repository, and, as such, deployment settings are usually not stored in a pom.xml. Instead, deployment settings are more frequently found in an individual user?s ~/.m2/settings.xml. For now, all you need to know is that the deploy:deploy goal is bound to the deploy phase and it takes care of transporting an artifact to a published repository and updating any repository information which might be affected by such a deployment.
Prev : 4.2. Package-specific Lifecycles
TOC
Next : Chapter 5. Build Profiles
Nexus Professional
Access a live demo of the Pro Suite Install a trial version of Nexus Professional on your own machine Purchase a license for Nexus Professional
Recent Posts
Last Chance To Register: Insight for CI Demo
Insight for CI Demo: Additional Session Added
When Licenses Meet Reality, the Result is Often Confusing
How does Insight handle conflicting OSS licenses?
New Webinar: Gain Visibility & Control At Build Time with Insight for CI
56---->
Prev : 4.2. Package-specific Lifecycles
TOC
Next : Chapter 5. Build Profiles
4.3. Common Lifecycle Goals
Many of the packaging lifecycles have similar goals. If you look at the goals bound to the WAR and JAR lifecycles, you?ll see that they differ only in the package phase. The package phase of the WAR lifecycle calls war:war and the package phase of the JAR lifecycle calls jar:jar. Most of the lifecycles you will come into contact with share some common lifecycle goals for managing resources, running tests, and compiling source code. In this section, we?ll explore some of these common lifecycle goals in detail.
4.3.1. Process Resources
The process-resources phase "processes" resources and copies them to the output directory. If you haven?t customized the default directory locations defined in the Super POM, this means that Maven will copy the files from ${basedir}/src/main/resources to ${basedir}/target/classes or the directory defined in ${project.build.outputDirectory}. In addition to copying the resources to the output directory, Maven can also apply a filter to the resources that allows you to replace tokens within resource file. Just like variables are referenced in a POM using ${...} notation, you can reference variables in your project?s resources using the same syntax. Coupled with build profiles, such a facility can be used to produce build artifacts which target different deployment platforms. This is something that is common in environments which need to produce output for development, testing, staging, and production platforms from the same project. For more information about build profiles, see Chapter 5, Build Profiles.
To illustrate resource filtering, assume that you have a project with an XML file in src/main/resources/META-INF/service.xml. You want to externalize some configuration variables to a properties file. In other words, you might want to reference a JDBC URL, username, and password for your database, and you don?t want to put these values directly into the service.xml file. Instead, you would like to use a properties file to capture all of the configuration points for your program. Doing this will allow you to consolidate all configuration into a single properties file and make it easier to change configuration values when you need to target a new deployment environment. First, take a look at the contents of service.xml in src/main/resources/META-INF.
Using Properties in Project Resources.
${jdbc.url} ${jdbc.username} ${jdbc.password}
This XML file uses the same property reference syntax you can use in the POM. In fact, the first variable referenced is the project variable which is also an implicit variable made available in the POM. The project variable provides access to POM information. The next three variable references are jdbc.url, jdbc.username, and jdbc.password. These custom variables are defined in a properties file src/main/filters/default.properties.
default.properties in src/main/filters.
jdbc.url=jdbc:hsqldb:mem:mydb
jdbc.username=sa
jdbc.password=
To configure resource filtering with this default.properties file, we need to specify two things in a project?s POM: a list of properties files in the filters element of the build configuration, and a flag to Maven that the resources directory is to be filtered. The default Maven behavior is to skip filtering and just copy the resources to the output directory; you?ll need to explicitly configure resource filter, or Maven will skip the step altogether. This default ensures that Maven?s resource filtering feature doesn?t surprise you out of nowhere and clobbering any ${...} references you didn?t want it to replace.
Filter Resources (Replacing Properties).
src/main/filters/default.properties
src/main/resources true
As with all directories in Maven, the resources directory does not need to be in src/main/resources. This is just the default value defined in the Super POM. You should also note that you don?t need to consolidate all of your resources into a single directory. You can always separate resources into separate directories under src/main. Assume that you have a project which contains hundreds of XML documents and hundreds of images. Instead of mixing the resources in the src/main/resources directory, you might want to create two directories src/main/xml and src/main/images to hold this content. To add directories to the list of resource directories, you would add the following resource elements to your build configuration.
Configuring Additional Resource Directories.
... src/main/resources
src/main/xml
src/main/images
...
When you are building a project that produces a console application or a command-line tool, you?ll often find yourself writing simple shell scripts that need to reference the JAR produced by a build. When you are using the assembly plugin to produce a distribution for an application as a ZIP or TAR, you might place all of your scripts in a directory like src/main/command. In the following POM resource configuration, you?ll see how we can use resource filtering and a reference to the project variable to capture the final output name of the JAR. For more information about the Maven Assembly plugin, see Chapter 8, Maven Assemblies.
If you run mvn process-resources in this project, you will end up with two files, run.sh and run.bat, in ${basedir}. We?ve singled out these two files in a resource element, configuring filtering, and set the targetPath to be ${basedir}. In a second resource element, we?ve configured the default resources path to be copied to the default output directory without any filtering. Filtering Script Resources shows you how to declare two resource directories and supply them with different filtering and target directory preferences. The project from Filtering Script Resources would contain a run.bat file in src/main/command with the following content:
@echo off
java -jar ${project.build.finalName}.jar %*
After running mvn process-resources, a file named run.bat would appear in ${basedir} with the following content:
@echo off
java -jar simple-cmd-2.3.1.jar %*
The ability to customize filtering for specific subsets of resources is another reason why complex projects with many different kinds of resources often find it advantageous to separate resources into multiple directories. The alternative to storing different kinds of resources with different filtering requirements in different directories is to use a more complex set of include and exclude patterns to match all resource files which match a certain pattern.
4.3.2. Compile
Most lifecycles bind the Compiler plugin?s compile goal to the compile phase. This phase calls out to compile:compile which is configured to compile all of the source code and copy the bytecode to the build output directory. If you haven?t customized the values defined in the Super POM, compile:compile is going to compile everything from src/main/java to target/classes. The Compiler plugin calls out to javac and uses default source and target settings of 1.3 and 1.1. In other words, the compiler plugin assumes that your Java source conforms to Java 1.3 and that you are targeting a Java 1.1 JVM. If you would like to change these settings, you?ll need to supply the target and source configuration to the Compiler plugin in your project?s POM as shown in Setting the Source and Target Versions for the Compiler Plugin.
Setting the Source and Target Versions for the Compiler Plugin.
...
... maven-compiler-plugin 1.5 1.5
...
...
Notice we are configuring the Compiler plugin, and not the specific compile:compile goal. If we were going to configure the source and target for just the compile:compile goal, we would place the configuration element below an execution element for the compile:compile goal. We?ve configured the target and source for the plugin because compile:compile isn?t the only goal we?re interested in configuring. The Compiler plugin is reused when Maven compiles tests using the compile:testCompile goal, and configuring target and source at the plugin level allows us to define it once for all goals in a plugin.
If you need to customize the location of the source code, you can do so by changing the build configuration. If you wanted to store your project?s source code in src/java instead of src/main/java and if you wanted build output to go to classes instead of target/classes, you could always override the default sourceDirectory defined by the Super POM.
Overriding the Default Source Directory.
... src/java classes
...
Warning
While it might seem necessary to bend Maven to your own idea of project directory structure, we can?t emphasize enough that you should sacrifice your own ideas of directory structure in favor of the Maven defaults. This isn?t because we?re trying to brainwash you into accepting the Maven Way, but it will be easier for people to understand your project if it adheres to the most basic conventions. Just forget about this. Don?t do it.
4.3.3. Process Test Resources
The process-test-resources phase is almost indistinguishable from the process-resources phase. There are some trivial differences in the POM, but most everything the same. You can filter test resources just as you filter regular resources. The default location for test resources is defined in the Super POM as src/test/resources, and the default output directory for test resources is target/test-classes as defined in ${project.build.testOutputDirectory}.
4.3.4. Test Compile
The test-compile phase is almost identical to the compile phase. The only difference is that test-compile is going to invoke compile:testCompile to compile source from the test source directory to the test build output directory. If you haven?t customized the default directories from the Super POM, compile:testCompile is going to compile the source in src/test/java to the target/test-classes directory.
As with the source code directory, if you want to customize the location of the test source code and the output of test compilation, you can do so by overriding the testSourceDirectory and the testOutputDirectory. If you wanted to store test source in src-test/ instead of src/test/java and you wanted to save test bytecode to classes-test/ instead of target/test-classes, you would use the following configuration.
Overriding the Location of Test Source and Output.
... src-test classes-test
...
4.3.5. Test
Most lifecycles bind the test goal of the Surefire plugin to the test phase. The Surefire plugin is Maven?s unit testing plugin, the default behavior of Surefire is to look for all classes ending in *Test in the test source directory and to run them as JUnit tests. The Surefire plugin can also be configured to run TestNG unit tests.
After running mvn test, you should also notice that the Surefire produces a number of reports in target/surefire-reports. This reports directory will have two files for each test executed by the Surefire plugin: an XML document containing execution information for the test, and a text file containing the output of the unit test. If there is a problem during the test phase and a unit test has failed, you can use the output of Maven and the contents of this directory to track down the cause of a test failure. This surefire-reports/ directory is also used during site generation to create an easy to read summary of all the unit tests in a project.
If you are working on a project that has some failing unit tests, but you want the project to produce output, you?ll need to configure the Surefire plugin to continue a build even if it encounters a failure. The default behavior is to stop a build whenever a unit test failure is encountered. To override this behavior, you?ll need to set the testFailureIgnore configuration property on the Surefire plugin to true.
If you would like to skip tests altogether, you can do so by executing the following command:
$ mvn install -Dmaven.test.skip=true
The maven.test.skip variable controls both the Compiler and the Surefire plugin, if you pass in maven.test.skip you?ve told Maven to ignore tests altogether.
4.3.6. Install
The install goal of the Install plugin is almost always bound to the install lifecycle phase. This install:install goal simply installs a project?s main artifact to the local repository. If you have a project with a groupId of org..mavenbook, an artifactId of simple-test, and a version of 1.0.2, the install:install goal is going to copy the JAR file from target/simple-test-1.0.2.jar to ~/.m2/repository/org//mavenbook/simple-test/1.0.2/simple-test-1.0.2.jar. If the project has POM packaging, this goal will copy the POM to the local repository.
4.3.7. Deploy
The deploy goal of the Deploy plugin is usually bound to the deploy lifecycle phase. This phase is used to deploy an artifact to a remote Maven repository, this is usually required to update a remote repository when you are performing a release. The deployment procedure can be as simple as copying a file to another directory or as complex as transferring a file over SCP using a public key. Deployment settings usually involve credentials to a remote repository, and, as such, deployment settings are usually not stored in a pom.xml. Instead, deployment settings are more frequently found in an individual user?s ~/.m2/settings.xml. For now, all you need to know is that the deploy:deploy goal is bound to the deploy phase and it takes care of transporting an artifact to a published repository and updating any repository information which might be affected by such a deployment.
Prev : 4.2. Package-specific Lifecycles
TOC
Next : Chapter 5. Build Profiles
Nexus Professional
Access a live demo of the Pro Suite Install a trial version of Nexus Professional on your own machine Purchase a license for Nexus Professional
Recent Posts
Last Chance To Register: Insight for CI Demo
Insight for CI Demo: Additional Session Added
When Licenses Meet Reality, the Result is Often Confusing
How does Insight handle conflicting OSS licenses?
New Webinar: Gain Visibility & Control At Build Time with Insight for CI
57---->
Prev : 4.2. Package-specific Lifecycles
TOC
Next : Chapter 5. Build Profiles
4.3. Common Lifecycle Goals
Many of the packaging lifecycles have similar goals. If you look at the goals bound to the WAR and JAR lifecycles, you?ll see that they differ only in the package phase. The package phase of the WAR lifecycle calls war:war and the package phase of the JAR lifecycle calls jar:jar. Most of the lifecycles you will come into contact with share some common lifecycle goals for managing resources, running tests, and compiling source code. In this section, we?ll explore some of these common lifecycle goals in detail.
4.3.1. Process Resources
The process-resources phase "processes" resources and copies them to the output directory. If you haven?t customized the default directory locations defined in the Super POM, this means that Maven will copy the files from ${basedir}/src/main/resources to ${basedir}/target/classes or the directory defined in ${project.build.outputDirectory}. In addition to copying the resources to the output directory, Maven can also apply a filter to the resources that allows you to replace tokens within resource file. Just like variables are referenced in a POM using ${...} notation, you can reference variables in your project?s resources using the same syntax. Coupled with build profiles, such a facility can be used to produce build artifacts which target different deployment platforms. This is something that is common in environments which need to produce output for development, testing, staging, and production platforms from the same project. For more information about build profiles, see Chapter 5, Build Profiles.
To illustrate resource filtering, assume that you have a project with an XML file in src/main/resources/META-INF/service.xml. You want to externalize some configuration variables to a properties file. In other words, you might want to reference a JDBC URL, username, and password for your database, and you don?t want to put these values directly into the service.xml file. Instead, you would like to use a properties file to capture all of the configuration points for your program. Doing this will allow you to consolidate all configuration into a single properties file and make it easier to change configuration values when you need to target a new deployment environment. First, take a look at the contents of service.xml in src/main/resources/META-INF.
Using Properties in Project Resources.
${jdbc.url} ${jdbc.username} ${jdbc.password}
This XML file uses the same property reference syntax you can use in the POM. In fact, the first variable referenced is the project variable which is also an implicit variable made available in the POM. The project variable provides access to POM information. The next three variable references are jdbc.url, jdbc.username, and jdbc.password. These custom variables are defined in a properties file src/main/filters/default.properties.
default.properties in src/main/filters.
jdbc.url=jdbc:hsqldb:mem:mydb
jdbc.username=sa
jdbc.password=
To configure resource filtering with this default.properties file, we need to specify two things in a project?s POM: a list of properties files in the filters element of the build configuration, and a flag to Maven that the resources directory is to be filtered. The default Maven behavior is to skip filtering and just copy the resources to the output directory; you?ll need to explicitly configure resource filter, or Maven will skip the step altogether. This default ensures that Maven?s resource filtering feature doesn?t surprise you out of nowhere and clobbering any ${...} references you didn?t want it to replace.
Filter Resources (Replacing Properties).
src/main/filters/default.properties
src/main/resources true
As with all directories in Maven, the resources directory does not need to be in src/main/resources. This is just the default value defined in the Super POM. You should also note that you don?t need to consolidate all of your resources into a single directory. You can always separate resources into separate directories under src/main. Assume that you have a project which contains hundreds of XML documents and hundreds of images. Instead of mixing the resources in the src/main/resources directory, you might want to create two directories src/main/xml and src/main/images to hold this content. To add directories to the list of resource directories, you would add the following resource elements to your build configuration.
Configuring Additional Resource Directories.
... src/main/resources
src/main/xml
src/main/images
...
When you are building a project that produces a console application or a command-line tool, you?ll often find yourself writing simple shell scripts that need to reference the JAR produced by a build. When you are using the assembly plugin to produce a distribution for an application as a ZIP or TAR, you might place all of your scripts in a directory like src/main/command. In the following POM resource configuration, you?ll see how we can use resource filtering and a reference to the project variable to capture the final output name of the JAR. For more information about the Maven Assembly plugin, see Chapter 8, Maven Assemblies.
If you run mvn process-resources in this project, you will end up with two files, run.sh and run.bat, in ${basedir}. We?ve singled out these two files in a resource element, configuring filtering, and set the targetPath to be ${basedir}. In a second resource element, we?ve configured the default resources path to be copied to the default output directory without any filtering. Filtering Script Resources shows you how to declare two resource directories and supply them with different filtering and target directory preferences. The project from Filtering Script Resources would contain a run.bat file in src/main/command with the following content:
@echo off
java -jar ${project.build.finalName}.jar %*
After running mvn process-resources, a file named run.bat would appear in ${basedir} with the following content:
@echo off
java -jar simple-cmd-2.3.1.jar %*
The ability to customize filtering for specific subsets of resources is another reason why complex projects with many different kinds of resources often find it advantageous to separate resources into multiple directories. The alternative to storing different kinds of resources with different filtering requirements in different directories is to use a more complex set of include and exclude patterns to match all resource files which match a certain pattern.
4.3.2. Compile
Most lifecycles bind the Compiler plugin?s compile goal to the compile phase. This phase calls out to compile:compile which is configured to compile all of the source code and copy the bytecode to the build output directory. If you haven?t customized the values defined in the Super POM, compile:compile is going to compile everything from src/main/java to target/classes. The Compiler plugin calls out to javac and uses default source and target settings of 1.3 and 1.1. In other words, the compiler plugin assumes that your Java source conforms to Java 1.3 and that you are targeting a Java 1.1 JVM. If you would like to change these settings, you?ll need to supply the target and source configuration to the Compiler plugin in your project?s POM as shown in Setting the Source and Target Versions for the Compiler Plugin.
Setting the Source and Target Versions for the Compiler Plugin.
...
... maven-compiler-plugin 1.5 1.5
...
...
Notice we are configuring the Compiler plugin, and not the specific compile:compile goal. If we were going to configure the source and target for just the compile:compile goal, we would place the configuration element below an execution element for the compile:compile goal. We?ve configured the target and source for the plugin because compile:compile isn?t the only goal we?re interested in configuring. The Compiler plugin is reused when Maven compiles tests using the compile:testCompile goal, and configuring target and source at the plugin level allows us to define it once for all goals in a plugin.
If you need to customize the location of the source code, you can do so by changing the build configuration. If you wanted to store your project?s source code in src/java instead of src/main/java and if you wanted build output to go to classes instead of target/classes, you could always override the default sourceDirectory defined by the Super POM.
Overriding the Default Source Directory.
... src/java classes
...
Warning
While it might seem necessary to bend Maven to your own idea of project directory structure, we can?t emphasize enough that you should sacrifice your own ideas of directory structure in favor of the Maven defaults. This isn?t because we?re trying to brainwash you into accepting the Maven Way, but it will be easier for people to understand your project if it adheres to the most basic conventions. Just forget about this. Don?t do it.
4.3.3. Process Test Resources
The process-test-resources phase is almost indistinguishable from the process-resources phase. There are some trivial differences in the POM, but most everything the same. You can filter test resources just as you filter regular resources. The default location for test resources is defined in the Super POM as src/test/resources, and the default output directory for test resources is target/test-classes as defined in ${project.build.testOutputDirectory}.
4.3.4. Test Compile
The test-compile phase is almost identical to the compile phase. The only difference is that test-compile is going to invoke compile:testCompile to compile source from the test source directory to the test build output directory. If you haven?t customized the default directories from the Super POM, compile:testCompile is going to compile the source in src/test/java to the target/test-classes directory.
As with the source code directory, if you want to customize the location of the test source code and the output of test compilation, you can do so by overriding the testSourceDirectory and the testOutputDirectory. If you wanted to store test source in src-test/ instead of src/test/java and you wanted to save test bytecode to classes-test/ instead of target/test-classes, you would use the following configuration.
Overriding the Location of Test Source and Output.
... src-test classes-test
...
4.3.5. Test
Most lifecycles bind the test goal of the Surefire plugin to the test phase. The Surefire plugin is Maven?s unit testing plugin, the default behavior of Surefire is to look for all classes ending in *Test in the test source directory and to run them as JUnit tests. The Surefire plugin can also be configured to run TestNG unit tests.
After running mvn test, you should also notice that the Surefire produces a number of reports in target/surefire-reports. This reports directory will have two files for each test executed by the Surefire plugin: an XML document containing execution information for the test, and a text file containing the output of the unit test. If there is a problem during the test phase and a unit test has failed, you can use the output of Maven and the contents of this directory to track down the cause of a test failure. This surefire-reports/ directory is also used during site generation to create an easy to read summary of all the unit tests in a project.
If you are working on a project that has some failing unit tests, but you want the project to produce output, you?ll need to configure the Surefire plugin to continue a build even if it encounters a failure. The default behavior is to stop a build whenever a unit test failure is encountered. To override this behavior, you?ll need to set the testFailureIgnore configuration property on the Surefire plugin to true.
If you would like to skip tests altogether, you can do so by executing the following command:
$ mvn install -Dmaven.test.skip=true
The maven.test.skip variable controls both the Compiler and the Surefire plugin, if you pass in maven.test.skip you?ve told Maven to ignore tests altogether.
4.3.6. Install
The install goal of the Install plugin is almost always bound to the install lifecycle phase. This install:install goal simply installs a project?s main artifact to the local repository. If you have a project with a groupId of org..mavenbook, an artifactId of simple-test, and a version of 1.0.2, the install:install goal is going to copy the JAR file from target/simple-test-1.0.2.jar to ~/.m2/repository/org//mavenbook/simple-test/1.0.2/simple-test-1.0.2.jar. If the project has POM packaging, this goal will copy the POM to the local repository.
4.3.7. Deploy
The deploy goal of the Deploy plugin is usually bound to the deploy lifecycle phase. This phase is used to deploy an artifact to a remote Maven repository, this is usually required to update a remote repository when you are performing a release. The deployment procedure can be as simple as copying a file to another directory or as complex as transferring a file over SCP using a public key. Deployment settings usually involve credentials to a remote repository, and, as such, deployment settings are usually not stored in a pom.xml. Instead, deployment settings are more frequently found in an individual user?s ~/.m2/settings.xml. For now, all you need to know is that the deploy:deploy goal is bound to the deploy phase and it takes care of transporting an artifact to a published repository and updating any repository information which might be affected by such a deployment.
Prev : 4.2. Package-specific Lifecycles
TOC
Next : Chapter 5. Build Profiles
Nexus Professional
Access a live demo of the Pro Suite Install a trial version of Nexus Professional on your own machine Purchase a license for Nexus Professional
Recent Posts
Last Chance To Register: Insight for CI Demo
Insight for CI Demo: Additional Session Added
When Licenses Meet Reality, the Result is Often Confusing
How does Insight handle conflicting OSS licenses?
New Webinar: Gain Visibility & Control At Build Time with Insight for CI
58---->
Prev : 4.2. Package-specific Lifecycles
TOC
Next : Chapter 5. Build Profiles
4.3. Common Lifecycle Goals
Many of the packaging lifecycles have similar goals. If you look at the goals bound to the WAR and JAR lifecycles, you?ll see that they differ only in the package phase. The package phase of the WAR lifecycle calls war:war and the package phase of the JAR lifecycle calls jar:jar. Most of the lifecycles you will come into contact with share some common lifecycle goals for managing resources, running tests, and compiling source code. In this section, we?ll explore some of these common lifecycle goals in detail.
4.3.1. Process Resources
The process-resources phase "processes" resources and copies them to the output directory. If you haven?t customized the default directory locations defined in the Super POM, this means that Maven will copy the files from ${basedir}/src/main/resources to ${basedir}/target/classes or the directory defined in ${project.build.outputDirectory}. In addition to copying the resources to the output directory, Maven can also apply a filter to the resources that allows you to replace tokens within resource file. Just like variables are referenced in a POM using ${...} notation, you can reference variables in your project?s resources using the same syntax. Coupled with build profiles, such a facility can be used to produce build artifacts which target different deployment platforms. This is something that is common in environments which need to produce output for development, testing, staging, and production platforms from the same project. For more information about build profiles, see Chapter 5, Build Profiles.
To illustrate resource filtering, assume that you have a project with an XML file in src/main/resources/META-INF/service.xml. You want to externalize some configuration variables to a properties file. In other words, you might want to reference a JDBC URL, username, and password for your database, and you don?t want to put these values directly into the service.xml file. Instead, you would like to use a properties file to capture all of the configuration points for your program. Doing this will allow you to consolidate all configuration into a single properties file and make it easier to change configuration values when you need to target a new deployment environment. First, take a look at the contents of service.xml in src/main/resources/META-INF.
Using Properties in Project Resources.
${jdbc.url} ${jdbc.username} ${jdbc.password}
This XML file uses the same property reference syntax you can use in the POM. In fact, the first variable referenced is the project variable which is also an implicit variable made available in the POM. The project variable provides access to POM information. The next three variable references are jdbc.url, jdbc.username, and jdbc.password. These custom variables are defined in a properties file src/main/filters/default.properties.
default.properties in src/main/filters.
jdbc.url=jdbc:hsqldb:mem:mydb
jdbc.username=sa
jdbc.password=
To configure resource filtering with this default.properties file, we need to specify two things in a project?s POM: a list of properties files in the filters element of the build configuration, and a flag to Maven that the resources directory is to be filtered. The default Maven behavior is to skip filtering and just copy the resources to the output directory; you?ll need to explicitly configure resource filter, or Maven will skip the step altogether. This default ensures that Maven?s resource filtering feature doesn?t surprise you out of nowhere and clobbering any ${...} references you didn?t want it to replace.
Filter Resources (Replacing Properties).
src/main/filters/default.properties
src/main/resources true
As with all directories in Maven, the resources directory does not need to be in src/main/resources. This is just the default value defined in the Super POM. You should also note that you don?t need to consolidate all of your resources into a single directory. You can always separate resources into separate directories under src/main. Assume that you have a project which contains hundreds of XML documents and hundreds of images. Instead of mixing the resources in the src/main/resources directory, you might want to create two directories src/main/xml and src/main/images to hold this content. To add directories to the list of resource directories, you would add the following resource elements to your build configuration.
Configuring Additional Resource Directories.
... src/main/resources
src/main/xml
src/main/images
...
When you are building a project that produces a console application or a command-line tool, you?ll often find yourself writing simple shell scripts that need to reference the JAR produced by a build. When you are using the assembly plugin to produce a distribution for an application as a ZIP or TAR, you might place all of your scripts in a directory like src/main/command. In the following POM resource configuration, you?ll see how we can use resource filtering and a reference to the project variable to capture the final output name of the JAR. For more information about the Maven Assembly plugin, see Chapter 8, Maven Assemblies.
If you run mvn process-resources in this project, you will end up with two files, run.sh and run.bat, in ${basedir}. We?ve singled out these two files in a resource element, configuring filtering, and set the targetPath to be ${basedir}. In a second resource element, we?ve configured the default resources path to be copied to the default output directory without any filtering. Filtering Script Resources shows you how to declare two resource directories and supply them with different filtering and target directory preferences. The project from Filtering Script Resources would contain a run.bat file in src/main/command with the following content:
@echo off
java -jar ${project.build.finalName}.jar %*
After running mvn process-resources, a file named run.bat would appear in ${basedir} with the following content:
@echo off
java -jar simple-cmd-2.3.1.jar %*
The ability to customize filtering for specific subsets of resources is another reason why complex projects with many different kinds of resources often find it advantageous to separate resources into multiple directories. The alternative to storing different kinds of resources with different filtering requirements in different directories is to use a more complex set of include and exclude patterns to match all resource files which match a certain pattern.
4.3.2. Compile
Most lifecycles bind the Compiler plugin?s compile goal to the compile phase. This phase calls out to compile:compile which is configured to compile all of the source code and copy the bytecode to the build output directory. If you haven?t customized the values defined in the Super POM, compile:compile is going to compile everything from src/main/java to target/classes. The Compiler plugin calls out to javac and uses default source and target settings of 1.3 and 1.1. In other words, the compiler plugin assumes that your Java source conforms to Java 1.3 and that you are targeting a Java 1.1 JVM. If you would like to change these settings, you?ll need to supply the target and source configuration to the Compiler plugin in your project?s POM as shown in Setting the Source and Target Versions for the Compiler Plugin.
Setting the Source and Target Versions for the Compiler Plugin.
...
... maven-compiler-plugin 1.5 1.5
...
...
Notice we are configuring the Compiler plugin, and not the specific compile:compile goal. If we were going to configure the source and target for just the compile:compile goal, we would place the configuration element below an execution element for the compile:compile goal. We?ve configured the target and source for the plugin because compile:compile isn?t the only goal we?re interested in configuring. The Compiler plugin is reused when Maven compiles tests using the compile:testCompile goal, and configuring target and source at the plugin level allows us to define it once for all goals in a plugin.
If you need to customize the location of the source code, you can do so by changing the build configuration. If you wanted to store your project?s source code in src/java instead of src/main/java and if you wanted build output to go to classes instead of target/classes, you could always override the default sourceDirectory defined by the Super POM.
Overriding the Default Source Directory.
... src/java classes
...
Warning
While it might seem necessary to bend Maven to your own idea of project directory structure, we can?t emphasize enough that you should sacrifice your own ideas of directory structure in favor of the Maven defaults. This isn?t because we?re trying to brainwash you into accepting the Maven Way, but it will be easier for people to understand your project if it adheres to the most basic conventions. Just forget about this. Don?t do it.
4.3.3. Process Test Resources
The process-test-resources phase is almost indistinguishable from the process-resources phase. There are some trivial differences in the POM, but most everything the same. You can filter test resources just as you filter regular resources. The default location for test resources is defined in the Super POM as src/test/resources, and the default output directory for test resources is target/test-classes as defined in ${project.build.testOutputDirectory}.
4.3.4. Test Compile
The test-compile phase is almost identical to the compile phase. The only difference is that test-compile is going to invoke compile:testCompile to compile source from the test source directory to the test build output directory. If you haven?t customized the default directories from the Super POM, compile:testCompile is going to compile the source in src/test/java to the target/test-classes directory.
As with the source code directory, if you want to customize the location of the test source code and the output of test compilation, you can do so by overriding the testSourceDirectory and the testOutputDirectory. If you wanted to store test source in src-test/ instead of src/test/java and you wanted to save test bytecode to classes-test/ instead of target/test-classes, you would use the following configuration.
Overriding the Location of Test Source and Output.
... src-test classes-test
...
4.3.5. Test
Most lifecycles bind the test goal of the Surefire plugin to the test phase. The Surefire plugin is Maven?s unit testing plugin, the default behavior of Surefire is to look for all classes ending in *Test in the test source directory and to run them as JUnit tests. The Surefire plugin can also be configured to run TestNG unit tests.
After running mvn test, you should also notice that the Surefire produces a number of reports in target/surefire-reports. This reports directory will have two files for each test executed by the Surefire plugin: an XML document containing execution information for the test, and a text file containing the output of the unit test. If there is a problem during the test phase and a unit test has failed, you can use the output of Maven and the contents of this directory to track down the cause of a test failure. This surefire-reports/ directory is also used during site generation to create an easy to read summary of all the unit tests in a project.
If you are working on a project that has some failing unit tests, but you want the project to produce output, you?ll need to configure the Surefire plugin to continue a build even if it encounters a failure. The default behavior is to stop a build whenever a unit test failure is encountered. To override this behavior, you?ll need to set the testFailureIgnore configuration property on the Surefire plugin to true.
If you would like to skip tests altogether, you can do so by executing the following command:
$ mvn install -Dmaven.test.skip=true
The maven.test.skip variable controls both the Compiler and the Surefire plugin, if you pass in maven.test.skip you?ve told Maven to ignore tests altogether.
4.3.6. Install
The install goal of the Install plugin is almost always bound to the install lifecycle phase. This install:install goal simply installs a project?s main artifact to the local repository. If you have a project with a groupId of org..mavenbook, an artifactId of simple-test, and a version of 1.0.2, the install:install goal is going to copy the JAR file from target/simple-test-1.0.2.jar to ~/.m2/repository/org//mavenbook/simple-test/1.0.2/simple-test-1.0.2.jar. If the project has POM packaging, this goal will copy the POM to the local repository.
4.3.7. Deploy
The deploy goal of the Deploy plugin is usually bound to the deploy lifecycle phase. This phase is used to deploy an artifact to a remote Maven repository, this is usually required to update a remote repository when you are performing a release. The deployment procedure can be as simple as copying a file to another directory or as complex as transferring a file over SCP using a public key. Deployment settings usually involve credentials to a remote repository, and, as such, deployment settings are usually not stored in a pom.xml. Instead, deployment settings are more frequently found in an individual user?s ~/.m2/settings.xml. For now, all you need to know is that the deploy:deploy goal is bound to the deploy phase and it takes care of transporting an artifact to a published repository and updating any repository information which might be affected by such a deployment.
Prev : 4.2. Package-specific Lifecycles
TOC
Next : Chapter 5. Build Profiles
Nexus Professional
Access a live demo of the Pro Suite Install a trial version of Nexus Professional on your own machine Purchase a license for Nexus Professional
Recent Posts
Last Chance To Register: Insight for CI Demo
Insight for CI Demo: Additional Session Added
When Licenses Meet Reality, the Result is Often Confusing
How does Insight handle conflicting OSS licenses?
New Webinar: Gain Visibility & Control At Build Time with Insight for CI
59---->
Prev : 4.1. Introduction
TOC
Next : 4.3. Common Lifecycle Goals
4.2. Package-specific Lifecycles
The specific goals bound to each phase default to a set of goals specific to a project?s packaging. A project with packaging jar has a different set of default goals from a project with a packaging of war. The packaging element affects the steps required to build a project. For an example of how the packaging affects the build, consider two projects: one with pom packaging and the other with jar packaging. The project with pom packaging will run the site:attach-descriptor goal during the package phase, and the project with jar packaging will run the jar:jar goal instead.
The following sections describe the lifecycle for all built-in packaging types in Maven. Use these sections to find out what default goals are mapped to default lifecycle phases.
4.2.1. JAR
JAR is the default packaging type, the most common, and thus the most commonly encountered lifecycle configuration. The default goals for the JAR lifecycle are shown in Table 4.2, ?Default Goals for JAR Packaging?.
Table 4.2. Default Goals for JAR Packaging
Lifecycle Phase
Goal
process-resources
resources:resources
compile
compiler:compile
process-test-resources
resources:testResources
test-compile
compiler:testCompile
test
surefire:test
package
jar:jar
install
install:install
deploy
deploy:deploy
4.2.2. POM
POM is the simplest packaging type. The artifact that it generates is itself only, rather than a JAR, SAR, or EAR. There is no code to test or compile, and there are no resources the process. The default goals for projects with POM packaging are shown in Table 4.3, ?Default Goals for POM Packaging?.
Table 4.3. Default Goals for POM Packaging
Lifecycle Phase
Goal
package
site:attach-descriptor
install
install:install
deploy
deploy:deploy
4.2.3. Maven Plugin
This packaging type is similar to JAR packaging type with three additions: plugin:descriptor, plugin:addPluginArtifactMetadata, and plugin:updateRegistry. These goals generate a descriptor file and perform some modifications to the repository data. The default goals for projects with plugin packaging are shown in Table 4.4, ?Default Goals for Plugin Packaging?.
Table 4.4. Default Goals for Plugin Packaging
Lifecycle Phase
Goal
generate-resources
plugin:descriptor
process-resources
resources:resources
compile
compiler:compile
process-test-resources
resources:testResources
test-compile
compiler:testCompile
test
surefire:test
package
jar:jar, plugin:addPluginArtifactMetadata
install
install:install, plugin:updateRegistry
deploy
deploy:deploy
4.2.4. EJB
EJBs, or Enterprise Java Beans, are a common data access mechanism for model-driven development in Enterprise Java. Maven provides support for EJB 2 and 3. Though you must configure the EJB plugin to specifically package for EJB3, else the plugin defaults to 2.1 and looks for the presence of certain EJB configuration files. The default goals for projects with EJB packaging are shown in Table 4.5, ?Default Goals for EJB Packaging?.
Table 4.5. Default Goals for EJB Packaging
Lifecycle Phase
Goal
process-resources
resources:resources
compile
compiler:compile
process-test-resources
resources:testResources
test-compile
compiler:testCompile
test
surefire:test
package
ejb:ejb
install
install:install
deploy
deploy:deploy
4.2.5. WAR
The WAR packaging type is similar to the JAR and EJB types. The exception being the package goal of war:war. Note that the war:war goal requires a web.xml configuration in your src/main/webapp/WEB-INF directory. The default goals for projects with WAR packaging are shown in Table 4.6, ?Default Goals for WAR Packaging?.
Table 4.6. Default Goals for WAR Packaging
Lifecycle Phase
Goal
process-resources
resources:resources
compile
compiler:compile
process-test-resources
resources:testResources
test-compile
compiler:testCompile
test
surefire:test
package
war:war
install
install:install
deploy
deploy:deploy
4.2.6. EAR
EARs are probably the simplest Java EE constructs, consisting primarily of the deployment descriptor application.xml file, some resources and some modules. The EAR plugin has a goal named generate-application-xml which generates the application.xml based upon the configuration in the EAR project?s POM. The default goals for projects with EAR packaging are shown in Table 4.7, ?Default Goals for EAR Packaging?.
Table 4.7. Default Goals for EAR Packaging
Lifecycle Phase
Goal
generate-resources
ear:generate-application-xml
process-resources
resources:resources
package
ear:ear
install
install:install
deploy
deploy:deploy
4.2.7. Other Packaging Types
This is not an exhaustive list of every packaging type available for Maven. There are a number of packaging formats available through external projects and plugins: the NAR (native archive) packaging type, the SWF and SWC packaging types for projects that produce Adobe Flash and Flex content, and many others. You can also define a custom packaging type and customize the default lifecycle goals to suit your own project packaging requirements.
To use one of these custom packaging types, you need two things: a plugin which defines the lifecycle for a custom packaging type and a repository which contains this plugin. Some custom packaging types are defined in plugins available from the central Maven repository. Here is an example of a project which references the Israfil Flex plugin and uses a custom packaging type of SWF to produce output from Adobe Flex source.
In Section 11.6, ?Plugins and the Maven Lifecycle?, we show you how to create your own packaging type with a customized lifecycle. This example should give you an idea of what you?ll need to do to reference a custom packaging type. All you need to do is reference the plugin which supplies the custom packaging type. The Israfil Flex plugin is a third-party Maven plugin hosted at Google Code, for more information about this plugin and how to use Maven to compile Adobe Flex go to http://code.google.com/p/israfil-mojo. This plugin supplies the following lifecycle for the SWF packaging type:
Table 4.8. Default Lifecycle for SWF Packaging
Lifecycle Phase
Goal
compile
flex2:compile-swc
install
install:install
deploy
deploy:deploy
Prev : 4.1. Introduction
TOC
Next : 4.3. Common Lifecycle Goals
Nexus Professional
Access a live demo of the Pro Suite Install a trial version of Nexus Professional on your own machine Purchase a license for Nexus Professional
Recent Posts
Last Chance To Register: Insight for CI Demo
Insight for CI Demo: Additional Session Added
When Licenses Meet Reality, the Result is Often Confusing
How does Insight handle conflicting OSS licenses?
New Webinar: Gain Visibility & Control At Build Time with Insight for CI
60---->
Prev : 4.1. Introduction
TOC
Next : 4.3. Common Lifecycle Goals
4.2. Package-specific Lifecycles
The specific goals bound to each phase default to a set of goals specific to a project?s packaging. A project with packaging jar has a different set of default goals from a project with a packaging of war. The packaging element affects the steps required to build a project. For an example of how the packaging affects the build, consider two projects: one with pom packaging and the other with jar packaging. The project with pom packaging will run the site:attach-descriptor goal during the package phase, and the project with jar packaging will run the jar:jar goal instead.
The following sections describe the lifecycle for all built-in packaging types in Maven. Use these sections to find out what default goals are mapped to default lifecycle phases.
4.2.1. JAR
JAR is the default packaging type, the most common, and thus the most commonly encountered lifecycle configuration. The default goals for the JAR lifecycle are shown in Table 4.2, ?Default Goals for JAR Packaging?.
Table 4.2. Default Goals for JAR Packaging
Lifecycle Phase
Goal
process-resources
resources:resources
compile
compiler:compile
process-test-resources
resources:testResources
test-compile
compiler:testCompile
test
surefire:test
package
jar:jar
install
install:install
deploy
deploy:deploy
4.2.2. POM
POM is the simplest packaging type. The artifact that it generates is itself only, rather than a JAR, SAR, or EAR. There is no code to test or compile, and there are no resources the process. The default goals for projects with POM packaging are shown in Table 4.3, ?Default Goals for POM Packaging?.
Table 4.3. Default Goals for POM Packaging
Lifecycle Phase
Goal
package
site:attach-descriptor
install
install:install
deploy
deploy:deploy
4.2.3. Maven Plugin
This packaging type is similar to JAR packaging type with three additions: plugin:descriptor, plugin:addPluginArtifactMetadata, and plugin:updateRegistry. These goals generate a descriptor file and perform some modifications to the repository data. The default goals for projects with plugin packaging are shown in Table 4.4, ?Default Goals for Plugin Packaging?.
Table 4.4. Default Goals for Plugin Packaging
Lifecycle Phase
Goal
generate-resources
plugin:descriptor
process-resources
resources:resources
compile
compiler:compile
process-test-resources
resources:testResources
test-compile
compiler:testCompile
test
surefire:test
package
jar:jar, plugin:addPluginArtifactMetadata
install
install:install, plugin:updateRegistry
deploy
deploy:deploy
4.2.4. EJB
EJBs, or Enterprise Java Beans, are a common data access mechanism for model-driven development in Enterprise Java. Maven provides support for EJB 2 and 3. Though you must configure the EJB plugin to specifically package for EJB3, else the plugin defaults to 2.1 and looks for the presence of certain EJB configuration files. The default goals for projects with EJB packaging are shown in Table 4.5, ?Default Goals for EJB Packaging?.
Table 4.5. Default Goals for EJB Packaging
Lifecycle Phase
Goal
process-resources
resources:resources
compile
compiler:compile
process-test-resources
resources:testResources
test-compile
compiler:testCompile
test
surefire:test
package
ejb:ejb
install
install:install
deploy
deploy:deploy
4.2.5. WAR
The WAR packaging type is similar to the JAR and EJB types. The exception being the package goal of war:war. Note that the war:war goal requires a web.xml configuration in your src/main/webapp/WEB-INF directory. The default goals for projects with WAR packaging are shown in Table 4.6, ?Default Goals for WAR Packaging?.
Table 4.6. Default Goals for WAR Packaging
Lifecycle Phase
Goal
process-resources
resources:resources
compile
compiler:compile
process-test-resources
resources:testResources
test-compile
compiler:testCompile
test
surefire:test
package
war:war
install
install:install
deploy
deploy:deploy
4.2.6. EAR
EARs are probably the simplest Java EE constructs, consisting primarily of the deployment descriptor application.xml file, some resources and some modules. The EAR plugin has a goal named generate-application-xml which generates the application.xml based upon the configuration in the EAR project?s POM. The default goals for projects with EAR packaging are shown in Table 4.7, ?Default Goals for EAR Packaging?.
Table 4.7. Default Goals for EAR Packaging
Lifecycle Phase
Goal
generate-resources
ear:generate-application-xml
process-resources
resources:resources
package
ear:ear
install
install:install
deploy
deploy:deploy
4.2.7. Other Packaging Types
This is not an exhaustive list of every packaging type available for Maven. There are a number of packaging formats available through external projects and plugins: the NAR (native archive) packaging type, the SWF and SWC packaging types for projects that produce Adobe Flash and Flex content, and many others. You can also define a custom packaging type and customize the default lifecycle goals to suit your own project packaging requirements.
To use one of these custom packaging types, you need two things: a plugin which defines the lifecycle for a custom packaging type and a repository which contains this plugin. Some custom packaging types are defined in plugins available from the central Maven repository. Here is an example of a project which references the Israfil Flex plugin and uses a custom packaging type of SWF to produce output from Adobe Flex source.
In Section 11.6, ?Plugins and the Maven Lifecycle?, we show you how to create your own packaging type with a customized lifecycle. This example should give you an idea of what you?ll need to do to reference a custom packaging type. All you need to do is reference the plugin which supplies the custom packaging type. The Israfil Flex plugin is a third-party Maven plugin hosted at Google Code, for more information about this plugin and how to use Maven to compile Adobe Flex go to http://code.google.com/p/israfil-mojo. This plugin supplies the following lifecycle for the SWF packaging type:
Table 4.8. Default Lifecycle for SWF Packaging
Lifecycle Phase
Goal
compile
flex2:compile-swc
install
install:install
deploy
deploy:deploy
Prev : 4.1. Introduction
TOC
Next : 4.3. Common Lifecycle Goals
Nexus Professional
Access a live demo of the Pro Suite Install a trial version of Nexus Professional on your own machine Purchase a license for Nexus Professional
Recent Posts
Last Chance To Register: Insight for CI Demo
Insight for CI Demo: Additional Session Added
When Licenses Meet Reality, the Result is Often Confusing
How does Insight handle conflicting OSS licenses?
New Webinar: Gain Visibility & Control At Build Time with Insight for CI
61---->
Prev : 4.1. Introduction
TOC
Next : 4.3. Common Lifecycle Goals
4.2. Package-specific Lifecycles
The specific goals bound to each phase default to a set of goals specific to a project?s packaging. A project with packaging jar has a different set of default goals from a project with a packaging of war. The packaging element affects the steps required to build a project. For an example of how the packaging affects the build, consider two projects: one with pom packaging and the other with jar packaging. The project with pom packaging will run the site:attach-descriptor goal during the package phase, and the project with jar packaging will run the jar:jar goal instead.
The following sections describe the lifecycle for all built-in packaging types in Maven. Use these sections to find out what default goals are mapped to default lifecycle phases.
4.2.1. JAR
JAR is the default packaging type, the most common, and thus the most commonly encountered lifecycle configuration. The default goals for the JAR lifecycle are shown in Table 4.2, ?Default Goals for JAR Packaging?.
Table 4.2. Default Goals for JAR Packaging
Lifecycle Phase
Goal
process-resources
resources:resources
compile
compiler:compile
process-test-resources
resources:testResources
test-compile
compiler:testCompile
test
surefire:test
package
jar:jar
install
install:install
deploy
deploy:deploy
4.2.2. POM
POM is the simplest packaging type. The artifact that it generates is itself only, rather than a JAR, SAR, or EAR. There is no code to test or compile, and there are no resources the process. The default goals for projects with POM packaging are shown in Table 4.3, ?Default Goals for POM Packaging?.
Table 4.3. Default Goals for POM Packaging
Lifecycle Phase
Goal
package
site:attach-descriptor
install
install:install
deploy
deploy:deploy
4.2.3. Maven Plugin
This packaging type is similar to JAR packaging type with three additions: plugin:descriptor, plugin:addPluginArtifactMetadata, and plugin:updateRegistry. These goals generate a descriptor file and perform some modifications to the repository data. The default goals for projects with plugin packaging are shown in Table 4.4, ?Default Goals for Plugin Packaging?.
Table 4.4. Default Goals for Plugin Packaging
Lifecycle Phase
Goal
generate-resources
plugin:descriptor
process-resources
resources:resources
compile
compiler:compile
process-test-resources
resources:testResources
test-compile
compiler:testCompile
test
surefire:test
package
jar:jar, plugin:addPluginArtifactMetadata
install
install:install, plugin:updateRegistry
deploy
deploy:deploy
4.2.4. EJB
EJBs, or Enterprise Java Beans, are a common data access mechanism for model-driven development in Enterprise Java. Maven provides support for EJB 2 and 3. Though you must configure the EJB plugin to specifically package for EJB3, else the plugin defaults to 2.1 and looks for the presence of certain EJB configuration files. The default goals for projects with EJB packaging are shown in Table 4.5, ?Default Goals for EJB Packaging?.
Table 4.5. Default Goals for EJB Packaging
Lifecycle Phase
Goal
process-resources
resources:resources
compile
compiler:compile
process-test-resources
resources:testResources
test-compile
compiler:testCompile
test
surefire:test
package
ejb:ejb
install
install:install
deploy
deploy:deploy
4.2.5. WAR
The WAR packaging type is similar to the JAR and EJB types. The exception being the package goal of war:war. Note that the war:war goal requires a web.xml configuration in your src/main/webapp/WEB-INF directory. The default goals for projects with WAR packaging are shown in Table 4.6, ?Default Goals for WAR Packaging?.
Table 4.6. Default Goals for WAR Packaging
Lifecycle Phase
Goal
process-resources
resources:resources
compile
compiler:compile
process-test-resources
resources:testResources
test-compile
compiler:testCompile
test
surefire:test
package
war:war
install
install:install
deploy
deploy:deploy
4.2.6. EAR
EARs are probably the simplest Java EE constructs, consisting primarily of the deployment descriptor application.xml file, some resources and some modules. The EAR plugin has a goal named generate-application-xml which generates the application.xml based upon the configuration in the EAR project?s POM. The default goals for projects with EAR packaging are shown in Table 4.7, ?Default Goals for EAR Packaging?.
Table 4.7. Default Goals for EAR Packaging
Lifecycle Phase
Goal
generate-resources
ear:generate-application-xml
process-resources
resources:resources
package
ear:ear
install
install:install
deploy
deploy:deploy
4.2.7. Other Packaging Types
This is not an exhaustive list of every packaging type available for Maven. There are a number of packaging formats available through external projects and plugins: the NAR (native archive) packaging type, the SWF and SWC packaging types for projects that produce Adobe Flash and Flex content, and many others. You can also define a custom packaging type and customize the default lifecycle goals to suit your own project packaging requirements.
To use one of these custom packaging types, you need two things: a plugin which defines the lifecycle for a custom packaging type and a repository which contains this plugin. Some custom packaging types are defined in plugins available from the central Maven repository. Here is an example of a project which references the Israfil Flex plugin and uses a custom packaging type of SWF to produce output from Adobe Flex source.
In Section 11.6, ?Plugins and the Maven Lifecycle?, we show you how to create your own packaging type with a customized lifecycle. This example should give you an idea of what you?ll need to do to reference a custom packaging type. All you need to do is reference the plugin which supplies the custom packaging type. The Israfil Flex plugin is a third-party Maven plugin hosted at Google Code, for more information about this plugin and how to use Maven to compile Adobe Flex go to http://code.google.com/p/israfil-mojo. This plugin supplies the following lifecycle for the SWF packaging type:
Table 4.8. Default Lifecycle for SWF Packaging
Lifecycle Phase
Goal
compile
flex2:compile-swc
install
install:install
deploy
deploy:deploy
Prev : 4.1. Introduction
TOC
Next : 4.3. Common Lifecycle Goals
Nexus Professional
Access a live demo of the Pro Suite Install a trial version of Nexus Professional on your own machine Purchase a license for Nexus Professional
Recent Posts
Last Chance To Register: Insight for CI Demo
Insight for CI Demo: Additional Session Added
When Licenses Meet Reality, the Result is Often Confusing
How does Insight handle conflicting OSS licenses?
New Webinar: Gain Visibility & Control At Build Time with Insight for CI
62---->
Prev : 4.1. Introduction
TOC
Next : 4.3. Common Lifecycle Goals
4.2. Package-specific Lifecycles
The specific goals bound to each phase default to a set of goals specific to a project?s packaging. A project with packaging jar has a different set of default goals from a project with a packaging of war. The packaging element affects the steps required to build a project. For an example of how the packaging affects the build, consider two projects: one with pom packaging and the other with jar packaging. The project with pom packaging will run the site:attach-descriptor goal during the package phase, and the project with jar packaging will run the jar:jar goal instead.
The following sections describe the lifecycle for all built-in packaging types in Maven. Use these sections to find out what default goals are mapped to default lifecycle phases.
4.2.1. JAR
JAR is the default packaging type, the most common, and thus the most commonly encountered lifecycle configuration. The default goals for the JAR lifecycle are shown in Table 4.2, ?Default Goals for JAR Packaging?.
Table 4.2. Default Goals for JAR Packaging
Lifecycle Phase
Goal
process-resources
resources:resources
compile
compiler:compile
process-test-resources
resources:testResources
test-compile
compiler:testCompile
test
surefire:test
package
jar:jar
install
install:install
deploy
deploy:deploy
4.2.2. POM
POM is the simplest packaging type. The artifact that it generates is itself only, rather than a JAR, SAR, or EAR. There is no code to test or compile, and there are no resources the process. The default goals for projects with POM packaging are shown in Table 4.3, ?Default Goals for POM Packaging?.
Table 4.3. Default Goals for POM Packaging
Lifecycle Phase
Goal
package
site:attach-descriptor
install
install:install
deploy
deploy:deploy
4.2.3. Maven Plugin
This packaging type is similar to JAR packaging type with three additions: plugin:descriptor, plugin:addPluginArtifactMetadata, and plugin:updateRegistry. These goals generate a descriptor file and perform some modifications to the repository data. The default goals for projects with plugin packaging are shown in Table 4.4, ?Default Goals for Plugin Packaging?.
Table 4.4. Default Goals for Plugin Packaging
Lifecycle Phase
Goal
generate-resources
plugin:descriptor
process-resources
resources:resources
compile
compiler:compile
process-test-resources
resources:testResources
test-compile
compiler:testCompile
test
surefire:test
package
jar:jar, plugin:addPluginArtifactMetadata
install
install:install, plugin:updateRegistry
deploy
deploy:deploy
4.2.4. EJB
EJBs, or Enterprise Java Beans, are a common data access mechanism for model-driven development in Enterprise Java. Maven provides support for EJB 2 and 3. Though you must configure the EJB plugin to specifically package for EJB3, else the plugin defaults to 2.1 and looks for the presence of certain EJB configuration files. The default goals for projects with EJB packaging are shown in Table 4.5, ?Default Goals for EJB Packaging?.
Table 4.5. Default Goals for EJB Packaging
Lifecycle Phase
Goal
process-resources
resources:resources
compile
compiler:compile
process-test-resources
resources:testResources
test-compile
compiler:testCompile
test
surefire:test
package
ejb:ejb
install
install:install
deploy
deploy:deploy
4.2.5. WAR
The WAR packaging type is similar to the JAR and EJB types. The exception being the package goal of war:war. Note that the war:war goal requires a web.xml configuration in your src/main/webapp/WEB-INF directory. The default goals for projects with WAR packaging are shown in Table 4.6, ?Default Goals for WAR Packaging?.
Table 4.6. Default Goals for WAR Packaging
Lifecycle Phase
Goal
process-resources
resources:resources
compile
compiler:compile
process-test-resources
resources:testResources
test-compile
compiler:testCompile
test
surefire:test
package
war:war
install
install:install
deploy
deploy:deploy
4.2.6. EAR
EARs are probably the simplest Java EE constructs, consisting primarily of the deployment descriptor application.xml file, some resources and some modules. The EAR plugin has a goal named generate-application-xml which generates the application.xml based upon the configuration in the EAR project?s POM. The default goals for projects with EAR packaging are shown in Table 4.7, ?Default Goals for EAR Packaging?.
Table 4.7. Default Goals for EAR Packaging
Lifecycle Phase
Goal
generate-resources
ear:generate-application-xml
process-resources
resources:resources
package
ear:ear
install
install:install
deploy
deploy:deploy
4.2.7. Other Packaging Types
This is not an exhaustive list of every packaging type available for Maven. There are a number of packaging formats available through external projects and plugins: the NAR (native archive) packaging type, the SWF and SWC packaging types for projects that produce Adobe Flash and Flex content, and many others. You can also define a custom packaging type and customize the default lifecycle goals to suit your own project packaging requirements.
To use one of these custom packaging types, you need two things: a plugin which defines the lifecycle for a custom packaging type and a repository which contains this plugin. Some custom packaging types are defined in plugins available from the central Maven repository. Here is an example of a project which references the Israfil Flex plugin and uses a custom packaging type of SWF to produce output from Adobe Flex source.
In Section 11.6, ?Plugins and the Maven Lifecycle?, we show you how to create your own packaging type with a customized lifecycle. This example should give you an idea of what you?ll need to do to reference a custom packaging type. All you need to do is reference the plugin which supplies the custom packaging type. The Israfil Flex plugin is a third-party Maven plugin hosted at Google Code, for more information about this plugin and how to use Maven to compile Adobe Flex go to http://code.google.com/p/israfil-mojo. This plugin supplies the following lifecycle for the SWF packaging type:
Table 4.8. Default Lifecycle for SWF Packaging
Lifecycle Phase
Goal
compile
flex2:compile-swc
install
install:install
deploy
deploy:deploy
Prev : 4.1. Introduction
TOC
Next : 4.3. Common Lifecycle Goals
Nexus Professional
Access a live demo of the Pro Suite Install a trial version of Nexus Professional on your own machine Purchase a license for Nexus Professional
Recent Posts
Last Chance To Register: Insight for CI Demo
Insight for CI Demo: Additional Session Added
When Licenses Meet Reality, the Result is Often Confusing
How does Insight handle conflicting OSS licenses?
New Webinar: Gain Visibility & Control At Build Time with Insight for CI
63---->
Prev : 4.1. Introduction
TOC
Next : 4.3. Common Lifecycle Goals
4.2. Package-specific Lifecycles
The specific goals bound to each phase default to a set of goals specific to a project?s packaging. A project with packaging jar has a different set of default goals from a project with a packaging of war. The packaging element affects the steps required to build a project. For an example of how the packaging affects the build, consider two projects: one with pom packaging and the other with jar packaging. The project with pom packaging will run the site:attach-descriptor goal during the package phase, and the project with jar packaging will run the jar:jar goal instead.
The following sections describe the lifecycle for all built-in packaging types in Maven. Use these sections to find out what default goals are mapped to default lifecycle phases.
4.2.1. JAR
JAR is the default packaging type, the most common, and thus the most commonly encountered lifecycle configuration. The default goals for the JAR lifecycle are shown in Table 4.2, ?Default Goals for JAR Packaging?.
Table 4.2. Default Goals for JAR Packaging
Lifecycle Phase
Goal
process-resources
resources:resources
compile
compiler:compile
process-test-resources
resources:testResources
test-compile
compiler:testCompile
test
surefire:test
package
jar:jar
install
install:install
deploy
deploy:deploy
4.2.2. POM
POM is the simplest packaging type. The artifact that it generates is itself only, rather than a JAR, SAR, or EAR. There is no code to test or compile, and there are no resources the process. The default goals for projects with POM packaging are shown in Table 4.3, ?Default Goals for POM Packaging?.
Table 4.3. Default Goals for POM Packaging
Lifecycle Phase
Goal
package
site:attach-descriptor
install
install:install
deploy
deploy:deploy
4.2.3. Maven Plugin
This packaging type is similar to JAR packaging type with three additions: plugin:descriptor, plugin:addPluginArtifactMetadata, and plugin:updateRegistry. These goals generate a descriptor file and perform some modifications to the repository data. The default goals for projects with plugin packaging are shown in Table 4.4, ?Default Goals for Plugin Packaging?.
Table 4.4. Default Goals for Plugin Packaging
Lifecycle Phase
Goal
generate-resources
plugin:descriptor
process-resources
resources:resources
compile
compiler:compile
process-test-resources
resources:testResources
test-compile
compiler:testCompile
test
surefire:test
package
jar:jar, plugin:addPluginArtifactMetadata
install
install:install, plugin:updateRegistry
deploy
deploy:deploy
4.2.4. EJB
EJBs, or Enterprise Java Beans, are a common data access mechanism for model-driven development in Enterprise Java. Maven provides support for EJB 2 and 3. Though you must configure the EJB plugin to specifically package for EJB3, else the plugin defaults to 2.1 and looks for the presence of certain EJB configuration files. The default goals for projects with EJB packaging are shown in Table 4.5, ?Default Goals for EJB Packaging?.
Table 4.5. Default Goals for EJB Packaging
Lifecycle Phase
Goal
process-resources
resources:resources
compile
compiler:compile
process-test-resources
resources:testResources
test-compile
compiler:testCompile
test
surefire:test
package
ejb:ejb
install
install:install
deploy
deploy:deploy
4.2.5. WAR
The WAR packaging type is similar to the JAR and EJB types. The exception being the package goal of war:war. Note that the war:war goal requires a web.xml configuration in your src/main/webapp/WEB-INF directory. The default goals for projects with WAR packaging are shown in Table 4.6, ?Default Goals for WAR Packaging?.
Table 4.6. Default Goals for WAR Packaging
Lifecycle Phase
Goal
process-resources
resources:resources
compile
compiler:compile
process-test-resources
resources:testResources
test-compile
compiler:testCompile
test
surefire:test
package
war:war
install
install:install
deploy
deploy:deploy
4.2.6. EAR
EARs are probably the simplest Java EE constructs, consisting primarily of the deployment descriptor application.xml file, some resources and some modules. The EAR plugin has a goal named generate-application-xml which generates the application.xml based upon the configuration in the EAR project?s POM. The default goals for projects with EAR packaging are shown in Table 4.7, ?Default Goals for EAR Packaging?.
Table 4.7. Default Goals for EAR Packaging
Lifecycle Phase
Goal
generate-resources
ear:generate-application-xml
process-resources
resources:resources
package
ear:ear
install
install:install
deploy
deploy:deploy
4.2.7. Other Packaging Types
This is not an exhaustive list of every packaging type available for Maven. There are a number of packaging formats available through external projects and plugins: the NAR (native archive) packaging type, the SWF and SWC packaging types for projects that produce Adobe Flash and Flex content, and many others. You can also define a custom packaging type and customize the default lifecycle goals to suit your own project packaging requirements.
To use one of these custom packaging types, you need two things: a plugin which defines the lifecycle for a custom packaging type and a repository which contains this plugin. Some custom packaging types are defined in plugins available from the central Maven repository. Here is an example of a project which references the Israfil Flex plugin and uses a custom packaging type of SWF to produce output from Adobe Flex source.
In Section 11.6, ?Plugins and the Maven Lifecycle?, we show you how to create your own packaging type with a customized lifecycle. This example should give you an idea of what you?ll need to do to reference a custom packaging type. All you need to do is reference the plugin which supplies the custom packaging type. The Israfil Flex plugin is a third-party Maven plugin hosted at Google Code, for more information about this plugin and how to use Maven to compile Adobe Flex go to http://code.google.com/p/israfil-mojo. This plugin supplies the following lifecycle for the SWF packaging type:
Table 4.8. Default Lifecycle for SWF Packaging
Lifecycle Phase
Goal
compile
flex2:compile-swc
install
install:install
deploy
deploy:deploy
Prev : 4.1. Introduction
TOC
Next : 4.3. Common Lifecycle Goals
Nexus Professional
Access a live demo of the Pro Suite Install a trial version of Nexus Professional on your own machine Purchase a license for Nexus Professional
Recent Posts
Last Chance To Register: Insight for CI Demo
Insight for CI Demo: Additional Session Added
When Licenses Meet Reality, the Result is Often Confusing
How does Insight handle conflicting OSS licenses?
New Webinar: Gain Visibility & Control At Build Time with Insight for CI
64---->
Prev : 4.1. Introduction
TOC
Next : 4.3. Common Lifecycle Goals
4.2. Package-specific Lifecycles
The specific goals bound to each phase default to a set of goals specific to a project?s packaging. A project with packaging jar has a different set of default goals from a project with a packaging of war. The packaging element affects the steps required to build a project. For an example of how the packaging affects the build, consider two projects: one with pom packaging and the other with jar packaging. The project with pom packaging will run the site:attach-descriptor goal during the package phase, and the project with jar packaging will run the jar:jar goal instead.
The following sections describe the lifecycle for all built-in packaging types in Maven. Use these sections to find out what default goals are mapped to default lifecycle phases.
4.2.1. JAR
JAR is the default packaging type, the most common, and thus the most commonly encountered lifecycle configuration. The default goals for the JAR lifecycle are shown in Table 4.2, ?Default Goals for JAR Packaging?.
Table 4.2. Default Goals for JAR Packaging
Lifecycle Phase
Goal
process-resources
resources:resources
compile
compiler:compile
process-test-resources
resources:testResources
test-compile
compiler:testCompile
test
surefire:test
package
jar:jar
install
install:install
deploy
deploy:deploy
4.2.2. POM
POM is the simplest packaging type. The artifact that it generates is itself only, rather than a JAR, SAR, or EAR. There is no code to test or compile, and there are no resources the process. The default goals for projects with POM packaging are shown in Table 4.3, ?Default Goals for POM Packaging?.
Table 4.3. Default Goals for POM Packaging
Lifecycle Phase
Goal
package
site:attach-descriptor
install
install:install
deploy
deploy:deploy
4.2.3. Maven Plugin
This packaging type is similar to JAR packaging type with three additions: plugin:descriptor, plugin:addPluginArtifactMetadata, and plugin:updateRegistry. These goals generate a descriptor file and perform some modifications to the repository data. The default goals for projects with plugin packaging are shown in Table 4.4, ?Default Goals for Plugin Packaging?.
Table 4.4. Default Goals for Plugin Packaging
Lifecycle Phase
Goal
generate-resources
plugin:descriptor
process-resources
resources:resources
compile
compiler:compile
process-test-resources
resources:testResources
test-compile
compiler:testCompile
test
surefire:test
package
jar:jar, plugin:addPluginArtifactMetadata
install
install:install, plugin:updateRegistry
deploy
deploy:deploy
4.2.4. EJB
EJBs, or Enterprise Java Beans, are a common data access mechanism for model-driven development in Enterprise Java. Maven provides support for EJB 2 and 3. Though you must configure the EJB plugin to specifically package for EJB3, else the plugin defaults to 2.1 and looks for the presence of certain EJB configuration files. The default goals for projects with EJB packaging are shown in Table 4.5, ?Default Goals for EJB Packaging?.
Table 4.5. Default Goals for EJB Packaging
Lifecycle Phase
Goal
process-resources
resources:resources
compile
compiler:compile
process-test-resources
resources:testResources
test-compile
compiler:testCompile
test
surefire:test
package
ejb:ejb
install
install:install
deploy
deploy:deploy
4.2.5. WAR
The WAR packaging type is similar to the JAR and EJB types. The exception being the package goal of war:war. Note that the war:war goal requires a web.xml configuration in your src/main/webapp/WEB-INF directory. The default goals for projects with WAR packaging are shown in Table 4.6, ?Default Goals for WAR Packaging?.
Table 4.6. Default Goals for WAR Packaging
Lifecycle Phase
Goal
process-resources
resources:resources
compile
compiler:compile
process-test-resources
resources:testResources
test-compile
compiler:testCompile
test
surefire:test
package
war:war
install
install:install
deploy
deploy:deploy
4.2.6. EAR
EARs are probably the simplest Java EE constructs, consisting primarily of the deployment descriptor application.xml file, some resources and some modules. The EAR plugin has a goal named generate-application-xml which generates the application.xml based upon the configuration in the EAR project?s POM. The default goals for projects with EAR packaging are shown in Table 4.7, ?Default Goals for EAR Packaging?.
Table 4.7. Default Goals for EAR Packaging
Lifecycle Phase
Goal
generate-resources
ear:generate-application-xml
process-resources
resources:resources
package
ear:ear
install
install:install
deploy
deploy:deploy
4.2.7. Other Packaging Types
This is not an exhaustive list of every packaging type available for Maven. There are a number of packaging formats available through external projects and plugins: the NAR (native archive) packaging type, the SWF and SWC packaging types for projects that produce Adobe Flash and Flex content, and many others. You can also define a custom packaging type and customize the default lifecycle goals to suit your own project packaging requirements.
To use one of these custom packaging types, you need two things: a plugin which defines the lifecycle for a custom packaging type and a repository which contains this plugin. Some custom packaging types are defined in plugins available from the central Maven repository. Here is an example of a project which references the Israfil Flex plugin and uses a custom packaging type of SWF to produce output from Adobe Flex source.
In Section 11.6, ?Plugins and the Maven Lifecycle?, we show you how to create your own packaging type with a customized lifecycle. This example should give you an idea of what you?ll need to do to reference a custom packaging type. All you need to do is reference the plugin which supplies the custom packaging type. The Israfil Flex plugin is a third-party Maven plugin hosted at Google Code, for more information about this plugin and how to use Maven to compile Adobe Flex go to http://code.google.com/p/israfil-mojo. This plugin supplies the following lifecycle for the SWF packaging type:
Table 4.8. Default Lifecycle for SWF Packaging
Lifecycle Phase
Goal
compile
flex2:compile-swc
install
install:install
deploy
deploy:deploy
Prev : 4.1. Introduction
TOC
Next : 4.3. Common Lifecycle Goals
Nexus Professional
Access a live demo of the Pro Suite Install a trial version of Nexus Professional on your own machine Purchase a license for Nexus Professional
Recent Posts
Last Chance To Register: Insight for CI Demo
Insight for CI Demo: Additional Session Added
When Licenses Meet Reality, the Result is Often Confusing
How does Insight handle conflicting OSS licenses?
New Webinar: Gain Visibility & Control At Build Time with Insight for CI
65---->
Prev : 4.1. Introduction
TOC
Next : 4.3. Common Lifecycle Goals
4.2. Package-specific Lifecycles
The specific goals bound to each phase default to a set of goals specific to a project?s packaging. A project with packaging jar has a different set of default goals from a project with a packaging of war. The packaging element affects the steps required to build a project. For an example of how the packaging affects the build, consider two projects: one with pom packaging and the other with jar packaging. The project with pom packaging will run the site:attach-descriptor goal during the package phase, and the project with jar packaging will run the jar:jar goal instead.
The following sections describe the lifecycle for all built-in packaging types in Maven. Use these sections to find out what default goals are mapped to default lifecycle phases.
4.2.1. JAR
JAR is the default packaging type, the most common, and thus the most commonly encountered lifecycle configuration. The default goals for the JAR lifecycle are shown in Table 4.2, ?Default Goals for JAR Packaging?.
Table 4.2. Default Goals for JAR Packaging
Lifecycle Phase
Goal
process-resources
resources:resources
compile
compiler:compile
process-test-resources
resources:testResources
test-compile
compiler:testCompile
test
surefire:test
package
jar:jar
install
install:install
deploy
deploy:deploy
4.2.2. POM
POM is the simplest packaging type. The artifact that it generates is itself only, rather than a JAR, SAR, or EAR. There is no code to test or compile, and there are no resources the process. The default goals for projects with POM packaging are shown in Table 4.3, ?Default Goals for POM Packaging?.
Table 4.3. Default Goals for POM Packaging
Lifecycle Phase
Goal
package
site:attach-descriptor
install
install:install
deploy
deploy:deploy
4.2.3. Maven Plugin
This packaging type is similar to JAR packaging type with three additions: plugin:descriptor, plugin:addPluginArtifactMetadata, and plugin:updateRegistry. These goals generate a descriptor file and perform some modifications to the repository data. The default goals for projects with plugin packaging are shown in Table 4.4, ?Default Goals for Plugin Packaging?.
Table 4.4. Default Goals for Plugin Packaging
Lifecycle Phase
Goal
generate-resources
plugin:descriptor
process-resources
resources:resources
compile
compiler:compile
process-test-resources
resources:testResources
test-compile
compiler:testCompile
test
surefire:test
package
jar:jar, plugin:addPluginArtifactMetadata
install
install:install, plugin:updateRegistry
deploy
deploy:deploy
4.2.4. EJB
EJBs, or Enterprise Java Beans, are a common data access mechanism for model-driven development in Enterprise Java. Maven provides support for EJB 2 and 3. Though you must configure the EJB plugin to specifically package for EJB3, else the plugin defaults to 2.1 and looks for the presence of certain EJB configuration files. The default goals for projects with EJB packaging are shown in Table 4.5, ?Default Goals for EJB Packaging?.
Table 4.5. Default Goals for EJB Packaging
Lifecycle Phase
Goal
process-resources
resources:resources
compile
compiler:compile
process-test-resources
resources:testResources
test-compile
compiler:testCompile
test
surefire:test
package
ejb:ejb
install
install:install
deploy
deploy:deploy
4.2.5. WAR
The WAR packaging type is similar to the JAR and EJB types. The exception being the package goal of war:war. Note that the war:war goal requires a web.xml configuration in your src/main/webapp/WEB-INF directory. The default goals for projects with WAR packaging are shown in Table 4.6, ?Default Goals for WAR Packaging?.
Table 4.6. Default Goals for WAR Packaging
Lifecycle Phase
Goal
process-resources
resources:resources
compile
compiler:compile
process-test-resources
resources:testResources
test-compile
compiler:testCompile
test
surefire:test
package
war:war
install
install:install
deploy
deploy:deploy
4.2.6. EAR
EARs are probably the simplest Java EE constructs, consisting primarily of the deployment descriptor application.xml file, some resources and some modules. The EAR plugin has a goal named generate-application-xml which generates the application.xml based upon the configuration in the EAR project?s POM. The default goals for projects with EAR packaging are shown in Table 4.7, ?Default Goals for EAR Packaging?.
Table 4.7. Default Goals for EAR Packaging
Lifecycle Phase
Goal
generate-resources
ear:generate-application-xml
process-resources
resources:resources
package
ear:ear
install
install:install
deploy
deploy:deploy
4.2.7. Other Packaging Types
This is not an exhaustive list of every packaging type available for Maven. There are a number of packaging formats available through external projects and plugins: the NAR (native archive) packaging type, the SWF and SWC packaging types for projects that produce Adobe Flash and Flex content, and many others. You can also define a custom packaging type and customize the default lifecycle goals to suit your own project packaging requirements.
To use one of these custom packaging types, you need two things: a plugin which defines the lifecycle for a custom packaging type and a repository which contains this plugin. Some custom packaging types are defined in plugins available from the central Maven repository. Here is an example of a project which references the Israfil Flex plugin and uses a custom packaging type of SWF to produce output from Adobe Flex source.
In Section 11.6, ?Plugins and the Maven Lifecycle?, we show you how to create your own packaging type with a customized lifecycle. This example should give you an idea of what you?ll need to do to reference a custom packaging type. All you need to do is reference the plugin which supplies the custom packaging type. The Israfil Flex plugin is a third-party Maven plugin hosted at Google Code, for more information about this plugin and how to use Maven to compile Adobe Flex go to http://code.google.com/p/israfil-mojo. This plugin supplies the following lifecycle for the SWF packaging type:
Table 4.8. Default Lifecycle for SWF Packaging
Lifecycle Phase
Goal
compile
flex2:compile-swc
install
install:install
deploy
deploy:deploy
Prev : 4.1. Introduction
TOC
Next : 4.3. Common Lifecycle Goals
Nexus Professional
Access a live demo of the Pro Suite Install a trial version of Nexus Professional on your own machine Purchase a license for Nexus Professional
Recent Posts
Last Chance To Register: Insight for CI Demo
Insight for CI Demo: Additional Session Added
When Licenses Meet Reality, the Result is Often Confusing
How does Insight handle conflicting OSS licenses?
New Webinar: Gain Visibility & Control At Build Time with Insight for CI
66---->
Prev : 4.1. Introduction
TOC
Next : 4.3. Common Lifecycle Goals
4.2. Package-specific Lifecycles
The specific goals bound to each phase default to a set of goals specific to a project?s packaging. A project with packaging jar has a different set of default goals from a project with a packaging of war. The packaging element affects the steps required to build a project. For an example of how the packaging affects the build, consider two projects: one with pom packaging and the other with jar packaging. The project with pom packaging will run the site:attach-descriptor goal during the package phase, and the project with jar packaging will run the jar:jar goal instead.
The following sections describe the lifecycle for all built-in packaging types in Maven. Use these sections to find out what default goals are mapped to default lifecycle phases.
4.2.1. JAR
JAR is the default packaging type, the most common, and thus the most commonly encountered lifecycle configuration. The default goals for the JAR lifecycle are shown in Table 4.2, ?Default Goals for JAR Packaging?.
Table 4.2. Default Goals for JAR Packaging
Lifecycle Phase
Goal
process-resources
resources:resources
compile
compiler:compile
process-test-resources
resources:testResources
test-compile
compiler:testCompile
test
surefire:test
package
jar:jar
install
install:install
deploy
deploy:deploy
4.2.2. POM
POM is the simplest packaging type. The artifact that it generates is itself only, rather than a JAR, SAR, or EAR. There is no code to test or compile, and there are no resources the process. The default goals for projects with POM packaging are shown in Table 4.3, ?Default Goals for POM Packaging?.
Table 4.3. Default Goals for POM Packaging
Lifecycle Phase
Goal
package
site:attach-descriptor
install
install:install
deploy
deploy:deploy
4.2.3. Maven Plugin
This packaging type is similar to JAR packaging type with three additions: plugin:descriptor, plugin:addPluginArtifactMetadata, and plugin:updateRegistry. These goals generate a descriptor file and perform some modifications to the repository data. The default goals for projects with plugin packaging are shown in Table 4.4, ?Default Goals for Plugin Packaging?.
Table 4.4. Default Goals for Plugin Packaging
Lifecycle Phase
Goal
generate-resources
plugin:descriptor
process-resources
resources:resources
compile
compiler:compile
process-test-resources
resources:testResources
test-compile
compiler:testCompile
test
surefire:test
package
jar:jar, plugin:addPluginArtifactMetadata
install
install:install, plugin:updateRegistry
deploy
deploy:deploy
4.2.4. EJB
EJBs, or Enterprise Java Beans, are a common data access mechanism for model-driven development in Enterprise Java. Maven provides support for EJB 2 and 3. Though you must configure the EJB plugin to specifically package for EJB3, else the plugin defaults to 2.1 and looks for the presence of certain EJB configuration files. The default goals for projects with EJB packaging are shown in Table 4.5, ?Default Goals for EJB Packaging?.
Table 4.5. Default Goals for EJB Packaging
Lifecycle Phase
Goal
process-resources
resources:resources
compile
compiler:compile
process-test-resources
resources:testResources
test-compile
compiler:testCompile
test
surefire:test
package
ejb:ejb
install
install:install
deploy
deploy:deploy
4.2.5. WAR
The WAR packaging type is similar to the JAR and EJB types. The exception being the package goal of war:war. Note that the war:war goal requires a web.xml configuration in your src/main/webapp/WEB-INF directory. The default goals for projects with WAR packaging are shown in Table 4.6, ?Default Goals for WAR Packaging?.
Table 4.6. Default Goals for WAR Packaging
Lifecycle Phase
Goal
process-resources
resources:resources
compile
compiler:compile
process-test-resources
resources:testResources
test-compile
compiler:testCompile
test
surefire:test
package
war:war
install
install:install
deploy
deploy:deploy
4.2.6. EAR
EARs are probably the simplest Java EE constructs, consisting primarily of the deployment descriptor application.xml file, some resources and some modules. The EAR plugin has a goal named generate-application-xml which generates the application.xml based upon the configuration in the EAR project?s POM. The default goals for projects with EAR packaging are shown in Table 4.7, ?Default Goals for EAR Packaging?.
Table 4.7. Default Goals for EAR Packaging
Lifecycle Phase
Goal
generate-resources
ear:generate-application-xml
process-resources
resources:resources
package
ear:ear
install
install:install
deploy
deploy:deploy
4.2.7. Other Packaging Types
This is not an exhaustive list of every packaging type available for Maven. There are a number of packaging formats available through external projects and plugins: the NAR (native archive) packaging type, the SWF and SWC packaging types for projects that produce Adobe Flash and Flex content, and many others. You can also define a custom packaging type and customize the default lifecycle goals to suit your own project packaging requirements.
To use one of these custom packaging types, you need two things: a plugin which defines the lifecycle for a custom packaging type and a repository which contains this plugin. Some custom packaging types are defined in plugins available from the central Maven repository. Here is an example of a project which references the Israfil Flex plugin and uses a custom packaging type of SWF to produce output from Adobe Flex source.
In Section 11.6, ?Plugins and the Maven Lifecycle?, we show you how to create your own packaging type with a customized lifecycle. This example should give you an idea of what you?ll need to do to reference a custom packaging type. All you need to do is reference the plugin which supplies the custom packaging type. The Israfil Flex plugin is a third-party Maven plugin hosted at Google Code, for more information about this plugin and how to use Maven to compile Adobe Flex go to http://code.google.com/p/israfil-mojo. This plugin supplies the following lifecycle for the SWF packaging type:
Table 4.8. Default Lifecycle for SWF Packaging
Lifecycle Phase
Goal
compile
flex2:compile-swc
install
install:install
deploy
deploy:deploy
Prev : 4.1. Introduction
TOC
Next : 4.3. Common Lifecycle Goals
Nexus Professional
Access a live demo of the Pro Suite Install a trial version of Nexus Professional on your own machine Purchase a license for Nexus Professional
Recent Posts
Last Chance To Register: Insight for CI Demo
Insight for CI Demo: Additional Session Added
When Licenses Meet Reality, the Result is Often Confusing
How does Insight handle conflicting OSS licenses?
New Webinar: Gain Visibility & Control At Build Time with Insight for CI
67---->
Prev : Chapter 4. The Build Lifecycle
TOC
Next : 4.2. Package-specific Lifecycles
4.1. Introduction
Maven models projects as nouns which are described by a POM. The POM captures the identity of a project: What does a project contain? What type of packaging a project needs? Does the project have a parent? What are the dependencies? We?ve explored the idea of describing a project in the previous chapters, but we haven?t introduced the mechanism that allows Maven to act upon these objects. In Maven the "verbs" are goals packaged in Maven plugins which are tied to a phases in a build lifecycle. A Maven lifecycle consists of a sequence of named phases: prepare-resources, compile, package, and install among other. There is phase that captures compilation and a phase that captures packaging. There are pre- and post- phases which can be used to register goals which must run prior to compilation, or tasks which must be run after a particular phase. When you tell Maven to build a project, you are telling Maven to step through a defined sequence of phases and execute any goals which may have been registered with each phase.
A build lifecycle is an organized sequence of phases that exist to give order to a set of goals. Those goals are chosen and bound by the packaging type of the project being acted upon. There are three standard lifecycles in Maven: clean, default (sometimes called build) and site. In this chapter, you are going to learn how Maven ties goals to lifecycle phases and how the lifecycle can be customized. You will also learn about the default lifecycle phases.
4.1.1. Clean Lifecycle (clean)
The first lifecycle you?ll be interested in is the simplest lifecycle in Maven. Running mvn clean invokes the clean lifecycle which consists of three lifecycle phases:
pre-clean
clean
post-clean
The interesting phase in the clean lifecycle is the clean phase. The Clean plugin?s clean goal (clean:clean) is bound to the clean phase in the clean lifecycle. The clean:clean goal deletes the output of a build by deleting the build directory. If you haven?t customized the location of the build directory it will be the ${basedir}/target directory as defined by the Super POM. When you execute the clean:clean goal you do not do so by executing the goal directly with mvn clean:clean, you do so by executing the clean phase of the clean lifecycle. Executing the clean phase gives Maven an opportunity to execute any other goals which may be bound to the pre-clean phase.
For example, suppose you wanted to trigger an antrun:run goal task to echo a notification on pre-clean, or to make an archive of a project?s build directory before it is deleted. Simply running the clean:clean goal will not execute the lifecycle at all, but specifying the clean phase will use the clean lifecycle and advance through the three lifecycle phases until it reaches the clean phase. Triggering a Goal on pre-clean shows an example of build configuration which binds the antrun:run goal to the pre-clean phase to echo an alert that the project artifact is about to be deleted. In this example, the antrun:run goal is being used to execute some arbitrary Ant commands to check for an existing project artifact. If the project?s artifact is about to be deleted it will print this to the screen
Triggering a Goal on pre-clean.
... ... maven-antrun-plugin file-exists pre-clean run
Running mvn clean on a project with this build configuration will produce output similar to the following:
[INFO] Scanning for projects...
[INFO] ----------------------------------------------------------------------
[INFO] Building Your Project
[INFO]task-segment: [clean]
[INFO] ----------------------------------------------------------------------
[INFO] [antrun:run {execution: file-exists}]
[INFO] Executing tasks
[echo] Deleting your-project-1.0-SNAPSHOT.jar
[INFO] Executed tasks
[INFO] [clean:clean]
[INFO] Deleting directory ~/corp/your-project/target
[INFO] Deleting directory ~/corp/your-project/target/classes
[INFO] Deleting directory ~/corp/your-project/target/test-classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1 second
[INFO] Finished at: Wed Nov 08 11:46:26 CST 2006
[INFO] Final Memory: 2M/5M
[INFO] ------------------------------------------------------------------------
In addition to configuring Maven to run a goal during the+ pre-clean+ phase, you can also customize the Clean plugin to delete files in addition to the build output directory. You can configure the plugin to remove specific files in a fileSet. The example below configures clean to remove all .class files in a directory named target-other/ using standard Ant file wildcards: \* and \**.
Customizing Behavior of the Clean Plugin.
4.0.0
... maven-clean-plugin target-other *.class
4.1.2. Default Lifecycle (default)
Most Maven users will be familiar with the default lifecycle. It is a general model of a build process for a software application. The first phase is validate and the last phase is deploy. The phases in the default Maven lifecycle are shown in Table 4.1, ?Maven Lifecycle Phases?.
Table 4.1. Maven Lifecycle Phases
Lifecycle Phase Description
validate
Validate the project is correct and all necessary information is available to complete a build
generate-sources
Generate any source code for inclusion in compilation
process-sources
Process the source code, for example to filter any values
generate-resources
Generate resources for inclusion in the package
process-resources
Copy and process the resources into the destination directory, ready for packaging
compile
Compile the source code of the project
process-classes
Post-process the generated files from compilation, for example to do bytecode enhancement on Java classes
generate-test-sources
Generate any test source code for inclusion in compilation
process-test-sources
Process the test source code, for example to filter any values
generate-test-resources
Create resources for testing
process-test-resources
Copy and process the resources into the test destination directory
test-compile
Compile the test source code into the test destination directory
test
Run tests using a suitable unit testing framework. These tests should not require the code be packaged or deployed
prepare-package
Perform any operations necessary to prepare a package before the actual packaging. This often results in an unpacked, processed version of the package (coming in Maven 2.1+)
package
Take the compiled code and package it in its distributable format, such as a JAR, WAR, or EAR
pre-integration-test
Perform actions required before integration tests are executed. This may involve things such as setting up the required environment
integration-test
Process and deploy the package if necessary into an environment where integration tests can be run
post-integration-test
Perform actions required after integration tests have been executed. This may include cleaning up the environment
verify
Run any checks to verify the package is valid and meets quality criteria
install
Install the package into the local repository, for use as a dependency in other projects locally
deploy
Copies the final package to the remote repository for sharing with other developers and projects (usually only relevant during a formal release)
4.1.3. Site Lifecycle (site)
Maven does more than build software artifacts from project, it can also generate project documentation and reports about the project, or a collection of projects. Project documentation and site generation have a dedicated lifecycle which contains four phases:
pre-site
site
post-site
site-deploy
The default goals bound to the site lifecycle is:
site - site:site
site-deploy -site:deploy
The packaging type does not usually alter this lifecycle since packaging types are concerned primarily with artifact creation, not with the type of site generated. The Site plugin kicks off the execution of Doxia document generation and other report generation plugins. You can generate a site from a Maven project by running the following command:
$ mvn site
For more information about Maven Site generation, see Chapter 10, Site Generation.
Prev : Chapter 4. The Build Lifecycle
TOC
Next : 4.2. Package-specific Lifecycles
Nexus Professional
Access a live demo of the Pro Suite Install a trial version of Nexus Professional on your own machine Purchase a license for Nexus Professional
Recent Posts
Last Chance To Register: Insight for CI Demo
Insight for CI Demo: Additional Session Added
When Licenses Meet Reality, the Result is Often Confusing
How does Insight handle conflicting OSS licenses?
New Webinar: Gain Visibility & Control At Build Time with Insight for CI
68---->
Prev : Chapter 4. The Build Lifecycle
TOC
Next : 4.2. Package-specific Lifecycles
4.1. Introduction
Maven models projects as nouns which are described by a POM. The POM captures the identity of a project: What does a project contain? What type of packaging a project needs? Does the project have a parent? What are the dependencies? We?ve explored the idea of describing a project in the previous chapters, but we haven?t introduced the mechanism that allows Maven to act upon these objects. In Maven the "verbs" are goals packaged in Maven plugins which are tied to a phases in a build lifecycle. A Maven lifecycle consists of a sequence of named phases: prepare-resources, compile, package, and install among other. There is phase that captures compilation and a phase that captures packaging. There are pre- and post- phases which can be used to register goals which must run prior to compilation, or tasks which must be run after a particular phase. When you tell Maven to build a project, you are telling Maven to step through a defined sequence of phases and execute any goals which may have been registered with each phase.
A build lifecycle is an organized sequence of phases that exist to give order to a set of goals. Those goals are chosen and bound by the packaging type of the project being acted upon. There are three standard lifecycles in Maven: clean, default (sometimes called build) and site. In this chapter, you are going to learn how Maven ties goals to lifecycle phases and how the lifecycle can be customized. You will also learn about the default lifecycle phases.
4.1.1. Clean Lifecycle (clean)
The first lifecycle you?ll be interested in is the simplest lifecycle in Maven. Running mvn clean invokes the clean lifecycle which consists of three lifecycle phases:
pre-clean
clean
post-clean
The interesting phase in the clean lifecycle is the clean phase. The Clean plugin?s clean goal (clean:clean) is bound to the clean phase in the clean lifecycle. The clean:clean goal deletes the output of a build by deleting the build directory. If you haven?t customized the location of the build directory it will be the ${basedir}/target directory as defined by the Super POM. When you execute the clean:clean goal you do not do so by executing the goal directly with mvn clean:clean, you do so by executing the clean phase of the clean lifecycle. Executing the clean phase gives Maven an opportunity to execute any other goals which may be bound to the pre-clean phase.
For example, suppose you wanted to trigger an antrun:run goal task to echo a notification on pre-clean, or to make an archive of a project?s build directory before it is deleted. Simply running the clean:clean goal will not execute the lifecycle at all, but specifying the clean phase will use the clean lifecycle and advance through the three lifecycle phases until it reaches the clean phase. Triggering a Goal on pre-clean shows an example of build configuration which binds the antrun:run goal to the pre-clean phase to echo an alert that the project artifact is about to be deleted. In this example, the antrun:run goal is being used to execute some arbitrary Ant commands to check for an existing project artifact. If the project?s artifact is about to be deleted it will print this to the screen
Triggering a Goal on pre-clean.
... ... maven-antrun-plugin file-exists pre-clean run
Running mvn clean on a project with this build configuration will produce output similar to the following:
[INFO] Scanning for projects...
[INFO] ----------------------------------------------------------------------
[INFO] Building Your Project
[INFO]task-segment: [clean]
[INFO] ----------------------------------------------------------------------
[INFO] [antrun:run {execution: file-exists}]
[INFO] Executing tasks
[echo] Deleting your-project-1.0-SNAPSHOT.jar
[INFO] Executed tasks
[INFO] [clean:clean]
[INFO] Deleting directory ~/corp/your-project/target
[INFO] Deleting directory ~/corp/your-project/target/classes
[INFO] Deleting directory ~/corp/your-project/target/test-classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1 second
[INFO] Finished at: Wed Nov 08 11:46:26 CST 2006
[INFO] Final Memory: 2M/5M
[INFO] ------------------------------------------------------------------------
In addition to configuring Maven to run a goal during the+ pre-clean+ phase, you can also customize the Clean plugin to delete files in addition to the build output directory. You can configure the plugin to remove specific files in a fileSet. The example below configures clean to remove all .class files in a directory named target-other/ using standard Ant file wildcards: \* and \**.
Customizing Behavior of the Clean Plugin.
4.0.0
... maven-clean-plugin target-other *.class
4.1.2. Default Lifecycle (default)
Most Maven users will be familiar with the default lifecycle. It is a general model of a build process for a software application. The first phase is validate and the last phase is deploy. The phases in the default Maven lifecycle are shown in Table 4.1, ?Maven Lifecycle Phases?.
Table 4.1. Maven Lifecycle Phases
Lifecycle Phase Description
validate
Validate the project is correct and all necessary information is available to complete a build
generate-sources
Generate any source code for inclusion in compilation
process-sources
Process the source code, for example to filter any values
generate-resources
Generate resources for inclusion in the package
process-resources
Copy and process the resources into the destination directory, ready for packaging
compile
Compile the source code of the project
process-classes
Post-process the generated files from compilation, for example to do bytecode enhancement on Java classes
generate-test-sources
Generate any test source code for inclusion in compilation
process-test-sources
Process the test source code, for example to filter any values
generate-test-resources
Create resources for testing
process-test-resources
Copy and process the resources into the test destination directory
test-compile
Compile the test source code into the test destination directory
test
Run tests using a suitable unit testing framework. These tests should not require the code be packaged or deployed
prepare-package
Perform any operations necessary to prepare a package before the actual packaging. This often results in an unpacked, processed version of the package (coming in Maven 2.1+)
package
Take the compiled code and package it in its distributable format, such as a JAR, WAR, or EAR
pre-integration-test
Perform actions required before integration tests are executed. This may involve things such as setting up the required environment
integration-test
Process and deploy the package if necessary into an environment where integration tests can be run
post-integration-test
Perform actions required after integration tests have been executed. This may include cleaning up the environment
verify
Run any checks to verify the package is valid and meets quality criteria
install
Install the package into the local repository, for use as a dependency in other projects locally
deploy
Copies the final package to the remote repository for sharing with other developers and projects (usually only relevant during a formal release)
4.1.3. Site Lifecycle (site)
Maven does more than build software artifacts from project, it can also generate project documentation and reports about the project, or a collection of projects. Project documentation and site generation have a dedicated lifecycle which contains four phases:
pre-site
site
post-site
site-deploy
The default goals bound to the site lifecycle is:
site - site:site
site-deploy -site:deploy
The packaging type does not usually alter this lifecycle since packaging types are concerned primarily with artifact creation, not with the type of site generated. The Site plugin kicks off the execution of Doxia document generation and other report generation plugins. You can generate a site from a Maven project by running the following command:
$ mvn site
For more information about Maven Site generation, see Chapter 10, Site Generation.
Prev : Chapter 4. The Build Lifecycle
TOC
Next : 4.2. Package-specific Lifecycles
Nexus Professional
Access a live demo of the Pro Suite Install a trial version of Nexus Professional on your own machine Purchase a license for Nexus Professional
Recent Posts
Last Chance To Register: Insight for CI Demo
Insight for CI Demo: Additional Session Added
When Licenses Meet Reality, the Result is Often Confusing
How does Insight handle conflicting OSS licenses?
New Webinar: Gain Visibility & Control At Build Time with Insight for CI
69---->
Prev : Chapter 4. The Build Lifecycle
TOC
Next : 4.2. Package-specific Lifecycles
4.1. Introduction
Maven models projects as nouns which are described by a POM. The POM captures the identity of a project: What does a project contain? What type of packaging a project needs? Does the project have a parent? What are the dependencies? We?ve explored the idea of describing a project in the previous chapters, but we haven?t introduced the mechanism that allows Maven to act upon these objects. In Maven the "verbs" are goals packaged in Maven plugins which are tied to a phases in a build lifecycle. A Maven lifecycle consists of a sequence of named phases: prepare-resources, compile, package, and install among other. There is phase that captures compilation and a phase that captures packaging. There are pre- and post- phases which can be used to register goals which must run prior to compilation, or tasks which must be run after a particular phase. When you tell Maven to build a project, you are telling Maven to step through a defined sequence of phases and execute any goals which may have been registered with each phase.
A build lifecycle is an organized sequence of phases that exist to give order to a set of goals. Those goals are chosen and bound by the packaging type of the project being acted upon. There are three standard lifecycles in Maven: clean, default (sometimes called build) and site. In this chapter, you are going to learn how Maven ties goals to lifecycle phases and how the lifecycle can be customized. You will also learn about the default lifecycle phases.
4.1.1. Clean Lifecycle (clean)
The first lifecycle you?ll be interested in is the simplest lifecycle in Maven. Running mvn clean invokes the clean lifecycle which consists of three lifecycle phases:
pre-clean
clean
post-clean
The interesting phase in the clean lifecycle is the clean phase. The Clean plugin?s clean goal (clean:clean) is bound to the clean phase in the clean lifecycle. The clean:clean goal deletes the output of a build by deleting the build directory. If you haven?t customized the location of the build directory it will be the ${basedir}/target directory as defined by the Super POM. When you execute the clean:clean goal you do not do so by executing the goal directly with mvn clean:clean, you do so by executing the clean phase of the clean lifecycle. Executing the clean phase gives Maven an opportunity to execute any other goals which may be bound to the pre-clean phase.
For example, suppose you wanted to trigger an antrun:run goal task to echo a notification on pre-clean, or to make an archive of a project?s build directory before it is deleted. Simply running the clean:clean goal will not execute the lifecycle at all, but specifying the clean phase will use the clean lifecycle and advance through the three lifecycle phases until it reaches the clean phase. Triggering a Goal on pre-clean shows an example of build configuration which binds the antrun:run goal to the pre-clean phase to echo an alert that the project artifact is about to be deleted. In this example, the antrun:run goal is being used to execute some arbitrary Ant commands to check for an existing project artifact. If the project?s artifact is about to be deleted it will print this to the screen
Triggering a Goal on pre-clean.
... ... maven-antrun-plugin file-exists pre-clean run
Running mvn clean on a project with this build configuration will produce output similar to the following:
[INFO] Scanning for projects...
[INFO] ----------------------------------------------------------------------
[INFO] Building Your Project
[INFO]task-segment: [clean]
[INFO] ----------------------------------------------------------------------
[INFO] [antrun:run {execution: file-exists}]
[INFO] Executing tasks
[echo] Deleting your-project-1.0-SNAPSHOT.jar
[INFO] Executed tasks
[INFO] [clean:clean]
[INFO] Deleting directory ~/corp/your-project/target
[INFO] Deleting directory ~/corp/your-project/target/classes
[INFO] Deleting directory ~/corp/your-project/target/test-classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1 second
[INFO] Finished at: Wed Nov 08 11:46:26 CST 2006
[INFO] Final Memory: 2M/5M
[INFO] ------------------------------------------------------------------------
In addition to configuring Maven to run a goal during the+ pre-clean+ phase, you can also customize the Clean plugin to delete files in addition to the build output directory. You can configure the plugin to remove specific files in a fileSet. The example below configures clean to remove all .class files in a directory named target-other/ using standard Ant file wildcards: \* and \**.
Customizing Behavior of the Clean Plugin.
4.0.0
... maven-clean-plugin target-other *.class
4.1.2. Default Lifecycle (default)
Most Maven users will be familiar with the default lifecycle. It is a general model of a build process for a software application. The first phase is validate and the last phase is deploy. The phases in the default Maven lifecycle are shown in Table 4.1, ?Maven Lifecycle Phases?.
Table 4.1. Maven Lifecycle Phases
Lifecycle Phase Description
validate
Validate the project is correct and all necessary information is available to complete a build
generate-sources
Generate any source code for inclusion in compilation
process-sources
Process the source code, for example to filter any values
generate-resources
Generate resources for inclusion in the package
process-resources
Copy and process the resources into the destination directory, ready for packaging
compile
Compile the source code of the project
process-classes
Post-process the generated files from compilation, for example to do bytecode enhancement on Java classes
generate-test-sources
Generate any test source code for inclusion in compilation
process-test-sources
Process the test source code, for example to filter any values
generate-test-resources
Create resources for testing
process-test-resources
Copy and process the resources into the test destination directory
test-compile
Compile the test source code into the test destination directory
test
Run tests using a suitable unit testing framework. These tests should not require the code be packaged or deployed
prepare-package
Perform any operations necessary to prepare a package before the actual packaging. This often results in an unpacked, processed version of the package (coming in Maven 2.1+)
package
Take the compiled code and package it in its distributable format, such as a JAR, WAR, or EAR
pre-integration-test
Perform actions required before integration tests are executed. This may involve things such as setting up the required environment
integration-test
Process and deploy the package if necessary into an environment where integration tests can be run
post-integration-test
Perform actions required after integration tests have been executed. This may include cleaning up the environment
verify
Run any checks to verify the package is valid and meets quality criteria
install
Install the package into the local repository, for use as a dependency in other projects locally
deploy
Copies the final package to the remote repository for sharing with other developers and projects (usually only relevant during a formal release)
4.1.3. Site Lifecycle (site)
Maven does more than build software artifacts from project, it can also generate project documentation and reports about the project, or a collection of projects. Project documentation and site generation have a dedicated lifecycle which contains four phases:
pre-site
site
post-site
site-deploy
The default goals bound to the site lifecycle is:
site - site:site
site-deploy -site:deploy
The packaging type does not usually alter this lifecycle since packaging types are concerned primarily with artifact creation, not with the type of site generated. The Site plugin kicks off the execution of Doxia document generation and other report generation plugins. You can generate a site from a Maven project by running the following command:
$ mvn site
For more information about Maven Site generation, see Chapter 10, Site Generation.
Prev : Chapter 4. The Build Lifecycle
TOC
Next : 4.2. Package-specific Lifecycles
Nexus Professional
Access a live demo of the Pro Suite Install a trial version of Nexus Professional on your own machine Purchase a license for Nexus Professional
Recent Posts
Last Chance To Register: Insight for CI Demo
Insight for CI Demo: Additional Session Added
When Licenses Meet Reality, the Result is Often Confusing
How does Insight handle conflicting OSS licenses?
New Webinar: Gain Visibility & Control At Build Time with Insight for CI
70---->
Prev : Chapter 4. The Build Lifecycle
TOC
Next : 4.2. Package-specific Lifecycles
4.1. Introduction
Maven models projects as nouns which are described by a POM. The POM captures the identity of a project: What does a project contain? What type of packaging a project needs? Does the project have a parent? What are the dependencies? We?ve explored the idea of describing a project in the previous chapters, but we haven?t introduced the mechanism that allows Maven to act upon these objects. In Maven the "verbs" are goals packaged in Maven plugins which are tied to a phases in a build lifecycle. A Maven lifecycle consists of a sequence of named phases: prepare-resources, compile, package, and install among other. There is phase that captures compilation and a phase that captures packaging. There are pre- and post- phases which can be used to register goals which must run prior to compilation, or tasks which must be run after a particular phase. When you tell Maven to build a project, you are telling Maven to step through a defined sequence of phases and execute any goals which may have been registered with each phase.
A build lifecycle is an organized sequence of phases that exist to give order to a set of goals. Those goals are chosen and bound by the packaging type of the project being acted upon. There are three standard lifecycles in Maven: clean, default (sometimes called build) and site. In this chapter, you are going to learn how Maven ties goals to lifecycle phases and how the lifecycle can be customized. You will also learn about the default lifecycle phases.
4.1.1. Clean Lifecycle (clean)
The first lifecycle you?ll be interested in is the simplest lifecycle in Maven. Running mvn clean invokes the clean lifecycle which consists of three lifecycle phases:
pre-clean
clean
post-clean
The interesting phase in the clean lifecycle is the clean phase. The Clean plugin?s clean goal (clean:clean) is bound to the clean phase in the clean lifecycle. The clean:clean goal deletes the output of a build by deleting the build directory. If you haven?t customized the location of the build directory it will be the ${basedir}/target directory as defined by the Super POM. When you execute the clean:clean goal you do not do so by executing the goal directly with mvn clean:clean, you do so by executing the clean phase of the clean lifecycle. Executing the clean phase gives Maven an opportunity to execute any other goals which may be bound to the pre-clean phase.
For example, suppose you wanted to trigger an antrun:run goal task to echo a notification on pre-clean, or to make an archive of a project?s build directory before it is deleted. Simply running the clean:clean goal will not execute the lifecycle at all, but specifying the clean phase will use the clean lifecycle and advance through the three lifecycle phases until it reaches the clean phase. Triggering a Goal on pre-clean shows an example of build configuration which binds the antrun:run goal to the pre-clean phase to echo an alert that the project artifact is about to be deleted. In this example, the antrun:run goal is being used to execute some arbitrary Ant commands to check for an existing project artifact. If the project?s artifact is about to be deleted it will print this to the screen
Triggering a Goal on pre-clean.
... ... maven-antrun-plugin file-exists pre-clean run
Running mvn clean on a project with this build configuration will produce output similar to the following:
[INFO] Scanning for projects...
[INFO] ----------------------------------------------------------------------
[INFO] Building Your Project
[INFO]task-segment: [clean]
[INFO] ----------------------------------------------------------------------
[INFO] [antrun:run {execution: file-exists}]
[INFO] Executing tasks
[echo] Deleting your-project-1.0-SNAPSHOT.jar
[INFO] Executed tasks
[INFO] [clean:clean]
[INFO] Deleting directory ~/corp/your-project/target
[INFO] Deleting directory ~/corp/your-project/target/classes
[INFO] Deleting directory ~/corp/your-project/target/test-classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1 second
[INFO] Finished at: Wed Nov 08 11:46:26 CST 2006
[INFO] Final Memory: 2M/5M
[INFO] ------------------------------------------------------------------------
In addition to configuring Maven to run a goal during the+ pre-clean+ phase, you can also customize the Clean plugin to delete files in addition to the build output directory. You can configure the plugin to remove specific files in a fileSet. The example below configures clean to remove all .class files in a directory named target-other/ using standard Ant file wildcards: \* and \**.
Customizing Behavior of the Clean Plugin.
4.0.0
... maven-clean-plugin target-other *.class
4.1.2. Default Lifecycle (default)
Most Maven users will be familiar with the default lifecycle. It is a general model of a build process for a software application. The first phase is validate and the last phase is deploy. The phases in the default Maven lifecycle are shown in Table 4.1, ?Maven Lifecycle Phases?.
Table 4.1. Maven Lifecycle Phases
Lifecycle Phase Description
validate
Validate the project is correct and all necessary information is available to complete a build
generate-sources
Generate any source code for inclusion in compilation
process-sources
Process the source code, for example to filter any values
generate-resources
Generate resources for inclusion in the package
process-resources
Copy and process the resources into the destination directory, ready for packaging
compile
Compile the source code of the project
process-classes
Post-process the generated files from compilation, for example to do bytecode enhancement on Java classes
generate-test-sources
Generate any test source code for inclusion in compilation
process-test-sources
Process the test source code, for example to filter any values
generate-test-resources
Create resources for testing
process-test-resources
Copy and process the resources into the test destination directory
test-compile
Compile the test source code into the test destination directory
test
Run tests using a suitable unit testing framework. These tests should not require the code be packaged or deployed
prepare-package
Perform any operations necessary to prepare a package before the actual packaging. This often results in an unpacked, processed version of the package (coming in Maven 2.1+)
package
Take the compiled code and package it in its distributable format, such as a JAR, WAR, or EAR
pre-integration-test
Perform actions required before integration tests are executed. This may involve things such as setting up the required environment
integration-test
Process and deploy the package if necessary into an environment where integration tests can be run
post-integration-test
Perform actions required after integration tests have been executed. This may include cleaning up the environment
verify
Run any checks to verify the package is valid and meets quality criteria
install
Install the package into the local repository, for use as a dependency in other projects locally
deploy
Copies the final package to the remote repository for sharing with other developers and projects (usually only relevant during a formal release)
4.1.3. Site Lifecycle (site)
Maven does more than build software artifacts from project, it can also generate project documentation and reports about the project, or a collection of projects. Project documentation and site generation have a dedicated lifecycle which contains four phases:
pre-site
site
post-site
site-deploy
The default goals bound to the site lifecycle is:
site - site:site
site-deploy -site:deploy
The packaging type does not usually alter this lifecycle since packaging types are concerned primarily with artifact creation, not with the type of site generated. The Site plugin kicks off the execution of Doxia document generation and other report generation plugins. You can generate a site from a Maven project by running the following command:
$ mvn site
For more information about Maven Site generation, see Chapter 10, Site Generation.
Prev : Chapter 4. The Build Lifecycle
TOC
Next : 4.2. Package-specific Lifecycles
Nexus Professional
Access a live demo of the Pro Suite Install a trial version of Nexus Professional on your own machine Purchase a license for Nexus Professional
Recent Posts
Last Chance To Register: Insight for CI Demo
Insight for CI Demo: Additional Session Added
When Licenses Meet Reality, the Result is Often Confusing
How does Insight handle conflicting OSS licenses?
New Webinar: Gain Visibility & Control At Build Time with Insight for CI
71---->
Prev : 3.6. POM Best Practices
TOC
Next : 4.1. Introduction
Chapter 4. The Build Lifecycle
4.1. Introduction
4.1.1. Clean Lifecycle (clean)
4.1.2. Default Lifecycle (default)
4.1.3. Site Lifecycle (site)
4.2. Package-specific Lifecycles
4.2.1. JAR
4.2.2. POM
4.2.3. Maven Plugin
4.2.4. EJB
4.2.5. WAR
4.2.6. EAR
4.2.7. Other Packaging Types
4.3. Common Lifecycle Goals
4.3.1. Process Resources
4.3.2. Compile
4.3.3. Process Test Resources
4.3.4. Test Compile
4.3.5. Test
4.3.6. Install
4.3.7. Deploy
Prev : 3.6. POM Best Practices
TOC
Next : 4.1. Introduction
Nexus Professional
Access a live demo of the Pro Suite Install a trial version of Nexus Professional on your own machine Purchase a license for Nexus Professional
Recent Posts
Last Chance To Register: Insight for CI Demo
Insight for CI Demo: Additional Session Added
When Licenses Meet Reality, the Result is Often Confusing
How does Insight handle conflicting OSS licenses?
New Webinar: Gain Visibility & Control At Build Time with Insight for CI
72---->
Prev : 3.5. Project Relationships
TOC
Next : Chapter 4. The Build Lifecycle
3.6. POM Best Practices
Maven can be used to manage everything from simple, single-project systems to builds that involve hundreds of inter-related submodules. Part of the learning process with Maven isn?t just figuring out the syntax for configuring Maven, it is learning the "Maven Way"?the current set of best practices for organizing and building projects using Maven. This section attempts to distill some of this knowledge to help you adopt best practices from the start without having to wade through years of discussions on the Maven mailing lists.
3.6.1. Grouping Dependencies
If you have a set of dependencies which are logically grouped together. You can create a project with pom packaging that groups dependencies together. For example, let?s assume that your application uses Hibernate, a popular Object-Relational mapping framework. Every project which uses Hibernate might also have a dependency on the Spring Framework and a MySQL JDBC driver. Instead of having to include these dependencies in every project that uses Hibernate, Spring, and MySQL you could create a special POM that does nothing more than declare a set of common dependencies. You could create a project called persistence-deps (short for Persistence Dependencies), and have every project that needs to do persistence depend on this convenience project:
Consolidating Dependencies in a Single POM Project.
If you create this project in a directory named persistence-deps, all you need to do is create this pom.xml and run mvn install. Since the packaging type is pom, this POM is installed in your local repository. You can now add this project as a dependency and all of its dependencies will be added as transitive dependencies to your project. When you declare a dependency on this persistence-deps project, don?t forget to specify the dependency type as pom.
Declaring a Dependency on a POM.
This is a project requiring JDBC
...
... org..mavenbook persistence-deps 1.0 pom
If you later decide to switch to a different JDBC driver (for example, JTDS), just replace the dependencies in the persistence-deps project to use net.+sourceforge.jtds:jtds+ instead of mysql:mysql-java-connector and update the version number. All projects depending on persistence-deps will use JTDS if they decide to update to the newer version. Consolidating related dependencies is a good way to cut down on the length of pom.xml files that start having to depend on a large number of dependencies. If you need to share a large number of dependencies between projects, you could also just establish parent-child relationships between projects and refactor all common dependencies to the parent project, but the disadvantage of the parent-child approach is that a project can have only one parent. Sometimes it makes more sense to group similar dependencies together and reference a pom dependency. This way, your project can reference as many of these consolidated dependency POMs as it needs.
Note
Maven uses the depth of a dependency in the tree when resolving conflicts using a nearest-wins approach. Using the dependency grouping technique above pushes those dependencies one level down in the tree. Keep this in mind when choosing between grouping in a pom or using dependencyManagement in a parent POM
3.6.2. Multi-module vs. Inheritance
There is a difference between inheriting from a parent project and being managed by a multimodule project. A parent project is one that passes its values to its children. A multimodule project simply manages a group of other subprojects or modules. The multimodule relationship is defined from the topmost level downwards. When setting up a multimodule project, you are simply telling a project that its build should include the specified modules. Multimodule builds are to be used to group modules together in a single build. The parent-child relationship is defined from the leaf node upwards. The parent-child relationship deals more with the definition of a particular project. When you associate a child with its parent, you are telling Maven that a project?s POM is derived from another.
To illustrate the decision process that goes into choosing a design that uses inheritance vs. multi-module or both approaches consider the following two examples: the Maven project used to generate this book and a hypothetical project that contains a number of logically grouped modules.
Simple Project
First, let?s take a look at the maven-book project. The inheritance and multi-module relationships are shown in Figure 3.4, ?maven-book Multi-module vs. Inheritance?.
Figure 3.4. maven-book Multi-module vs. Inheritance
When we build this Maven book you are reading, we run mvn package in a multi-module project named maven-book. This multi-module project includes two submodules: book-examples and book-chapters. Neither of these projects share the same parent, they are related only in that they are modules in the maven-book project. book-examples builds the ZIP and TGZ archives you downloaded to get this book?s example. When we run the book-examples build from book-examples/ directory with mvn package, it has no knowledge that it is a part of the larger maven-book project. book-examples doesn?t really care about maven-book, all it knows in life is that its parent is the top-most POM and that it creates an archive of examples. In this case, the maven-book project exists only as a convenience and as an aggregator of modules.
Each of the three projects: maven-book, book-examples, and book-chapters all list a shared "corporate" parent ? . This is a common practice in organizations which have adopted Maven, instead of having every project extend the Super POM by default, some organizations define a top-level corporate POM that serves as the default parent when a project doesn?t have any good reason to depend on another. In this book example, there is no compelling reason to have book-examples and book-chapters share the same parent POM, they are entirely different projects which have a different set of dependencies, a different build configuration, and use drastically different plugins to create the content you are now reading. The POM gives the organization a chance to customize the default behavior of Maven and supply some organization-specific information to configure deployment settings and build profiles.
Multi-module Enterprise Project
Let?s take a look at an example that provides a more accurate picture of a real-world project where inheritance and multi-module relationships exist side by side. Figure 3.5, ?Enterprise Multi-module vs. Inheritance? shows a collection of projects that resemble a typical set of projects in an enterprise application. There is a top-level POM for the corporation with an artifactId of . There is a multi-module project named big-system which references sub-modules server-side and client-side.
Figure 3.5. Enterprise Multi-module vs. Inheritance
What?s going on here? Let?s try to deconstruct this confusing set of arrows. First, let?s take a look at big-system. The big-system might be the project that you would run mvn package on to build and test the entire system. big-system references submodules client-side and server-side. Each of these projects effectively rolls up all of the code that runs on either the server or on the client. Let?s focus on the server-side project. Under the server-side project we have a project called server-lib and a multi-module project named web-apps. Under web-apps we have two Java web applications: client-web and admin-web.
Let?s start with the parent/child relationships from client-web and admin-web to web-apps. Since both of the web applications are implemented in the same web application framework (let?s say Wicket), both projects would share the same set of core dependencies. The dependencies on the Servlet API, the JSP API, and Wicket would all be captured in the web-apps project. Both client-web and admin-web also need to depend on server-lib, this dependency would be defined as a dependency between web-apps and server-lib. Because client-web and admin-web share so much configuration by inheriting from web-apps, both client-web and admin-web will have very small POMs containing little more than identifiers, a parent declaration, and a final build name.
Next we focus on the parent/child relationship from web-apps and server-lib to server-side. In this case, let?s just assume that there is a separate working group of developers which work on the server-side code and another group of developers that work on the client-side code. The list of developers would be configured in the server-side POM and inherited by all of the child projects underneath it: web-apps, server-lib, client-web, and admin-web. We could also imagine that the server-side project might have different build and deployment settings which are unique to the development for the server side. The server-side project might define a build profile that only makes sense for all of the server-side projects. This build profile might contain the database host and credentials, or the server-side project?s POM might configure a specific version of the Maven Jetty plugin which should be universal across all projects that inherit the server-side POM.
In this example, the main reason to use parent/child relationships is shared dependencies and common configuration for a group of projects which are logically related. All of the projects below big-system are related to one another as submodules, but not all submodules are configured to point back to parent project that included it as a submodule. Everything is a submodule for reasons of convenience, to build the entire system just go to the big-system project directory and run mvn package. Look more closely at the figure and you?ll see that there is no parent/child relationship between server-side and big-system. Why is this? POM inheritance is very powerful, but it can be overused. When it makes sense to share dependencies and build configuration, a parent/child relationship should be used. When it doesn?t make sense is when there are distinct differences between two projects. Take, for example, the server-side and client-side projects. It is possible to create a system where client-side and server-side inherited a common POM from big-system, but as soon as a significant divergence between the two child projects develops, you then have to figure out creative ways to factor out common build configuration to big-system without affecting all of the children. Even though client-side and server-side might both depend on Log4J, they also might have distinct plugin configurations.
There?s a certain point defined more by style and experience where you decide that minimal duplication of configuration is a small price to pay for allowing projects like client-side and server-side to remain completely independent. Designing a huge set of thirty plus projects which all inherit five levels of POM configuration isn?t always the best idea. In such a setup, you might not have to duplicate your Log4J dependency more than once, but you?ll also end up having to wade through five levels of POM just figure out how Maven calculated your effective POM. All of this complexity to avoid duplicating five lines of dependency declaration. In Maven, there is a "Maven Way", but there are also many ways to accomplish the same thing. It all boils down to preference and style. For the most part, you won?t go wrong if all of your submodules turn out to define back-references to the same project as a parent, but your use of Maven may evolve over time.
Prev : 3.5. Project Relationships
TOC
Next : Chapter 4. The Build Lifecycle
Nexus Professional
Access a live demo of the Pro Suite Install a trial version of Nexus Professional on your own machine Purchase a license for Nexus Professional
Recent Posts
Last Chance To Register: Insight for CI Demo
Insight for CI Demo: Additional Session Added
When Licenses Meet Reality, the Result is Often Confusing
How does Insight handle conflicting OSS licenses?
New Webinar: Gain Visibility & Control At Build Time with Insight for CI
"What is eCPM? What affects my eCPM? What can I do to earn a higher eCPM?" Effective cost per thousand impressions (eCPM) is the amount of revenue you can expect to earn from AdSense for every 1000 impressions shown on your site. Since eCPM helps you measure how well your ads are performing, we often hear questions from publishers about the factors that impact this metric and how it relates to their earnings. If you're using the new interface, you'll see that your reports show RPM (revenue per thousand impressions); RPM is just another term for eCPM, and it's calculated the same way, so we use these two terms interchangeably. To help provide some clarity, we're kicking off a two-part video series with more insights into how eCPM is calculated in order to help you maximize earnings. With the help of AdSense optimization specialist, Matthew Carpenter Arevalo, we'll show you the factors that affect eCPM, how to track user behavior and traffic patterns, and ...
Comments