Deploying war file to Tomcat with a different path

72,954

Solution 1

Tomcat will always extract the contents of a war file, to a folder of the same name (when it's configured to deploy wars - as default etc.).

You can extract it to a folder name of your choice. So if you unzip the contents of foo.war to a folder called bar/ manually, instead of just dropping the war into the web apps folder, it'll still load the web application.

However, this is totally unnecessary as you can specify the URL pattern of the application without messing with the folder / war file name at all by overriding the context root element for your application:

This is often set in the Tomcat server.xml - but that practice is fairly widely discouraged. Instead, I'd suggest you use context.xml in the META-INF folder of your web application / war file:

<Context path="/bar" .../>

When the application is deployed, the context.xml should be copied to /conf/Catalina/localhost but renamed to foo.xml

Note that conext roots must be unique and there are some additional considerations if you're using the autoDeploy or deployOnStartup operations (Source http://tomcat.apache.org/tomcat-7.0-doc/config/context.html).


Other options include:

  • Clean the web apps folder each deployment and drop your new foo-1.1.0 war in.
  • Include the version number in a flat file. foo/version1
  • Or simply include the version in a config / XML file.

You could also use Ant (or an equivalent tool) to automate your deployments (and perform any of the above).

Solution 2

There is an important point to emphasize about the path attribute of the context fragment definition. To cite the documentation on the topic:

When autoDeploy or deployOnStartup operations are performed by a Host, the name and context path of the web application are derived from the name(s) of the file(s) that define(s) the web application.

deployOnStartup is the default behavior of Tomcat hosts.

To follow the documentation, this has a very important consequence:

the context path may not be defined in a META-INF/context.xml

According to the ways of defining a Tomcat context, this lets only two solutions:

  • In individual files (with a ".xml" extension) in the $CATALINA_BASE/conf/[enginename]/[hostname]/ directory
  • Inside a Host element in the main conf/server.xml, which is a discouraged solution in a production environment as it requires restarting the server

Another solution takes advantage of the unpackWARs attribute.

In my point of view, for these reasons, the general and easy way to implement a subtle path in a production environment is taking advantage of the naming of war files (what could include versions management and be a solution to your problem). A single sharp (e.g. test#path.war) in the war file names implies a segment in the context path (e.g. /test/path). A double sharp introduces the version number (e.g. test#path##112.war). This works whether or not unpacking war files, hot deployment or not, is deployment agnostic (manager or file system) and manages multiples versions of a same archive.

But if there is the need to have a path distinct from the archive name, it seems the only solution is the descriptor in the /conf/[enginename]/[hostname]/ directory or the server.xml file. For these, you need an access to the server filesystem.

The relevant solution is highly related to the way Tomcat is configured and managed in the everyday.

Solution 3

If you just want to include a version info in your war file name, you can name it like: my-app##1.2.3.war. It gets unpacked to the directory my-app##1.2.3 but the context will be just my-app (i.e. http://host/my-app/).

Works at least with Tomcat 7.0.55

Share:
72,954

Related videos on Youtube

z12345
Author by

z12345

Updated on June 29, 2020

Comments

  • z12345
    z12345 almost 4 years

    If I deploy a war file to Tomcat, called for example foo-bar-1.1.2.war, how can I deploy it so that it is extracted to webapps/bar and its URL root is /bar/...?

    My intention here is to keep the war file in the webapps server with its version information so that I know which version is installed but have it overwrite a previous version of the app.

    I could deploy the war file using PSI Probe. This would allow me to specify a target context for the web app. However, it means that I would lose any version information in the war file name.

  • z12345
    z12345 about 12 years
    I thought there might be a way to deploy a war file without manually extracting its contents so that you could keep its version information but deploy it over an existing context.
  • Michael
    Michael about 12 years
    What's your app version got to do with the name of the war file / application folder?
  • z12345
    z12345 about 12 years
    I've edited the question in the hope that it will be clearer.
  • z12345
    z12345 about 12 years
    The problem is knowing which version of the app is currently installed and reducing the length of its name in a URL. You're right that I didn't make the requirements clear enough in the first place.
  • z12345
    z12345 about 12 years
    I'm going to accept this as the canonical answer because you mentioned including the version number in a flat file, which is the approach I'm taking.
  • TechSpellBound
    TechSpellBound almost 11 years
    AFAIK, servlet-mapping "/bar" will not map to <ip-address>/bar but to <ip-address>/<web-app-name>/bar (as far as auto deployment of tomcat is true). Point if I am wrong.
  • Michael
    Michael almost 11 years
    @TechSpellBound Sorry, you are correct. I've updated my answer.
  • Max
    Max over 6 years
    To deploy this by URL one should url-encode the sharps # to %23, eg. http://localhost:8080/manager/text/deploy?path=/myapp%23%23v‌​1.2.2.24%20(myName)&‌​war=file:/D:/RELEASE‌​.Tomcat.wars/myapp%2‌​3%23v1.2.2.24%20(myN‌​ame).war , otherwise deploy will fail by a file-not-found exception.
  • Dave X
    Dave X over 6 years
    I'm not sure if I'm doing it right yet, but this seems like the right way. It makes the 'version' column in the tomcat manager app make more sense. I'm trying copy/move apps to webaps like 'cp /tmp/tds-5.0.0-alpha3.war thredds##500a3.war` to keep version numbers separate for THREDDS.