2

I am experiencing a problem with TomCat 7 any changes i make to the application and i build using ant to see those changes i have to constantly restart the server. Only when the server is shutdown then i can build and deploy then restart the server and it will work.

If i do not restart the server and i undeploy and deploy it the application i will get a http :404 error.

Can some one please tell me what i need to do to avoid this restart at every change it annoying.

ANT build File:

<?xml version="1.0"?>


<project name="app" basedir="." default="usage">
    <property file="build.properties"/>

    <property name="src.dir" value="src"/>
    <property name="web.dir" value="war"/>
    <property name="build.dir" value="${web.dir}/WEB-INF/classes"/>
    <property name="name" value="crimeTrack"/>

    <path id="master-classpath">
        <fileset dir="${web.dir}/WEB-INF/lib">
            <include name="*.jar"/>
        </fileset>

        <fileset dir="${appserver.lib}">
            <include name="servlet*.jar"/>

        </fileset>

        <pathelement path="${build.dir}"/>
    </path>

    <target name="usage">
        <echo message=""/>
        <echo message="${name} build file command list"/>
        <echo message="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"/>       
        <echo message="                | Targets: ANT                                    |"/>                                       
        <echo message="                ---------------------------------------------------"/>
        <echo message="                | build     --: Build the application             |"/>             
        <echo message="                ---------------------------------------------------"/>
        <echo message="                | deploy    --: Deploy application as directory   |"/>
        <echo message="                ---------------------------------------------------"/>
        <echo message="                | deploywar --: Deploy application as a WAR file  |"/>
        <echo message="                ---------------------------------------------------"/>
        <echo message="                | install   --: Install application in Tomcat     |"/>
        <echo message="                ---------------------------------------------------"/>
        <echo message="                | reload    --: Reload application in Tomcat      |"/>
        <echo message="                ---------------------------------------------------"/>
        <echo message="                | start     --: Start Tomcat application          |"/>
        <echo message="                ---------------------------------------------------"/>
        <echo message="                | stop      --: Stop Tomcat application           |"/>
        <echo message="                ---------------------------------------------------"/>
        <echo message="                | list      --: List Tomcat applications          |"/>
        <echo message="                ---------------------------------------------------"/>
        <echo message="                ___________________________________________________"/>
        <echo message="                Targets: Database                                  "/>
        <echo message="                ___________________________________________________"/>
        <echo message="                | createTables --: Creates Database Tables        |"/>
        <echo message="                ---------------------------------------------------"/>
        <echo message="                | emptyTables --: Empty Database Tables           |"/>
        <echo message="                ---------------------------------------------------"/>
        <echo message="                | loadData  --: Loads data into Database Tables   |"/>
        <echo message="                ---------------------------------------------------"/>
        <echo message="                | showTables --: Lists the tables in Database     |"/>
        <echo message="                ---------------------------------------------------"/>
        <echo message="                ___________________________________________________"/>
        <echo message="                Targets: Junit                                     "/>
        <echo message="                ___________________________________________________"/>
        <echo message="                | tests --: Runs test on all objects using JUNIT  |"/> 
        <echo message=                 "${deploy.path}/${name} and ${build.dir}" /> 
        <echo message="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"/>
    </target>

    <target name="build" description="Compile main source tree java files">
        <mkdir dir="${build.dir}"/>
        <javac destdir="${build.dir}" source="1.7" target="1.7" debug="true" includeantruntime="false" 
               deprecation="false" optimize="false" failonerror="true">
            <src path="${src.dir}"/>
            <classpath refid="master-classpath"/>
        </javac>
    </target>

    <target name="deploy" depends="build" description="Deploy application">
        <copy todir="${deploy.path}/${name}" preservelastmodified="true">
            <fileset dir="${web.dir}">
                <include name="**/*.*"/>
            </fileset>
        </copy>
    </target>

    <target name="deploywar" depends="build" description="Deploy application as a WAR file">
        <war destfile="${name}.war"
             webxml="${web.dir}/WEB-INF/web.xml">
            <fileset dir="${web.dir}">
                <include name="**/*.*"/>
            </fileset>
        </war>
        <copy todir="${deploy.path}" preservelastmodified="true">
            <fileset dir=".">
                <include name="*.war"/>
            </fileset>
        </copy>
    </target>

