0

I have an application with the name cat_tiger.war that gets deployed as localhost:8080/cat_tiger but I want to change the context path to localhost:8080/cat/lion/ instead. I've added the META-INF/context.xml file as

<?xml version="1.0" encoding="UTF-8"?> <Context copyXML="true" docBase="cat_tiger" path="/cat/lion"/>

and the server.xml file to be

<Host name="localhost" appBase="webapps" copyXML="true" deployXML="true" unpackWARs="true" autoDeploy="true">

but it still deploys as localhost:8080/cat_tiger/

Any ideas as to what else needs to be changed?

EDIT: [1] Tomcat 8.5.3

[2] 04-Sep-2018 13:50:41.830 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDescriptor Deployment of configuration descriptor [/opt/tomcat/conf/Catalina/localhost/cat_tiger.xml] has finished in [2,750] ms ... ... 04-Sep-2018 13:50:39.070 WARNING [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDescriptor A docBase [/opt/tomcat/webapps/cat_tiger] inside the host appBase has been specified, and will be ignored

[3] I'm deploying through Netbeans but will have to be deployed in a Docker container eventually.

GrizzLee
  • 3
  • 1
  • 1
  • 4
  • This works for me. Can you update your post (as opposed to commenting) with the following information: [1] The version of Tomcat you are using. [2] Post what you see in Tomcat's catalina log when you deploy. I see this: _"Deploying configuration descriptor [C:\apache-tomcat-8.5.20\conf\Catalina\localhost\cat#lion.xml]"_ Do you see something similar? [3] Give full details on how are you deploying your app to Tomcat: manually or through an IDE, are you stopping Tomcat, what file(s) get copied, etc... – skomisa Sep 04 '18 at 16:38
  • I just noticed that the Tomcat version is in your title. Can you add a **tomcat8.5** tag? – skomisa Sep 04 '18 at 17:00

1 Answers1

1

I don't understand why you are having problems, but I've created the web project using NetBeans 8.2 (File > New Project... > Java Web > Web Application), and successfully changed the context, so perhaps if I give details of my project you can identify where there's a crucial difference.

1 cat_tiger\web\META-INF\context.xml

My file looks identical to yours:

<?xml version="1.0" encoding="UTF-8"?>
<Context copyXML="true" docBase="cat_tiger" path="/cat/lion"/>

[2] Run output

Select the project node, right click and select Run from the popup menu to run on Tomcat 8.5:

ant -f D:\\NB82\\cat_tiger -Dnb.internal.action.name=run -Ddirectory.deployment.supported=true -DforceRedeploy=false -Dnb.wait.for.caches=true -Dbrowser.context=D:\\NB82\\cat_tiger -Duser.properties.file=C:\\Users\\johndoe\\AppData\\Roaming\\NetBeans\\8.2\\build.properties run
init:
deps-module-jar:
deps-ear-jar:
deps-jar:
library-inclusion-in-archive:
library-inclusion-in-manifest:
compile:
compile-jsps:
In-place deployment at D:\NB82\cat_tiger\build\web
Deployment is in progress...
deploy?config=file%3A%2FC%3A%2FUsers%2Fjohndoe%2FAppData%2FLocal%2FTemp%2Fcontext7953615149857268018.xml&path=/cat/lion
OK - Deployed application at context path [/cat/lion]
Start is in progress...
start?path=/cat/lion
OK - Started application at context path [/cat/lion]
run-deploy:
Browsing: http://localhost:8080/cat/lion
run-display-browser:
run:
BUILD SUCCESSFUL (total time: 0 seconds)

Actually, you probably don't need to run the application to see the problem; just select Deploy instead of Run from the popup menu. This is the output I get from Deploy:

ant -f D:\\NB82\\cat_tiger -Dnb.internal.action.name=redeploy -Ddirectory.deployment.supported=true -DforceRedeploy=true -Dnb.wait.for.caches=true -Dbrowser.context=D:\\NB82\\cat_tiger -Duser.properties.file=C:\\Users\\johndoe\\AppData\\Roaming\\NetBeans\\8.2\\build.properties run-deploy
init:
deps-module-jar:
deps-ear-jar:
deps-jar:
library-inclusion-in-archive:
library-inclusion-in-manifest:
compile:
compile-jsps:
Undeploying ...
undeploy?path=/cat_tiger
OK - Undeployed application at context path [/cat_tiger]
In-place deployment at D:\NB82\cat_tiger\build\web
Deployment is in progress...
deploy?config=file%3A%2FC%3A%2FUsers%2Fjohndoe%2FAppData%2FLocal%2FTemp%2Fcontext5063723197082921373.xml&path=/cat/lion
OK - Deployed application at context path [/cat/lion]
Start is in progress...
start?path=/cat/lion
OK - Started application at context path [/cat/lion]
run-deploy:
BUILD SUCCESSFUL (total time: 0 seconds)

[3] Tomcat log

Here are the deployment details in the Tomcat log, where you can see that my deployment shows the context correctly, whereas yours does not:

05-Sep-2018 23:09:09.321 INFO [http-nio-8080-exec-6] org.apache.catalina.startup.HostConfig.deployDescriptor Deploying configuration descriptor [C:\apache-tomcat-8.5.20\conf\Catalina\localhost\cat#lion.xml]
05-Sep-2018 23:09:09.334 INFO [http-nio-8080-exec-6] org.apache.catalina.startup.HostConfig.deployDescriptor Deployment of configuration descriptor [C:\apache-tomcat-8.5.20\conf\Catalina\localhost\cat#lion.xml] has finished in [13] ms
05-Sep-2018 23:09:09.338 INFO [http-nio-8080-exec-5] org.apache.catalina.util.LifecycleBase.start The start() method was called on component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/cat/lion]] after start() had already been called. The second call will be ignored.

[4] C:\apache-tomcat-8.5.20\conf\Catalina\localhost\cat#lion.xml

This is the file Tomcat created when deploying the application:

<?xml version="1.0" encoding="UTF-8"?>
<Context copyXML="true" docBase="D:\NB82\cat_tiger\build\web" path="/cat/lion"/>

Note that docBase contains an absolute path.

[5] server.xml

Here's the entire content. I'm using Tomcat 8.5. Note that the <host> element is slightly different to yours, but when I added copyXML="true" deployXML="true" to the <host> element (so it looked like yours) everything continued to work fine:

<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">
    <Listener className="org.apache.catalina.startup.VersionLoggerListener"/>
    <Listener SSLEngine="on" className="org.apache.catalina.core.AprLifecycleListener"/>
    <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"/>
    <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>
    <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener"/>
    <GlobalNamingResources>
        <Resource auth="Container" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" name="UserDatabase" pathname="conf/tomcat-users.xml" type="org.apache.catalina.UserDatabase"/>
    </GlobalNamingResources>
    <Service name="Catalina">
        <Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" relaxedQueryChars="[]|{}^+\`&quot;&lt;&gt;"/>
        <Connector port="8009" protocol="AJP/1.3" redirectPort="8443"/>
        <Engine defaultHost="localhost" name="Catalina">
            <Realm className="org.apache.catalina.realm.LockOutRealm">
                <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
            </Realm>
            <Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">
                <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" pattern="%h %l %u %t &quot;%r&quot; %s %b" prefix="localhost_access_log" suffix=".txt"/>
                <Context docBase="C:\apache-tomcat-8.5.20\wtpwebapps\PlusServlet" path="/PlusServlet" reloadable="true" source="org.eclipse.jst.jee.server:PlusServlet"/>
            </Host>
        </Engine>
    </Service>
</Server>

Updated 9/6/2018:

Ignore the answer given above! Even though it happened to work for my configuration, the approach is explicitly disallowed in the Tomcat documentation.

Specifically, path should not be specified within the <Context> of a context.xml file placed within the application's META-INF directory. From the path description in the Common Attributes section of the Tomcat 8.5 documentation for the Context Container:

This attribute must only be used when statically defining a Context in server.xml. In all other circumstances, the path will be inferred from the filenames used for either the .xml context file or the docBase.

Even when statically defining a Context in server.xml, this attribute must not be set unless either the docBase is not located under the Host's appBase or both deployOnStartup and autoDeploy are false. If this rule is not followed, double deployment is likely to result.

skomisa
  • 16,436
  • 7
  • 61
  • 102
  • Thanks for the detailed answer, unfortunately I'm still unable to get it to work with the Application's context.xml file. I resorted to manually adding the Context element within server.xml for now. :D – GrizzLee Sep 06 '18 at 19:33
  • @GrizzLee OK, I'm stumped over why it's not working for you. But you are aware that updating server.xml directly is discouraged, right? That's fine to get up and running, but it's still worth getting this working within NetBeans, and it definitely works for me. One more simple change you might try is to put the absolute path in **docBase** in your context.xml. – skomisa Sep 06 '18 at 20:38
  • 1
    @GrizzLee I just read the [relevant Tomcat 8.5 documentation](https://tomcat.apache.org/tomcat-8.5-doc/config/context.html), and I have updated my answer accordingly. What we were trying to do was invalid (even though it worked for me), and putting the `` in **server.xml** is appropriate for what you are doing. – skomisa Sep 06 '18 at 21:26
  • sorry for the late response, yea thats what i ended up doing ultimately. Its confusing how the Document says its an option to have a context.xml in each application but later says we can only change the path in the server.xml... Thanks for the help though! – GrizzLee Sep 19 '18 at 17:10