• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Jeanne Boyarsky
  • Devaka Cooray
  • Paul Clapham
Sheriffs:
  • Tim Cooke
  • Knute Snortum
  • Bear Bibeault
Saloon Keepers:
  • Ron McLeod
  • Tim Moores
  • Stephan van Hulst
  • Piet Souris
  • Ganesh Patekar
Bartenders:
  • Frits Walraven
  • Carey Brown
  • Tim Holloway

Externalized Tomcat config getting deleted

 
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi!

I recently looked into ways how to make externalized config work with Tomcat 8.
To release a new version to our production Tomcat, I usually just login via FTP, delete the old webapp/war and upload the new webapp/war. AutoDeploy does the rest. We currently don't use the Tomcat Manager.

Now, i can't have my config be a part of my war anymore. It needs to instead sit on the server in a persistent way (=externalized config). Tomcat seems to make this basically impossible for me. I am now using for my config. In the context, i have a JNDI environment entry that specifies where the workspace folder for this app (which includes config files etc.) is located. I can not hardcode this in my war, because the same war is used for development, production and staging, and the workspace location is different for all of those.
Example:

This external context XML works fine, until Tomcat deletes it. If see basically no way, without the manager, to redeploy my war without this file getting deleted. I can't restart the server (our admin does that) and i don't see why i should be forced to shut down the server just to prevent tomcat from deleting my configuration when i delete the old war. This Tomcat behaviour doesn't make any sense for me.

- Some people have suggested to make the config read-only. This doesn't work, because tomcat will not autoDeploy a new war if it cannot delete the config.
- Some people suggest not using autoDeploy. As explained, this would require me to restart tomcat on every deploy or use the manager.

So, what i would like to get more information on:
Do i HAVE to use the manager? Or am i just stupid?
And is the manager capable of deploying a new war without deleting my context?
And why is this stupid behaviour still a thing? I have seen tons of posts of people with this problem, here, on stackoverflow, on the mailing lists. It creates problems for everyone it seems, and i have not seen a proper solution that applies to my situation.
 
Bartender
Posts: 20842
125
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't recall ever having my Config file deleted by Tomcat. But then I usually don't delete the WAR, I overwrite it. And at that, I don't do it on a live server. From about Tomcat 4 on there were problems with Tomcat running out of PermGen space until PermGen finally became obsolete at about Java version 8 so after 2 or 3 hot-deploys Tomcat was usually pretty sick.

Then again, in the shops I've worked in, application developers weren't supposed to be able to modify the production servers at all. We'd submit a change request with instructions for the system operator who would pull the module from production archives and install as indicated. They liked me because I bundled my apps in OS installer packages, which have the advantage of being able to put files in locations outside the WAR (such as conf/Catalina/localhost) and do non-Java setup functions such as installing cron scripts.

Incidentally, it's very unsafe to use relative file path names in your configuration. JEE doesn't actually support the idea of a "current directory" and Tomcat might change directories without warning as it runs.

As far as deployment options go, there are several for Tomcat. There's the brute-force copy like you're doing, there's the administrative webapp, there's Tomcat's administrative web services and you may be able even to deploy via MBeans. And, of course, a build via Maven, Ant, or something similar can generally be set up to deploy as a target option.

If you're going to deploy "hot", I would recommend that you use one of the deployment interfaces instead of simply copying files. The deployment interfaces should be capable of keeping things together. Note, however that you'll probaby have to supply the Context information along with the WAR. The JSR that defines such features requires 2 "deployment descriptors". The Context element is the external server-dependent deployment descriptor. There's also an interna server-independent deployment descriptor. It's the WEB-INF/web.xml file.
 
Kath Tharsas
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Tomcat deleting context config on undeploy (and thus on redeploy because that includes undeploy) is documented, intended (sadly), and easily reproducable, see:

https://marc.info/?l=tomcat-user&w=2&r=1&s=tomcat+deletes+context.xml&q=b
https://serverfault.com/questions/192784/why-does-tomcat-like-deleting-my-context-xml-file
https://stackoverflow.com/questions/4032773/why-does-tomcat-replace-context-xml-on-redeploy
https://blog.alwold.com/2008/05/07/getting-tomcat-to-stop-deleting-your-context-xml-files/

