0

How can I configure Tomcat 7 to allow a WAR file to specify its own context root, which is NOT based on the WAR file name? Example: I have A-1.0.0.war and B-1.0.0.war and I want to deploy both to the same Tomcat instance. When the deployment finishes, I want to point browser to localhost:8080/portal and see the contents in A-1.0.0.war, and I want to curl a rest request to localhost:8080/rest/v1/helloworld whose implementation comes from B-1.0.0.war.

I have scouted around and tried configuring different ways, but none of these are producing my desired scenario above. Also, I find the Tomcat documentation a bit too sparse to understand fully. I've read:

  1. Tomcat 7 html manager howto
  2. Tomcat host config
  3. deploying-war-file-to-tomcat-with-a-different-path

After digesting those, in %CATALINA_HOME%/conf/server.xml I have this single Host entry:

<Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true"
            deployXML="true" copyXML="true" >
    <Context path="/portal" docBase="/www/" reloadable="true" swallowOutput="true">
        <WatchedResource>WEB-INF/web.xml</WatchedResource>
        <Logger className="org.apache.catalina.logger.FileLogger" prefix="www-sample-com-log." suffix=".txt" timestamp="true"/>
    </Context>
    <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
            prefix="localhost_access_log" suffix=".txt"
            pattern="%h %l %u %t &quot;%r&quot; %s %b" />
</Host>

This is the full content of A.war/META-INF/context.xml from one of the WAR files:

<?xml version="1.0" encoding="UTF-8"?>
<Context path="/portal" docBase="ROOT/portal" />

When I deploy to Tomcat via the Admin console, I am using the "WAR file to deploy" buttons, but I am not specifying any of the fields under the "Deploy directory or WAR file located on server" (because I want these to come from the WAR itself, not make someone specify it). When I open the webapps directory, I see this listing. I would expect to see, instead of A-1.0.0/ directory, portal/:

A-1.0.0/
B-1.0.0/
docs/
examples/
host-manager/
manager/
ROOT/
sample/
A-1.0.0.war
B-1.0.0.war
sample.war

In case it helps, here's some backstory to my scenario. My objective is to move an application bundled in a single .jar into two .war files. Currently, it's a maven project that produces a single jar as its build artifact containing both a Spring MVC and a JSP application. My client is starting up the application on command line using java. Where I want to get to is standing up a Tomcat 7 install on our dev server, which someone can deploy a WAR file through Tomcat's admin console. I also want to put a version number in the file name of the WAR so that it's clear to the people handling the WAR what they are deploying. On every build/release cycle, I want them to un-deploy the old war and deploy the new war. As a side note - this is the first time I'm attempting to deploy an application as a war, and I may have missed some best practice on doing this, so do kindly correct me if this is not a good way.

Community
  • 1
  • 1

1 Answers1

0

I, personally, don't use the manager app for installing the apps, I configure Tomcat manually, so I can't say how to do it with manager app, but here's how you can control app context path independent of the war file name.

First, it is NOT recommended to put <Context> inside server.xml (see Tomcat documentation). You should create a context XML file in the .../conf/Catalina/localhost folder instead.

So, here are the steps:

  1. Copy your war file anywhere on the system, but outside the Tomcat folders, e.g. /mywars/A-1.0.0.war.

  2. Create file .../conf/Catalina/localhost/portal.xml:

    <Context docBase="/mywars/A-1.0.0.war" reloadable="true" swallowOutput="true">
        <Logger className="org.apache.catalina.logger.FileLogger" prefix="www-sample-com-log." suffix=".txt" timestamp="true"/>
    </Context>
    

    Note that it doesn't have a path attribute. The context path is determined from the file name, i.e. /portal.

  3. If needed, restart Tomcat.

    I usually shut down Tomcat before making changes, so multiple changes don't cause multiple reloads.

The META-INF/context.xml is not used when doing it like this, even if present.

If your webapp uses Servlet Init Parameters, which you configure using <Parameter> elements inside the <Context> element, you can even install the same webapp (war file) multiple times in a single Tomcat instance, under different context paths, each configured differently, by simply creating multiple XML files in the .../conf/Catalina/localhost folder.

Andreas
  • 154,647
  • 11
  • 152
  • 247
  • Thanks for the answer. This revealed something I totally missed, which is that Tomcat will look for an xml file in its `conf/Catalina/localhost/` folder. Now I understand what the `conf///` means in the documentation. Will try this when I get back to work tomorrow. But I have a further question - if next month I want to deploy A-2.0.0.war over the old 1.0.0 version, do I have to add another `` (or change the existing one) to match the name of the new WAR file? Now I'm thinking that putting version number in the WAR file name is a bad idea... –  Mar 17 '17 at 04:13
  • Unless you want to keep both versions running, using different context paths, just update the `docBase` of the existing xml file. – Andreas Mar 17 '17 at 12:23