<!-- ============================================================== -->
<!--                           Tomcat tasks                         -->
<!-- ============================================================== -->

    <path id="catalina-ant-classpath">
        <!-- We need the Catalina jars for Tomcat -->
        <!--  * for other app servers - check the docs -->
        <fileset dir="${appserver.lib}">
            <include name="catalina-ant.jar"/>
        </fileset>
    </path>

    <taskdef name="install" classname="org.apache.catalina.ant.DeployTask">
        <classpath refid="catalina-ant-classpath"/>
    </taskdef>
    <taskdef name="reload" classname="org.apache.catalina.ant.ReloadTask">
        <classpath refid="catalina-ant-classpath"/>
    </taskdef>
    <taskdef name="list" classname="org.apache.catalina.ant.ListTask">
        <classpath refid="catalina-ant-classpath"/>
    </taskdef>
    <taskdef name="start" classname="org.apache.catalina.ant.StartTask">
        <classpath refid="catalina-ant-classpath"/>
    </taskdef>
    <taskdef name="stop" classname="org.apache.catalina.ant.StopTask">
        <classpath refid="catalina-ant-classpath"/>
    </taskdef>

    <target name="install" description="Install application on the Tomcat Server">
        <install url="${tomcat.manager.url}"
                 username="${tomcat.manager.username}"
                 password="${tomcat.manager.password}"
                 path="/${name}"
                 war="${name}"/>
    </target>

    <target name="reload" description="Reload application on the Tomcat Server">
        <reload url="${tomcat.manager.url}"
                 username="${tomcat.manager.username}"
                 password="${tomcat.manager.password}"
                 path="/${name}"/>
    </target>

    <target name="start" description="Start Tomcat application">
        <start url="${tomcat.manager.url}"
                 username="${tomcat.manager.username}"
                 password="${tomcat.manager.password}"
                 path="/${name}"/>
    </target>

    <target name="stop" description="Stop Tomcat application">
        <stop url="${tomcat.manager.url}"
                 username="${tomcat.manager.username}"
                 password="${tomcat.manager.password}"
                 path="/${name}"/>
    </target>

    <target name="list" description="List Tomcat applications on server">
        <list url="${tomcat.manager.url}"
                 username="${tomcat.manager.username}"
                 password="${tomcat.manager.password}"/>
    </target>

<!-- End Tomcat tasks -->


