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
Related
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.
My team is working on a Java application that runs on Jboss WildFly, using Maven to resolve dependencies and Primefaces.
We're using Eclipse to build, deploy and run the server. Eclipse does most of the work, building the WAR file, deploying it to server and running it.
Now we need to create an script that performs all those steps because it has to run on remote server.
.
The steps would be something like this...
1 Run Maven:
$M2_HOME/bin/mvn clean install
2 Build project to a war file
3 Deploy war file into the WildFly deployment folder
$WILDFLY_HOME/bin/jboss-cli.sh --connect --command="deploy --force [PATH_TO_WAR]"
4 Start server
$WILDFLY_HOME/bin/standalone.sh
.
I can perform every step but once the server is running it don't seem to be any changes in the application. I think this is because the WAR file has to be built optimizing it for JBoss. Eclipse has a way to do this when exporting the project. I need to know how to do that from command.
EDIT:
The real problem is that Jboss is not updating the published project when i run it from bash script. I thought it was because i had to build it on a specific way. I was wrong. The build is fine, just running Maven the deploy is done. The thing is that even if i rebuild project and redeploy it, server doesn't seem to notice at all.
I've tried deleting tmp, lib and data folders from standalone folder, and nothing happens. I also deleted standalone/deployed sub files and folders and got the same result.
The only way i achieve the result i'm expecting is getting into Eclipse, go to Servers tab, right click on JBoss Wildfly and click on 'Clean...'. This options seems to clean cache, rebuild and re publish the application in a right way that i don't know. I didn't find any answers on google.
eclipse server clean option
Give a look on Eclipse war export: optimize for a specific server runtime.
Quoting from #Konstantin Komissarchik's answer :
Eclipse itself doesn't do anything with that option. What happens is
dependent on a particular server adapter. Many of the adapters don't
do anything with this option either, but they might in the future.
If a server adapter does support export optimization, it has the
option of displaying custom options beneath that pop-up list of
runtimes, so that's a good cue to use to see if something will
actually happen.
So taking in consideration that in your provided image there is no custom options below Wildfly 9 selection, I am pretty sure that this option does not perform any optimization at your exported war so you can totally omit it in your new build-deploy process.
How can i build the war file from command, knowing it will have to run on Wildfly?
We are also deploying applications for a long time on several versions of Widlfy with the same approach as you are planning to, without the optimization thing. I can ensure you that we have not faced any performance issue.
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
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
I use Eclipse Indigo (EE) to build applications in Java framework Vaadin,
using Tomcat 7.0 server. After changes in code I wont see result in a browser,
so I need to click option "Clean Tomcat Work Directory.." and wait until
Tomcat stop and start a server.
Otherwise, when I refresh app page, I don't see any changes.
Even when I restart server (and when eclipse automatically restart it when I save changes), without cleaning tomcat directory.
Option "Automatically publish when resources change" is enabled.
Is any faster way to do that? or can I automate that process?
Additionally to the answer of Kowser, it is possible do hot code changes when running tomcat in debug mode.
Otherwise you could investigate in JRebel
In your "Modules" tab of your Tomcat, you hace to clic on 'Edit' and uncheck the 'Auto reloading enables' option.
With that, several changes won't need a restart (as long as you start your server in debug mode).
If you setup your project to use ant for building and deploying, you can simply add Ant builder to your project Builders to run your ant build and deploy targets every time after you have saved a file. Then provided that tomcat is configured to support auto-deploy, this should achieve what you want, with two caveats:
If your project takes more than a few seconds to build, building after every save is not practical.
You may run out of memory for the tomcat instance if the same app is deployed to it repeatedly for a number of times. This can happen if tomcat is somehow unable to recover all the memory from undeployed resources.
It might be possible. But your setup is a bit different from what I use. I am just using tomcat+eclipse to do Servlet development using Velocity and Torque.
The following works for me where changes are visible in the browser as soon as I save in eclipse.
I assume that you have a project directory such as
apache-tomcat-7.0.11/webapps/$YOU_PROJECT/WEB-INF/classes/
Create a symbolic link with ln -s from your eclipse project directory and to the classes directory in WEB-INF.
Then configure eclipse to write all .class files to this directory. (Done by right clicking on the project in Eclipse and choosing Properties and then Java build path.
In your $tomcat/conf/context.xml config file first tag should be:
<Context allowLinking="true" reloadable="true">
Also add the following as a child to if it is not already there.
<WatchedResource>WEB-INF/web.xml</WatchedResource>
That is what I have done, but I am not sure it works with your EE tools.
ps: This solution assumes that you are using linux/unix. I don't know if it works with windows. The major problem is that eclipse can't write class files outside the project directory (Which is why that symlink is required).
btw: Tomcat may(Depending on class loader, used .jar files and other complicated details) leak a lot of memory when automatic reload is enabled so you may want to increase the allowed memory(Mostly permgen) to prevent out of memmory exceptions from tomcat.
I know this has been asked and answered very long ago. But use this info if it is helpful to anyone of you. I use Eclipse Kepler and configured Tomcat 7 server inside eclipse. I don't have to do any other configuration but to just uncheck Update context paths check box. That is all. Leave other setting as default.
In this way, changes to the resources files (xhtml pages, css files etc.) as well as the java source code files show up in the browser. Only for class files the web application would be redeployed (no server restart auto as well as manual required).
Location of Update context paths: Double click on the tomcat server under Server tab. Under Publishing tab you would find this Update context paths check box.
Absolutely no other change needs to be done for the auto publishing. This works both in normal and debug mode of tomcat.
Screen shot from my eclipse below:
No, there is no other way.
You will notice immediate changes only while updating a JSP/HTML/etc.... Classes will not be loaded/refreshed automatically. It will be contradictory to change a loaded/instantiated class when server is live, isn't it? At least it should not be possible.
It's better to perform Unit Test while developing something. It can help you to reduce the amount of annoying server restarts.