Tomcat WAR file deploy failure in Windows - java

I have an application running in a tomcat container in Windows environment.
When I have to update the application, the tomcat windows service is stopped, new ROOT.war file is copied in the webapps folder and tomcat service is restarted.
Sometimes it happens that the ROOT.war extraction fails and the extracted ROOT folder has only few subfolder and few files. Obviously the following application startup fails.
To solve this problem I have to stop tomcat, delete ROOT folder and run in again to let tomcat re-extract the ROOT.war again from the beginning.
I cannot understand why sometimes it happens and sometimes no. However, it makes impossibile to me to create an automatic update. It is too risky.
Do you have any idea why it can happen?

Resources are not released. So, when you try to update the existing war file, tomcat is not able to delete the older files before deployment/redeployment.
To resolve this issue, ensure that:
The application is not open/running on web browser.
You're not stuck in debug mode when you click on update.
All processes/requests are completed before redeployment.
All files/streams are closed within the code.
When all else fails, you may want to stop the application. Then update. There are ways to stop applications on tomcat using command line, batch files, etc. You can then automate the process.
If you want a more reliable way to do this, you may use jrebel or a free version of the same. There are other ways to update code. Basically, standalone tomcat is not worth anything more than a development server.

Remark: if you are updating the application while Tomcat is running you need to either:
use Tomcat Manager to deploy it,
call tryAddServiced (before Tomcat 9.0 addServiced/isServiced) before any modification to the webapps directory and removeServiced afterwards. This can be done through JMX on the bean Catalina:type=Deployer,host=<your_host_name>,
replace the WAR file (almost) atomically: e.g. deleting the old one and moving (renaming) the new one from another location on the same filesystem should work.
which prevents Tomcat from immediately deploying the application until the copy operation is finished.
To prevent the OS from locking the files in the webapps/ROOT folder you have two options:
Use antiResourceLocking="true" as already suggested by Svetlin, which basically forces Tomcat to copy webapps/ROOT to a uniquely named temporary directory before deployment (the copy will be locked, webapps/ROOT will not),
Use parallel deployment by naming your WAR files: ROOT##001.war, ROOT##002.war, etc. This is basically an explicit version of the antiResourceLocking feature with the additional advantage of letting clients transition fluently between the old and new app version.

Related

Upate a java file in war file