Also, i do not use relative paths in production. The example in OP is from my "dev" config, were i use embedded tomcat and the base is always the project directory (and if it changes, it doesn't really matter. Its just dev). The point is that i needs to be adjustable, and it needs to be adjustable per war, but not defined in the war.

So all in all, what you are telling me, is that i should use the manager webapp or http interface that maven/grade plugins are using? Well it seems to be only option left, i just hope that this doesn't delete my stuff, too.
 
Tim Holloway
Bartender
Posts: 20842
125
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The Tomcat "working directory/current directory" is probably going to be the CATALINA_BASE directory, but it's not guaranteed, so it's better not to get into the habit even for testing.

Anyway, remember that I said that the Context XML file is the "server-dependent deployment descriptor? If you deploy a webapp, it's required as part of the deployment. That's how it was designed per the original JSR spec. It's not just a Tomcat thing.
 
Kath Tharsas
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well if that is how it was designed, it seems to be a very bad design. Like, what is the official way to supply external persistent config to your webapps, that works when you want to deploy the same webapp multiple times on one server? Don't tell me there is none and that i have to KNOW my the target environment at the time when i build my war file, because that makes no sense. That would mean i would have to build a war file for dev, one for staging, one for production, and additional ones for every kind of server that i would want to deploy my war on.

About the path: I could probably fiddle with my build so i can put my current project dir into the dev context instead of relative paths. Then i would not need relative paths at all.
 
Tim Holloway
Bartender
Posts: 20842
125
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Actually, they thought they were pretty clever. Every app deployment needs a certain amount of information to be provided to the webapp server. Some of that information - such as the welcome page location, security context, and error page information is portable and doesn't care whether the webapp is running on Tomcat or on Wildfly or WebSphere. So that goes in the server-independent deployment descriptor (web.xml).

But some is specific to the webapp server itself. Stuff like the database connection pool configuration (which can be shared between multiple webapps), the security realm configuration, and, of course the JNDI data. So it goes in the server-dependent deployment descriptor. Which is a Context file for Tomcat, but has a completely different name and format for WebSphere and for Wildfly. You can submit the exact same WAR for deployment under any of these servers and only the server-dependent deployment descriptor changes, not the WAR file. This is part of the "write once/run anywhere" characteristic of Java and JEE. Although Tomcat and jetty strain the concept, since they're not complete JEE implementations.

Tomcat's rules for deployment aren't entirely intuitive. Until recently, if you copied a new WAR file into the default Tomcat webapps directory, the default behavior was for Tomcat to explode that WAR file into its component files and directories and use them. BUT if you copied an updated WAR file into the webapps directory, that file wasn't exploded. Instead, Tomcat continued to use the old exploded WAR until you manually deleted it. That quirk was only fixed very recently. Before that, my standard deployments either turned off exploding or I deleted the exploded WAR, and the contents of the Tomcat work and temp directories every time I updated the WAR.

The Context file doesn't just define stuff statically. If you update it, Tomcat will re-deploy the WAR. If you delete the WAR, the reason that it deletes the Context is that the Context is defining a URL context path and a pointer to application classes and resources (the WAR) and if you delete the actual WAR, then the Context is broken. Tomcat doesn't have a concept of being incompletely deployed. If a Context is present, the app is considered deployed. If you undeploy the app, its deployment descriptor must therefore be removed.

 
Kath Tharsas
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, i noticed the behaviour you describe (i can't just overwrite the unexploded war) in Tomcat 7/8. I also have Tomcat 9 here for testing, ill try if what you describe works there, and see if that also deletes the external context.

Anyway, it seems to me that either the JSR's or Tomcats concept of the server-dependent deployment descriptor is lacking, because the concept of an "incomplete" context (or some kind of persistent config) is necessary in reality. And not allowing people to do this does not make sense imho as explained.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!