| At line 1 changed 1 line. |
| [I|MattRaible]'ve been told I should use Tomcat's Ant Tasks (install, list, refresh, remove) in [AppFuse] to ease deployment of the app. So I tried that today (June 24, 2003). Here's how I set it up and what I found. I hope to use this page to get a consensus on how these tasks should be used. |
| [I|MattRaible] finally figured out how to use Tomcat's Ant Tasks (install, remove, reload, start, stop, list) in [AppFuse] to ease deployment of the app. Below is a list of of the steps I used to integrate them into my build.xml file. |
| At line 3 changed 1 line. |
| 1. First, I defined a tomcat.classpath for the catalina-ant.jar file. Putting in in $ANT_HOME/lib did not work - and this way seemed cleaner. So in __properties.xml__, I added: |
| 1. Rather than defining each task with a <taskdef>, I created a tomcatTasks.properties file with the following contents: |
| At line 5 changed 5 lines. |
| <!-- For Tomcat Tasks --> |
| <path id="tomcat.classpath"> |
| <fileset dir="${tomcat.home}/server/lib" |
| includes="catalina-ant.jar" /> |
| </path> |
| deploy=org.apache.catalina.ant.DeployTask |
| install=org.apache.catalina.ant.InstallTask |
| list=org.apache.catalina.ant.ListTask |
| reload=org.apache.catalina.ant.ReloadTask |
| remove=org.apache.catalina.ant.RemoveTask |
| resources=org.apache.catalina.ant.ResourcesTask |
| roles=org.apache.catalina.ant.RolesTask |
| start=org.apache.catalina.ant.StartTask |
| stop=org.apache.catalina.ant.StopTask |
| undeploy=org.apache.catalina.ant.UndeployTask |
| At line 11 changed 1 line. |
| 2. Then in __build.xml__, I define the tasks in the "define-tasks" target: |
|
| 2. Then I created a tomcat.properties file with the following contents. Make sure the $CATALINA_HOME/conf/tomcat-users.xml file has an entry with username/password __admin/admin__ and that they have the __manager__ role. |
| At line 13 changed 13 lines. |
| <!-- Tomcat Tasks --> |
| <taskdef name="install" |
| classname="org.apache.catalina.ant.InstallTask" |
| classpathref="tomcat.classpath" /> |
| <taskdef name="list" |
| classname="org.apache.catalina.ant.ListTask" |
| classpathref="tomcat.classpath" /> |
| <taskdef name="reload" |
| classname="org.apache.catalina.ant.ReloadTask" |
| classpathref="tomcat.classpath" /> |
| <taskdef name="remove" |
| classname="org.apache.catalina.ant.RemoveTask" |
| classpathref="tomcat.classpath" /> |
| # Properties for Tomcat Server |
| tomcat.server=localhost |
| tomcat.manager.url=http://${tomcat.server}:8080/manager |
| tomcat.username=admin |
| tomcat.password=admin |
| At line 27 changed 1 line. |
| 3. Then I created targets for each one of these tasks: |
|
| 3. I included a reference to tomcat.properties in my build.xml file: |
| At line 29 changed 8 lines. |
| <!-- =================================================================== --> |
| <!-- install, list, reload and remove are all Tomcat deployment targets. --> |
| <!-- =================================================================== --> |
| <target name="install" depends="package-web" |
| description="Install application to servlet container"> |
| <install url="${tomcat.manager.url}" username="${tomcat.username}" |
| password="${tomcat.password}" path="/${webapp.name}" |
| war="file://${webapp.dist}/${webapp.war}"/> |
| <property file="tomcat.properties"/> |
| }}} |
|
| 4. Then I added all a single taskdef and all the targets/tasks I wanted to use to my build.xml file: |
| {{{ |
| <taskdef file="${ant-contrib.dir}/tomcatTasks.properties"> |
| <classpath> |
| <pathelement path="${tomcat.home}/server/lib/catalina-ant.jar"/> |
| </classpath> |
| </taskdef> |
| <target name="install" description="Install application in Tomcat" |
| depends="package-web"> |
| <deploy url="${tomcat.manager.url}" |
| username="${tomcat.username}" |
| password="${tomcat.password}" |
| path="/${webapp.name}" |
| war="file:${webapp.dist}/${webapp.war}"/> |
| At line 39 changed 4 lines. |
| <target name="list" depends="define-tasks" |
| description="List installed applications on servlet container"> |
| <list url="${tomcat.manager.url}" username="${tomcat.username}" |
| password="${tomcat.password}" /> |
| <target name="remove" description="Remove application in Tomcat"> |
| <undeploy url="${tomcat.manager.url}" |
| username="${tomcat.username}" |
| password="${tomcat.password}" |
| path="/${webapp.name}"/> |
| At line 45 changed 4 lines. |
| <target name="refresh" depends="package-web" |
| description="Reload application on servlet container"> |
| <reload url="${tomcat.manager.url}" username="${tomcat.username}" |
| password="${tomcat.password}" path="/${webapp.name}"/> |
| <target name="reload" description="Reload application in Tomcat"> |
| <reload url="${tomcat.manager.url}" |
| username="${tomcat.username}" |
| password="${tomcat.password}" |
| path="/${webapp.name}"/> |
| At line 51 changed 4 lines. |
| <target name="remove" depends="define-tasks" |
| description="Remove application on servlet container"> |
| <remove url="${tomcat.manager.url}" username="${tomcat.username}" |
| password="${tomcat.password}" path="/${webapp.name}"/> |
| <target name="start" description="Start Tomcat application"> |
| <start url="${tomcat.manager.url}" |
| username="${tomcat.username}" |
| password="${tomcat.password}" |
| path="/${webapp.name}"/> |
| At line 56 removed 2 lines. |
| }}} |
| __NOTE:__ I used "refresh" as a target name since I already have a "reload" task that stops tomcat, undeploys, cleans and redeploys. |
| At line 59 changed 1 line. |
| 4. My understanding is that I should be able to point the ''install'' and ''refresh'' tasks at the .war file for my app, and it'll install/reload as requested. The ''list'' and ''remove'' tasks work fine at this point. |
| <target name="stop" description="Stop Tomcat application"> |
| <stop url="${tomcat.manager.url}" |
| username="${tomcat.username}" |
| password="${tomcat.password}" |
| path="/${webapp.name}"/> |
| </target> |
| At line 61 changed 5 lines. |
| ---- |
| !!My Issues: |
| __Install: Doesn't work.__ I get the good ol' {{java.sql.SQLException: Cannot load JDBC driver class 'null'}}. Everything looks fine from the Ant side though: |
| {{{ |
| [install] OK - Installed application at context path /appfuse |
| <target name="list" description="List Tomcat applications"> |
| <list url="${tomcat.manager.url}" |
| username="${tomcat.username}" |
| password="${tomcat.password}"/> |
| </target> |
| At line 67 removed 1 line. |
| If I restart Tomcat, everything starts and loads just fine. |
| At line 69 changed 9 lines. |
| __Remove: Doesn't seem to work__, but it actually does. Here's what Ant reports: |
| {{{ |
| [remove] FAIL - Encountered exception java.io.IOException: java.lang.NullPointerException |
| }}} |
| If I run the same task again, I get: |
| {{{ |
| [remove] FAIL - No context exists for path /appfuse |
| }}} |
| Proving that it actually did work the first time. |
| __NOTE: There are a few things I discovered in this process:__ |
| At line 79 changed 5 lines. |
| __Reload: Doesn't work__: |
| {{{ |
| [reload] FAIL - Reload not supported on WAR deployed at path /appfuse |
| }}} |
| Even though my context has ''reloadable="true"'' |
| * If you put a ''context.xml'' file in your WAR's META-INF directory, the __deploy__ task will recognize it and use it. This is the same as defining your context in server.xml or putting an ''appname.xml'' file in $CATALINA_HOME/webapps. In Tomcat 4, this only works with the deploy task. In Tomcat 5, this will work with any war - even if you just drop it into $CATALINA_HOME/webapps. |
| At line 85 changed 5 lines. |
| ---- |
| !!My Thoughts |
| * The problem might be that I'm not pointing to a build/appfuse directory that contains an already intact webapp directory structure - instead I'm pointing to a ''real'' .war file. My context has __path="/appfuse"__ rather than ''path="/appfuse.war"'', so I wonder if that matters. |
| * Reload seems pointless to me, I still have to deploy (copy files to $CATALINA_HOME/webapp) to Tomcat, and when I do this with Ant's <copy> task, Tomcat reloads the app automagically. |
| * Using these tasks seems like a waste of time - especially since I'm just replacing something that already works for me. Please, someone prove me wrong. And not with points and counterpoints - but by checking out [AppFuse] from CVS and submitting patches. ;-) |
| ;:''That's a very slick feature IMO. Now if there was only a way to deploy the JDBC Driver with the WAR and have it auto-deployed to $CATALINA_HOME/common/lib.'' |
| At line 91 changed 1 line. |
| ~ [MattRaible] |
| * All these tasks will overwrite your server.xml file in Tomcat 4.1.x. They do create a backup, but if you're having configuration issues after using these, revert back to your original server.xml. I've included a [minimal server.xml|server-4.1.29.xml] for Tomcat 4.1.29. Also, the war is deployed under the ''$CATALINA_HOME/work/Standalone/localhost/manager'' directory. |
| * In Tomcat 4.1.x, the ''reload'' target doesn't work with WARs. You have to use "ant stop start" to simulate a reload. |
| At line 93 changed 2 lines. |
| ---- |
| !!Comments |
| __The good news is that all of the issues that occur in Tomcat 4.1.x are gone in Tomcat 5.__ |
| At line 96 changed 63 lines. |
| __Install: Doesn't work.__: Well, you need to specify the context XML file also (it's a separate deployment, so the existing one doesn't get picked up automatically). If the Context element is in server.xml, then it won't work. |
|
| __Remove: Doesn't seem to work__: I don't know about that one. Probably the fact that there a context file is causing trouble of some sort. |
|
| __Reload: Doesn't work__: You can't reload a WAR indeed (you undeploy it, and then redeploy it when it is updated; however, its content cannot change unless the WAR itself changes, that's why reloading has no meaning for a WAR). Webapp reloading is for automatic class change tracking. It doesn't prevent any manual reloading. |
|
| The behavior of the deployer and its related tasks will be more intuitive in TC 5, and more integrated with the auto deployer. the latest nightly has a lot of this stuff implemented [http://cvs.apache.org/builds/jakarta-tomcat-5/nightly/jakarta-tomcat-5-bin-20030624.tar.gz]. Note that both install and remove are now deprecated, replaced by deploy and undeploy. |
|
| ~ Remy ~ |
|
| !! Corrections |
| Comments and suggestions are not quite correct. \\ |
| I have not changed earlier contributions - instead I have added some coding samples that really work.\\ |
|
| Newer distributions (Tomcat4.1.24, Tomcat4.1.27) document in detail the usage of the ant tasks, see Manager_App_HOW-TO in the tomcat-docs. \\ |
| A very confusing point is the different syntax of the war attribute : In target install you need the syntax of a jar-URL: |
| {{{ |
| <!-- Install war file to servlet container --> |
| <target name="install"> |
| <install url="${managerapp.url}" |
| username="${managerapp.userid}" |
| password="${managerapp.password}" |
| path="/${context}" |
| war="jar:file:${build.dir}/${war.file}!/" /> |
| </target> |
| }}} |
| On the other hand, the deploy target uses a simple file-URL: |
| {{{ |
| <!-- Deploy an application to servlet container --> |
| <target name="deploy"> |
| <deploy url="${managerapp.url}" |
| username="${managerapp.userid}" |
| password="${managerapp.password}" |
| path="/${context}" |
| war="file:${build.dir}/${war.file}" /> |
| </target> |
| }}} |
| Other targets that do not require a war attribute are uncritical, eg |
| {{{ |
| <!-- Remove an application on servlet container --> |
| <target name="remove"> |
| <remove url="${managerapp.url}" |
| username="${managerapp.userid}" |
| password="${managerapp.password}" |
| path="/${context}" /> |
| </target> |
| }}} |
| There is one remaining problem with the undeploy target - in some circumstances the target does not complete but ends up with an error message: |
| {{{ |
| <!-- Undeploy an application from servlet container --> |
| <target name="undeploy"> |
| <undeploy url="${managerapp.url}" |
| username="${managerapp.userid}" |
| password="${managerapp.password}" |
| path="/${CONTEXT}" /> |
| </target> |
|
| FAIL - Cannot remove document base for path /eai_sc |
| }}} |
| The reason seems to be some locking by the Tomcat server itself. While Tomcat is running, even a remove (rm -rf under Unix) doesn´t work. \\ |
| As a workaround you can also use the remove task to withdraw the deployment of your webapp. |
|
| ~ Martin Wolf ~ |
| * In Tomcat 5, the server.xml is __not__ overwritten. The context.xml is extracted where you would expect it ($CATALINA_HOME/conf/Catalina/localhost), and the WAR is deployed (and expanded) to the webapps directory. |
| |
| * The ''reload'' target works in Tomcat 5 - providing you don't have any non-serializeable attributes in your session. |