If your target deployment environment is a Java EE container, then you should be using Cargo for this. Cargo can be called directly through Java or can be invoked through build script plugins - there are plugins for ant and maven (1 and 2).
The following example shows how I've setup a maven project that can deploy a .war artifact immediately after building. This isn't ground breaking stuff, but useful to implement in case you aren't doing it already.
Without further ado, here are relevant parts of the pom.xml file:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.jasonwhaley.sample</groupId>
<artifactId>sample</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>sample</name>
<!-- snip -->
<build>
<plugins>
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.0</version>
<configuration>
<container>
<containerId>tomcat6x</containerId>
<type>remote</type>
</container>
<configuration>
<type>runtime</type>
<properties>
<cargo.tomcat.manager.url>http://ec2-204-236-241-59.compute-1.amazonaws.com:8080/manager</cargo.tomcat.manager.url>
<cargo.remote.username>manager</cargo.remote.username>
<cargo.remote.password>manager</cargo.remote.password>
</properties>
</configuration>
</configuration>
</plugin>
<!-- snip -->
</plugins>
</build>
</project>
Basically, by including the cargo plugin in the
mvn clean install cargo:redeploywhich results in:
[INFO] [cargo:redeploy {execution: default-cli}]
[INFO] [mcat6xRemoteDeployer] Redeploying [/Users/whaley/Repositories/Personal/sample_ci/webapp/target/sample-1.0-SNAPSHOT.war]
[INFO] [mcat6xRemoteDeployer] Undeploying [/Users/whaley/Repositories/Personal/sample_ci/webapp/target/sample-1.0-SNAPSHOT.war]
[INFO] [mcat6xRemoteDeployer] Deploying [/Users/whaley/Repositories/Personal/sample_ci/webapp/target/sample-1.0-SNAPSHOT.war]When it comes to continuous integration, what I prefer to do is setup one build project that builds and tests the .war through `mvn clean install`. Upon completion, I then start another project that does `mvn clean install cargo:redeploy`.
The reason for this separation is that your notification lists for the initial build project should be different than the notification list for deployment project. Developers should be the primary recipient of any notifications from the initial build. After that, any operations member responsible for the target container or development lead probably only need to know about notifications regarding the automated deployment project.
The advantage of orchestrating this through your CI server is that the process is visible to all. If someone notices that the latest commit isn't reflected on the target container (or if the target container doesn't have the build at all), then a quick peek at the CI server can show what step of the process failed simply by looking at the build status and more detail in the build logs.