I am working on a project and the project is in running state. As there is some issue in a java file and I have resolved that issue. But I don't have an idea how to update that particular java file in war file which is deployed on the company server.Please help me out.
Tomcat doesn't support hot deployment. SO you have to restart Tomcat anyhow.
And if you are going to restart it, either replace the .class file(the one which u have changed) or generate new war and then retart Tomcat. Your changes will be reflected.
Update : for hot deployment http://www.mulesoft.com/tomcat-deploy-procedures
You can replace your new java .class file into your extracted project folder under tomcat
http://tomcat.apache.org/tomcat-6.0-doc/manager-howto.html#Reload_An_Existing_Application
This will cause a service interruption anyway, but probably still shorter than restarting the whole server.
Note that this will only works when the web application is deployed from an unpacked directory, otherwise you will have to undeploy and deploy again the web app.
(http://tomcat.apache.org/tomcat-6.0-doc/manager-howto.html#Undeploy_an_Existing_Application)

Problems with Java JRun Cache

Jrun4 came bundled with our install of Coldfusion. Recently we decided to create a new server within JRun to accomodate a new webapp that will always need to be run over SSL.
Long story short. The app was deployed when a bug was found and quickly fixed, recompiled and we redeployed the webapp. As far as JRun is showing the new webapp gets deployed and is being served however, when hitting the webapp none of the new changes are being served up. To verify that the changes are indeed present, I have actually verified the checksum differences and also run a java decompiler on the modified class files and the changes are present. I have added console messages to the app to verify that they get printed to console, none of the new messages appear.
The procedures I have attempted:
Hot deployed the war file, console stated the file was redeployed
Turned off the JRun server hosting the file and restarted it with the modified file.
Completely deleted the existing JRun server hosting the webapp. Shutdown JRun. Restarted and created a new JRun server to host the webapp.
Opened javacpl.exe, Java Control Panel, and deleted all temporary files, applets and applications included.
Downloaded TOMCAT and deployed the same war to the webapps directory, everything showed up correctly. I cannot use tomcat though as the company would need to allow it to be used.
I am now at the point that I think I may need to reimage the entire server and deploy the webapp on a fresh JRun install however, there really must be a better way.
The problem was due to an older version of the war being programmatically added to the java classpath that jrun was using.
This was causing it to reference classes from the classpath rather then the newer deployed classes.

Modifying startup script for tomcat deployment using Maven

I am using a profiling tool, which gets loaded as and when I startup Tomcat with the application war file placed in the webapps directory. So once I run startup, my classes get instrumented and everything works fine.
But for this, I am taking the war file generated as part of maven install ( which downloads tomcat and deploys the war file in it) , and placing it in another tomcat which I have downloaded manually. Then I need to do some editing in the catalin.bat file, to set the JAVA_OPTS property to the javaagent so that it gets started on startup.
What I would like to do is, setup the tool and integrate it with maven such that on a clean and install, the classes gets instrumented and the profiling tool starts running. I believe we can do some configuration changes in pom.xml to achieve this? Any help in this regard would be greatly appreciated! Thanks
This is only part of what you need, but you should configure your tomcat in a different way - maybe this eases your task sufficiently that you'll be able to solve the rest yourself:
You don't need to update catalina.bat - instead create a file named setenv.bat in the same directory: It's not included in tomcat, but if it's there, it will be taken into account during startup/shutdown of tomcat.
Speaking about startup/shutdown: The JAVA_OPTS that you set in this file will be used for startup as well as shutdown (there's a java process started when tomcat shall shut down, running for a brief time). If you have massive memory requirements, allocate JMX ports etc, these will apply for both processes, thus may be conflicting. You rather want to set CATALINA_OPTS - this is just used for starting tomcat, not for shutting it down.
So, the typical content for setenv.bat is
SET CATALINA_OPTS="-DyourSettings -DwhateverYouLike"
And, by the way, the same works for setenv.sh on other platforms

Can not put anything into /var/lib/tomcat7/webapps/

I was starting on JAVA web development today and encountered some problems, I installed my tomcat7 on my ubuntu machine. Now when I browse to //localhost:8080, I get the default welcome page saying:
This is the default Tomcat home page. It can be found on the local filesystem at: /var/lib/tomcat7/webapps/ROOT/index.html
Tomcat7 veterans might be pleased to learn that this system instance of Tomcat is installed with CATALINA_HOME in /usr/share/tomcat7 and CATALINA_BASE in /var/lib/tomcat7, following the rules from /usr/share/doc/tomcat7-common/RUNNING.txt.gz.
But strangely when I try echo $CATALINA_HOME nothing shows up.
Also I can not copy/create anything in the default /var/lib/tomcat7/ROOT though it's just a matter of providing few permissions but I was wondering whether it is the right way to do it?,
What I would like to do is create a separate directory in my home where I can put my web application and tomcat can read hem from there. Is there a way to do it? In apache I can do it by changing the document-root and directory but I don't know how to do it for tomcat
But strangely when I try echo $CATALINA_HOME nothing shows up.
This is because the packaged version sets CATALINA_HOME just prior to launching Tomcat, after reading it from a configuration file (typically somewhere in /etc).
Also I can not copy/create anything in the default
/var/lib/tomcat7/ROOT though it's just a matter of providing few
permissions but I was wondering whether it is the right way to do it?
The permissions problem has to do with you not being root (or the Tomcat user). Most packaged Tomcat installations (deb or RPM) tend to install with a specific user in mind, and copying stuff in as a different sometimes won't work.
/usr/share/tomcat7 is your CATALINA_HOME directory, and it has links to the other directories, such as /var/lib/tomcat7/webapps, /etc/tomcat7, etc. You shouldn't copy directly into a web application, you should package the web application into a WAR file and "deploy" it. The advantages are numerous.
What I would like to do is create a separate directory in my home
where I can put my web application and tomcat can read hem from there.
Is there a way to do it?
Yes, one is created when "deploying a web app". Look to the standard Tomcat7 documentation, and consider installing the "manager" web application if you like a non-command line interface. Now that you know what "installation" of a web app is called, it will likely be an easier task.
In apache I can do it by changing the document-root and directory but
I don't know how to do it for tomcat
Tomcat has a different, slightly more restrictive set of requirements for a document-root. You need to learn it, and just come to terms with the idea that it's never going to be the same. Basically under the "webapps" directory, is a WAR file or a expanded directory that came from a WAR file. Editing in-place is not a good idea for Tomcat, as the CGI-equivalents are not read from disk each time they are ran, they are linked into the memory of Tomcat. This means that a change in the directory might not affect your web application, which is good enough reason to not bother changing the on-disk files for a deployed web application.
Modify the web application, repackage it, and update the deployment. It's really the "right" way to go with Tomcat.
Give permission 777 to the webroot folder
sudo chmod -R 777 Webroot
After moving to the tomcat folder

Deploy a war to tomcat

In the past 10 years or so, I had the opportunity to deploy web applications into a tomcat countless times. I also wrote several scripts trying to do that automatically, but never
managed to completely automate it.
Here is the issue. I am trying to deploy a new war, with the same name as an existing war in the webapps of my tomcat.
Option 1: The naive approach - just copy the war and wait for it to update the exploded directory. This sometimes work. Many times - the exploded directory is not updated in a reasonable time.
Option 2: The through approach - stop the tomcat, delete all the wars and temporary files. copy the war and start the tomcat. This usually involves stopping the tomcat, waiting for a while - and then checking to see if the process is still alive and killing it.
Option 3: The manual approach - This might be surprising, but I found it to work many of the times - copy the war, wait for the exploded directory to be updated, and once it does -
restart the tomcat. if it doesn't - you can try to delete the temporary work files, and that sometimes help.
I also tried many options - with different order and subset of the actions - restart, stop, delete war, delete exploded, delete localhost context, delete localhost work directory, copy war, sleep, compare dates, ask the tomcat politely to reload, etc. Nothing seemed to just work.
It might be something that I am doing wrong, but I've heard the same experience from numerous people, so I'm here to get some advice - what say you? What is the best way to deploy a new war to a tomcat?
Thanks!
you can easily automate this in a shell script with curl
on tomcat 6:
curl --upload-file deployme.war "http://tomcat:s3cret#localhost:8088/manager/deploy?path=/deployme&update=true"
on tomcat 7
curl -T "deployme.war" "http://tomcat:s3cret#localhost:8080/manager/text/deploy?path=/deployme&update=true"
or via almost any porgramming language. I posted a java based solution here
I tend to go for Option 2. If there is a project I am working on in the ide especially with a debugger attached, I find things eventually start getting messed up. Might be chasing a red herring for an hour before I discover clearing everything away makes the problem go away. Then it is nice to have a script on the side that I can occasionally launch to clear everything up:
shutdown force with a 60s timeout
clear out the log, temp, work directories
clear out the webapp folder
copy in the new war file from the build location
explode the new war file
if necessary, run an awk script to customize machine specific values in the properties files (hence the previous explode)
startup with the CATALINA_PID environment variable set (to enable the shutdown force)
Normally things shutdown nicely. If not, then there is usually a background thread that was started up but missing a shutdown hook (say a memecached client) and needs to be hunted down. Normally, just dropping in the new war seems to work to. But if in a dev environment, a script for doing the full blown restart is nice.
Cargo - http://cargo.codehaus.org/ - can be used to remotely deploy WAR files to a number of web containers, Tomcat included.
See http://cargo.codehaus.org/Quick+start for examples in Java. Ant and Maven support is also available.
I upload the WAR to my home directory, cd to /usr/local/tomcat, then run the following commands:
bin/shutdown.sh
rm webapps/ROOT.war
rm -rf webapps/ROOT
cp ~/ROOT.war webapps
bin/startup.sh
Easy enough to automate, but I've been too lazy (or not lazy enough) to do that thus far.
I just use the Tomcat management tool to stop the process, remove it, and install the new WAR. Easy peasy.
See the section on "Deploying using the Client Deployer Package"
It's basically a ready made ant script to perform common tomcat deployment operations.
http://tomcat.apache.org/tomcat-7.0-doc/deployer-howto.html#Deploying_on_a_running_Tomcat_server

Categories