The Tomcat7 plugin for Maven has a number of uses. In a previous post, I’ve looked at using it to deploy a build to an embedded Tomcat server for integration testing with Selenium.
A more simple use case is to simply deploy (or undeploy) a built artifact (war) to a Tomcat installation on a local machine or on a remote server.
The following examples are available to download from the Spanners Demo on GitHub.
Deploy a single artifact to localhost Tomcat
The Tomcat 7 plugin is added to the pom as follows:
<!-- Deploy wars to Tomcat 7 with mvn tomcat7:deploy or tomcat7:redeploy --> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.1</version> <configuration> <url>http://localhost:8080/manager/text</url> <username>admin</username> <password>admin</password> </configuration> </plugin>
Note that the URL ends with /manager/text. This is the Tomcat plain text based interface that Maven uses to invoke commands in Tomcat.
The username and password must correspond with a Tomcat user with the ‘manager-script’ role. This user is created in Tomcat by adding the following to the tomcat-users.xml file in the <TOMCAT HOME>\conf directory.
<role rolename="manager-script"/> <user username="admin" password="admin" roles="manager-script"/>
The Maven artifact can be built and deployed to Tomcat with the following command:
mvn tomcat7:deploy
and removed with the following command:
mvn tomcat7:undeploy
If the war is already running in Tomcat and you want to make a new build and update it, use the redeploy goal:
mvn tomcat7:redeploy
If the war has already been built and is to be deployed without rebuilding:
mvn tomcat7:deploy-only
Removing the username, password and URL from the pom
If multiple team members are working on the same project, it’s not ideal to store usernames and passwords in the Maven pom file. For a start, you may not want other users knowing your top secret password. Even if this isn’t a problem, another team member may use a different username and password to access their Tomcat.
Maven allows server usernames and passwords to be stored on each user’s own machine in the settings.xml which usually lives in ${user.home}/.m2/settings.xml. Note that it is possible to encrypt passwords in settings.xml, but I won’t cover that here.
In settings.xml, a server is configured as follows:
<server> <id>tomcat-localhost</id> <username>admin</username> <password>admin</password> </server>
Instead of specifying the username and password in the pom, we can specify the server by its id:
<plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <configuration> <server>tomcat-localhost</server> <url>${tomcat.deploy.url}</url> </configuration> </plugin>
In the above example, I’ve also abstracted out the <url> as a Maven property. This allows individual users to override the default setting by using a profile defined in their own settings.xml:
<profiles> <profile> <id>localOverrides</id> <properties> <tomcat.deploy.url>http://localhost:8080/manager/text</tomcat.deploy.url> </properties> </profile> </profiles>
This would be activated as follows:
mvn tomcat7:deploy -PlocalOverrides
Alternatively, the profile could be marked <activeByDefault>true</activeByDefault>.
Deploying multiple artifacts
The Spanners demo consists of three deployable wars: spanners-mvc (Spring MVC demo), spanners-struts (Struts demo) and spanners-ws (Spring Web Services demo). If the above plugin and config is added to all three POMs, they could all be deployed with a single command.
Better yet the plugin and configuration can be added to the root parent project, spanners-pom, in the <pluginManagement> section. Then each child project only need to refer to the plugin by name. The configuration is inherited from the parent.
<plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> </plugin>
Running the following from the project root will deploy all three applications:
mvn tomcat7:deploy
Deploying automatically on builds
It may be desirable to have Maven automatically redeploy the application(s) to a test server on builds. This can be done by binding a Tomcat plugin goal to a Maven execution phase. The following example shows how to automatically deploy all runnable artifacts (wars) to an integration test server when a new build is deployed to the Maven repository. This may be useful in a Continuous Integration (CI) scenario where we want some system running the latest build.
Note here two meanings of the word deploy. deploy is a standard Maven lifecycle phase which uploads an artifact to a remote repository for sharing with other developers. The Tomcat 7 plugin also has a deploy goal which uploads and starts the application in Tomcat. In this example, we want Tomcat updated with the latest build whenever we put an updated build in the Maven repository.
<profiles> <profile> <id>update-itg</id> <build> <plugins> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <!-- Deploy to integration test server on Maven deploy --> <executions> <execution> <id>deploy-to-integrationtest</id> <goals> <goal>redeploy-only</goal> </goals> <phase>deploy</phase> <configuration> <server>integrationtest</server> <url>http://itg.example.com:8080/manager/text</url> </configuration> </execution> </executions> </plugin> </plugins> </build> </profile> </profiles>
In this case the plugin is added to a build profile. This allows us to enable or disable it at command time. It’s disabled by default and can be activated by running:
mvn deploy -Pupdate-itg
The plugin redeploy-only goal is bound to the Maven deploy lifecycle phase. When this is run, the application is built, the artifacts (jars, wars and poms) are uploaded to the Maven repository and the updated application is started up on Tomcat, ready for manual or automated integration testing.
Hi,
I am trying to deploy a war file on remote tomcat server through maven tomcat7 plugin. on my configuration I am using mode=”both” because i want to deploy war as well as context.xml for that particular war.
config in pom.xml
org.apache.tomcat.maven
tomcat7-maven-plugin
2.2
http://192.168.0.0:8080/manager/text
TomcatServer
/MYAPP
both
true
i am getting following ERROR:
[INFO] — tomcat7-maven-plugin:2.2:deploy (default-cli) @ sdms —
[INFO] Deploying war and context to http://192.168.0.0:8080/MYAPP
[INFO] FAIL – Failed to deploy application at context path /MYAPP
Please suggest me if it is possible.
Thank you very much for this tutorial. I was able to deploy my app with maven and it is so much easier now! Thank you sir.
[…] Finally, we need to deploy the Spanners-MVC application. This could also be done using the docker cp command to copy the war to the Tomcat webapp directory. I prefer to have Maven deploy the application as described in a previous post: […]