<!-- ============================================================== -->
<!--                          TESTING JUNIT                         -->
<!-- ============================================================== -->

     <property name="test.dir" value="test"/>


    <path id="test-classpath">
                <fileset dir="${web.dir}/WEB-INF/lib">
                    <include name="*.jar"/>
                </fileset>
                <pathelement path="${build.dir}"/>
                <pathelement path="${test.dir}"/>
                <pathelement path="${web.dir}/WEB-INF/classes"/>
    </path>


        <target name="buildtests" description="Compile test tree java files">
            <mkdir dir="${build.dir}"/>
            <javac destdir="${build.dir}" source="1.7" target="1.7" debug="true"
                deprecation="false" optimize="false" failonerror="true">
                <src path="${test.dir}"/>
                <classpath refid="master-classpath"/>
            </javac>
        </target>

        <target name="tests" depends="build, buildtests" description="Run tests">
            <junit printsummary="on"
                fork="false"
                haltonfailure="false"
                failureproperty="tests.failed"
                showoutput="true">
                <classpath refid="test-classpath"/>
                <formatter type="brief" usefile="false"/>

                <batchtest>
                    <fileset dir="${build.dir}">
                        <include name="**/*Tests.*"/>
                        <exclude name="**/Jdbc*Tests.*"/>
                    </fileset>
                </batchtest>

            </junit>

            <fail if="tests.failed">
                tests.failed=${tests.failed}
                ***********************************************************
                ***********************************************************
                *************     Testing Found Errors!...    *************
                ***********************************************************
                ***********************************************************
            </fail>
        </target>

     <target name="dbTests" depends="build, buildtests,emptyTables,createTables,loadData" 
                description="Run db tests">
            <junit printsummary="on"
                fork="false"
                haltonfailure="false"
                failureproperty="tests.failed"
                showoutput="true">
                <classpath refid="test-classpath"/>
                <formatter type="brief" usefile="false"/>

                <batchtest>
                    <fileset dir="${build.dir}">
                        <include name="**/Jdbc*Tests.*"/>
                    </fileset>
                </batchtest>

            </junit>

            <fail if="tests.failed">
                tests.failed=${tests.failed}
                ***********************************************************
                ***********************************************************
                *************     Testing Found Errors!...    *************
                ***********************************************************
                ***********************************************************
            </fail>
        </target>

      <target name="clean" description="Clean output directories">
            <delete>                
                <fileset dir="${build.dir}">
                    <include name="**/*.class"/>
                </fileset>
            </delete>
        </target>

        <target name="undeploy" description="Un-Deploy application">
            <delete>
                <fileset dir="${deploy.path}/${name}">
                    <include name="**/*.*"/>
                </fileset>
            </delete>
        </target>



    <!-- ============================================================== -->
    <!--                          DataBase CrimeTrack                   -->
    <!-- ============================================================== -->

    <target name="createTables">
            <echo message="CREATE TABLES USING: ${db.driver} ${db.url}"/>
            <sql driver="${db.driver}"
                 url="${db.url}"
                 userid="${db.user}"
                 password="${db.pw}"
                 onerror="continue"
                 src="db/create_database_tables.sql">  
                <classpath refid="master-classpath"/>
            </sql> 
        </target>

        <target name="emptyTables">
            <echo message="EMPTY TABLES USING: ${db.driver} ${db.url}"/>
            <sql driver="${db.driver}"
                 url="${db.url}"
                 userid="${db.user}"
                 password="${db.pw}"
                 onerror="continue"
                 src="db/flush_data.sql">  
                <classpath refid="master-classpath"/>
            </sql> 
        </target>

        <target name="loadData">
            <echo message="LOAD DATA USING: ${db.driver} ${db.url}"/>
            <sql driver="${db.driver}"
                 url="${db.url}"
                 userid="${db.user}"
                 password="${db.pw}"
                 onerror="continue"
                 src="db/load_systems_tables.sql">  
                <classpath refid="master-classpath"/>
            </sql> 
        </target>

        <target name="showTables">
            <echo message="SHOW DATABASE TABLES USING: ${db.driver} ${db.url}"/>
            <sql driver="${db.driver}"
                 url="${db.url}"
                 userid="${db.user}"
                 password="${db.pw}"
                 onerror="continue"
                 print="true">  
                <classpath refid="master-classpath"/>

            SHOW TABLES;

            </sql> 
        </target>

         <target name="shutdownDb">
            <echo message="SHUT DOWN DATABASE USING: ${db.driver} ${db.url}"/>
            <sql driver="${db.driver}"
                 url="${db.url}"
                 userid="${db.user}"
                 password="${db.pw}"
                 onerror="continue">  
                <classpath refid="master-classpath"/>

            SHUTDOWN;

            </sql> 
        </target>   

</project>
devdar
  • 5,564
  • 28
  • 100
  • 153
  • Do you start any threads in your application that keep it from being properly undeployed? Are you holding any other resources that might be locked and not accessible to your new application? How are you redeploying? Through WAR files or plain directory changes? If you're doing directory changes, it might be that you're still changing files while tomcat already deploys, thus it can't fully deploy. Do you see anything in the logs? – Olaf Kock Jan 11 '13 at 11:32
  • No threads are used, nor is the application holding resources since its simple registration form. I am using a war file for deployment. However when i do an undeploy from ant the war file doesnt get deleted i have to stop the service and manually delete it and then run ant deploy ad restart the service – devdar Jan 12 '13 at 00:34

1 Answers1

2

You should probably create ant task which does a hotswap. There's even a project which helps you to do it. Alternatively, you can use jrebel but it is a commercial product.

Community
  • 1
  • 1
mindas
  • 26,463
  • 15
  • 97
  • 154
  • Can hotswap be configured to also replace WAR files as well i am seeing in an example where it replaces class files. I would like for it to replace an entire WAR file – devdar Jan 14 '13 at 19:45
  • Don't think so. Replacing war file is actually a redeploy. As for 404 error, this is not normal - you need to provide more info to help to understand why this happens. – mindas Jan 16 '13 at 02:50
  • What i am doing is a clean, build, deploy and a deploywar once i make a change to the application. When this happens i have to restart the server and run these tasks then restart the server and i will see the changes other than that i get the 404 error. – devdar Jan 16 '13 at 16:53
  • As mentioned, redeploying the newly compiled war is not the technique I was suggesting. If you only changed a few lines in your code and did not make any API changes, you just hotswap the class and it should work without any restarts. This ant project is about hotswap using ant -- but has nothing to do with redeploying .wars. – mindas Jan 19 '13 at 19:15