Cargo + Maven + Two Tomcats
Recently I've been struggling to make Maven execute two Tomcat instances (with different applications on different ports). I decided to put a solution here so you don't have to discover it by yourself.
Goal
The goal was to run two web applications on different ports before integration tests, and once the tests are finished, to stop them.
IMPORTANT If you do not need to run your webapps on different ports than this post is not for you. Simply put more then one webapp under <deployables> of a single Tomcat instance.
Tools
Maven, Maven Cargo Plugin and Tomcat.
Solution
This is how the first application is started:
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<executions>
<execution>
<id>start-first-app</id>
<phase>pre-integration-test</phase>
<configuration>
<container>
<containerId>tomcat7x</containerId>
<zipUrlInstaller>
<url>file:resources/${tomcat.zip.file}</url>
<downloadDir>${project.basedir}/resources</downloadDir>
<extractDir>${project.build.directory}/extracts</extractDir>
</zipUrlInstaller>
<systemProperties>
...
</systemProperties>
<log>${project.build.directory}/first_app.log</log>
</container>
<configuration>
<properties>
<cargo.servlet.port>${first_app.server.port}</cargo.servlet.port>
<cargo.tomcat.ajp.port>${first_app.ajp.port}</cargo.tomcat.ajp.port>
<cargo.rmi.port>${first_app.rmi.port}</cargo.rmi.port>
</properties>
<home>${project.build.directory}/tomcat_first_app</home>
</configuration>
<deployables>
<deployable>
<properties>
<context>ROOT</context>
</properties>
</deployable>
</deployables>
</configuration>
<goals>
<goal>start</goal>
</goals>
</execution>
Things to notice:
containerIdmust be equal to one of the containers supported by Cargo - see here for the full listzipUrlInstaller- I keep zipped Tomcat in SVNsystemProperties- yeah, you can pass some to the Tomcat if you wish (your application can make use of them)log- optional. If not set all logs will go to standard output. In case of more than one web app running, it is sometimes more convenient to have separate logs.configuration properties- this is crucial! Every instance of Tomcat you plan to start during your build must have uniquecargo.servlet.portandcargo.rmi.port. Not sure about thecargo.tomcat.ajp.portbut I added it just in case.home- this is where your Tomcat will be installed.context- this is how you make your application appear under e.g. http://localhost:8080 instead of http://localhost:8080/myappdeployable- nogroupIdorartifactIdmentioned here because we deploy the application from this project (which is of typewar)
Now the configuration for stopping of the first application
<execution>
<id>stop-first-app</id>
<phase>verify</phase>
<configuration>
<container>
<containerId>tomcat7x</containerId>
</container>
<configuration>
<properties>
<cargo.servlet.port>${first_app.server.port}</cargo.servlet.port>
</properties>
<home>${project.build.directory}/tomcat_first_app</home>
</configuration>
</configuration>
<goals>
<goal>stop</goal>
</goals>
</execution>
Three things are identical to the start configuration
containerIdcargo.servlet.porthome
Please notice the phases that were used so far: pre-integration-test and verify. For the second application we have to use different phases because Maven for some reasons does not allow the same plugin to be run twice during the same lifecycle phase.
Ok, let us start the second application:
<execution>
<id>start-second-app</id>
<phase>package</phase>
<configuration>
<container>
<containerId>tomcat7x</containerId>
<zipUrlInstaller>
<url>file:resources/${tomcat.zip.file}</url>
<downloadDir>${project.basedir}/resources</downloadDir>
<extractDir>${project.build.directory}/extracts</extractDir>
</zipUrlInstaller>
<systemProperties>
...
</systemProperties>
<log>${project.build.directory}/second_app.log</log>
</container>
<configuration>
<properties>
<cargo.servlet.port>${second_app.server.port}</cargo.servlet.port>
<cargo.tomcat.ajp.port>${second_app.ajp.port}</cargo.tomcat.ajp.port>
<cargo.rmi.port>${second_app.rmi.port}</cargo.rmi.port>
</properties>
<home>${project.build.directory}/tomcat_second_app</home>
</configuration>
<deployer />
<deployables>
<deployable>
<groupId>some.groupId</groupId>
<artifactId>some.artifact</artifactId>
<type>war</type>
<properties>
<context>ROOT</context>
</properties>
</deployable>
</deployables>
</configuration>
<goals>
<goal>start</goal>
</goals>
</execution>
Nothing new here. Some elements are different though:
phase- it ispacakgethis time - different than previouslylog- if we specify log files it makes sense to make them different (but remember, this is optional)properties- servlet, rmi and ajp ports - if they do not differ you will encounter errorshome- yeah, definitely we need a different directory for this second Tomcatdeployer- this one is tricky - if you do not specify it, cargo will deploy the current application! (provided that it is of type war or ear)deployable- this is a different application (I haven't shown it but you also need to add a dependency for the same artifact - can be with thetestscope.
And now stopping it. There is nothing new here. Notice the different phase (post-integration-test)!
<execution>
<id>stop-second-app</id>
<phase>post-integration-test</phase>
<configuration>
<container>
<containerId>tomcat7x</containerId>
</container>
<configuration>
<properties>
<cargo.servlet.port>${second_app.server.port}</cargo.servlet.port>
</properties>
<home>${project.build.directory}/tomcat_second_app</home>
</configuration>
</configuration>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
Well, that is it. Good luck with your Maven/Cargo development.
P.S. If you have questions please ask them on appropriate mailing lists.



Recent comments
7 weeks 1 day ago
8 weeks 39 min ago
8 weeks 1 hour ago
9 weeks 3 days ago
9 weeks 3 days ago
9 weeks 4 days ago
9 weeks 4 days ago
12 weeks 15 hours ago
12 weeks 18 hours ago
14 weeks 15 hours ago