How to handle redeploy of java WARs to tomcat5.5 on Windows and avoid jar file locking
Windows will lock files under Tomcat WEB-INF/lib and prevent redeploys of WARs
At some point recently I began having this problem where windows was locking the jar files in airweb/WEB-INF/lib every time. Prior I would have 3-4 times while I could redeploy before getting tomcat permgen errors in tomcat before having to stop tomcat manually and delete web application files and restart tomcat and redeploy.
2. Manually shuts down the windows service (net stop Tomcat5)
3. Deletes files similar to with ransack
4. unwars the war (instead of remote deploying with maven cargo plugin –saves about 30 seconds)
5. starts windows service (net start Tomcat5)
6.Checks in code to subversion if a deploy is done
7.Open a browser with my web application
Basically this completely removes tomcat hotdeploy and removes the windows file locking issues. If tomcat is not already started script will run to completion but you will see a 2 return code early in the process, however it doesnt halt any subsequent steps.
net start Tomcat5
net stop Tomcat5
You have tomcat installed at C:/opt/tomcat
You have tomcat installed as a windows service called Tomcat5
You are running the OS Windows XP, if not then change the os in the exec command to match whatever System.getProperty("os.name") returns, otherwise these ant scripts wont fire.
A mvn –U clean deploy took about 1:30 to 1:40 on my machine
A mvn –U clean install took about 1:15
For example in my web applications pom.xml
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>stop-delete-from-tomcat</id>
<phase>generate-sources</phase>
<configuration>
<tasks>
<property name="cp"
refid="maven.compile.classpath" />
<echo>
Maven Dependency Classpath is ${cp}
</echo>
<property name="catalina.home"
value="c:/opt/tomcat" />
<echo message="Stop Tomcat" />
<exec dir="${basedir}" executable="cmd.exe" os="Windows XP"
output="${catalina.home}/logs/catalina.out" >
<arg line="/c net stop Tomcat5"/>
</exec>
<echo>
Deleting ${artifactId} from tomcat
</echo>
<echo>
=====================================================
</echo>
<!-- may or may not be there -->
<delete file="${catalina.home}/webapps/${artifactId}.war" />
<!-- can only delete if tomcat is stopped -->
<delete file="${catalina.home}/conf/Catalina/localhost/${artifactId}.xml" />
<delete dir="${catalina.home}/work/Catalina/localhost/${artifactId}" />
<delete dir="${catalina.home}/webapps/${artifactId}" />
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
<execution>
<id>unwar-exploded-start-tomcat</id>
<phase>pre-integration-test</phase>
<configuration>
<tasks>
<property name="catalina.home"
value="c:/opt/tomcat" />
<unwar src="${basedir}/target/${artifactId}.war" dest="${catalina.home}/webapps/${artifactId}" />
<echo message="Start Tomcat" />
<exec dir="${basedir}" executable="cmd.exe" os="Windows XP"
output="${catalina.home}/logs/catalina.out" >
<arg line="/c net start Tomcat5"/>
</exec>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
<execution>
<id>open-browser</id>
<phase>install</phase>
<configuration>
<tasks>
<!-- open browser with homepage -->
<property name="browser"
location="C:/Program Files/Internet Explorer/IEXPLORE.EXE" />
<property name="url"
value="http://localhost:8080/airweb/login.do" />
<exec executable="${browser}"
spawn="true">
<arg value="${url}" />
</exec>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
Adding a commit comment from eclipse external command to the pom scm checkin/commit
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-scm-plugin</artifactId>
<version>1.0</version>
<configuration>
<connectionType>connection</connectionType>
<message>MVN:${scm.message}</message>
<includes>
src/**,test/**,pom.xml,build.xml
</includes>
</configuration>
<executions>
<!-- svn update -->
<execution>
<id>update</id>
<phase>generate-sources</phase>
<goals>
<goal>update</goal>
</goals>
</execution>
<!-- svn add -->
<!-- svn commit -->
<execution>
<id>add-checkin</id>
<phase>deploy</phase>
<goals>
<goal>add</goal>
<goal>checkin</goal>
</goals>
</execution>
</executions>
</plugin>
And then in the External Command in eclipse for deploying:
Location:
${maven_exec}
Arguments:
-U clean deploy -Dscm.message="${string_prompt:scm.message}"
The last line will give you a prompt or alert box which will set the entered text as a maven property and this will be used the maven scm plugin message and subversion commit comment.
We also tried blocking commits with subversion hooks if they didnt have this MVN comment in them. However this didnt work out very well in practice and we stopped using the subversion hooks to block commits that didnt come from maven. Still since using this we have had much less problems with subversion commited code that wasnt maven deployed. Or maven deployments that werent commited to subversion.
Re: How to handle redeploy of java WARs to tomcat5.5 on Windows and avoid jar file locking
You then proceed to explain that you use Maven to script the shut down and restart of the server. This does not really solve the problem of the application not undeploying and the need to restart the server.
If you need to test the application against a centralized test server which is shared by other developers and applications you still have the same problem you had before. You cannot redeploy an application without shutting down the server and possibly disrupting other applications. Unfortunately, for me this means I cannot redeploy my applications on the test server as the server admins where I work will not give developers rights to shut down the servers in order to redeploy, and rightfully so.
I do believe that the reason the jars in my applications are locking is something other than Windows though (especially since the test server runs on Unix, though I do use Windows to develop). I know that struts tiles jars were locking because of the use of the DTDs in the tiles definition files. I still have to find out why the jdbc, and poi jars are locking. I have already created a listener to deregister the jdbc drivers for the application when the application stops.
It is too bad there is not a simpler solution which would just remove the classloader when the application is undeployed and free all the files. Jars and resources locking and not allowing undeployment really is a huge headache for something which should be much simpler.
