Define Servlet Context in WAR-File - java

How can I tell e.g. Tomcat to use a specific context path when given my WAR-File?
Example:
I have a war file created by maven build and the resulting name of the file is rather long.
So I do not want the tomcat manager application to use the filename of the war as the context.
Supplying a context.xml in META-INF did not produce the desired results
I also found this in the documentation for the path attribute of Context:
The value of this field must not be set except when statically defining a Context in server.xml, as it will be inferred from the filenames used for either the .xml context file or the docBase.
So it does not seem to be the right way to tell the application-server what the path for my WAR should be.
Any more hints?

There are two important points in the the documentation of the Context Container:
In individual files (with a ".xml" extension) in the $CATALINA_BASE/conf/[enginename]/[hostname]/ directory. The name of the file (less the .xml extension) will be used as the context path. Multi-level context paths may be defined using #, e.g. foo#bar.xml for a context path of /foo/bar. The default web application may be defined by using a file called ROOT.xml.
Only if a context file does not exist for the application in the $CATALINA_BASE/conf/[enginename]/[hostname]/, in an individual file at /META-INF/context.xml inside the application files. If the web application is packaged as a WAR then /META-INF/context.xml will be copied to $CATALINA_BASE/conf/[enginename]/[hostname]/ and renamed to match the application's context path. Once this file exists, it will not be replaced if a new WAR with a newer /META-INF/context.xml is placed in the host's appBase.
So, when you bundle a META-INF/context.xml, the file gets renamed to the name of the WAR and this name becomes the context path, regardless of any path defined in the Context element.
I see thus two options here:
Either set the name of the generated war to a shorter name (I suggest using <finalName> over <warName> which is deprecated AFAIK):
<project>
...
<build>
<finalName>mycontext</finalName>
...
</build>
...
</project>
Or use the maven-tomcat-plugin for the deployment and set the context path in the plugin configuration:
<project>
...
<build>
...
<plugins>
...
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tomcat-maven-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<configuration>
<path>/mycontext</path>
</configuration>
</plugin>
...
</plugins>
...
</build>
...
</project>

I found an easy solution to keep war file name and choose the context-path.
You just have to deploy your war outside of the Host's appBase and to create a link inside the appBase directory.
Ex. :
ln -sf ${CATALINA_HOME}/wars/myapp-0.0.8-SNAPSHOT.war ${CATALINA_HOME}/webapps/myapp.war
Ektor

You can set the path attribute of the <Context> element of your META-INF/context.xml.
Alternatively, you can configure maven to create the war artifact with a custom name:
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.0</version>
<configuration>
<warName>yourCustomWarName</warName>
</configuration>
</plugin>
........
</plugins>
</build>

In your project there is a folder META-INF, in that folder there is a context.xml file.
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/myproject" />

Related

How to set JBoss Wildfly context root with XML-less Spring web application?

Having a Spring application with Maven where all the configuration is done in Java (all configuration previously stored in web.xml is now in annotated #Configuration files or in WebAppInitializer that extends AbstractAnnotationConfigDispatcherServletInitializer), how can I set the context root for my application in JBoss Wildfly? The app has no web.xml, nor jboss-web.xml .
When the app used XML configuration the context root was set in jboss-web.xml like this:
<jboss-web>
<context-root>mywebcontextroot</context-root>
</jboss-web>
JBoss wildfly defaults the context root to the name of the war file. Setting the name of the war file to the desired value (web context root) in Maven solves the issue:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
<warName>mywebcontextroot</warName>
</configuration>
</plugin>
More detailed answer by #Nikhil Bide can be found here.

Spring boot : Add static web page (Angular) in a custom folder outside classpath folder (classes)

How would I place the static contents in a WAR Archive.
I have tried placing them inside the classes folder and works fine, but to make the cleaner I am asked to put it outside the WEB-INF, in a custom folder. I was able to do that and make it work by setting the welcome page in web.xml
<welcome-page>'./app/index.html'</welcome-page>
But the issue is that I don't want 'app' to appear in my URL, when the pages were kept inside classes/static the index.html appeared in root(localhost:8080), but putting the pages in custom folder URL changed to - localhost:8080/app
Is there any way to keep the pages in a custom folder and still get the index page and its dependencies from root URL.
Either you place your resources under "src/main/webapp", these will be copied to the root of your WAR. If you need more flexibility, maybe the maven-war-plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<webResources>
<resource>
<directory>${project.basedir}/mycustomdir</directory>
<targetPath>somewhere</targetPath>
</resource>
</webResources>
</configuration>
</plugin>

Why aren't my jsp files displaying when deployed by Tomcat in war file?

ANOTHER EDIT: I just re-read it and the question is very ambiguous: the problem is Tomcat won't show me the views. They ARE in a folder under Tomcat's webapps directory.
EDIT: BOUNTY available. The code is here
I have a spring boot web app that runs fine under eclipse tomcat server when I navigate to http://localhost:8080/swa-boot/.
When I try to deploy it as a war under Tomcat 9.0.14 externally I get:
Message /swa-boot/WEB-INF/views/home.jsp
Description The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.
home.jsp is in the views folder.
I have tried adding to pom the resource:
<directory>${basedir}/src/main/webapp</directory>
<includes>
<include>**/**</include>
</includes>
And the dependency
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
I have also tried removing the ‘provided’ scope.
I have in application.properties:
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp
I have changed any <a tags in the jsp pages to be of the form:
TakeMeToTheController.
I have added the views folder to the Deployment Assembly.
The folders under tomcat web apps look like:
And under the tomcat server web apps directory:
Any ideas?
EDIT: Deployment Assemblies:
Looks like the generated war does not pick up contents of your src/main/webapp folder.
Change line no. 72 in your pom.xml as below
<warSourceDirectory>src/main/webapp</warSourceDirectory>
This way the generated war will have contents of src/main/webapp. Test the new war and see. Check this question to see how to correctly specify warSourceDirectory.
Edit
In adition you need to remove the web.xml file from src/main/webapp/WEB-INF folder. Either delete it or move it outside src folder.
Next run an mvn clean install and deploy target/swa-boot.war to tomcat.
A working copy is here - https://storage.googleapis.com/schoon/swa-boot.zip
Looks to me like your config is incorrect:
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
The file referenced - servlet-context.xml - does not exist under WEB-INF but under src/main/resources which means at runtime it will be under the root of the classpath and should therefore be referenced as below:
<param-value>classpath:/servlet-context.xml</param-value>
You can also remove this from your POM and delete the WebContent folder completely as the root of your web app, being a Maven project, is now webapp and not WebContent.
<warSourceDirectory>WebContent</warSourceDirectory>
You have to make a couple of changes.
First change is to remove resources configuration. This is packing everything under /src/main/webapp into WEB-INF/classes with same source structure.
<resources>
<resource>
<directory>${basedir}/src/main/webapp</directory>
<includes>
<include>**/**</include>
</includes>
</resource>
<resource>
<directory>src/main/webapp</directory>
</resource>
<resource>
<directory>${basedir}/src/main/resources</directory>
<includes>
<include>**/**</include>
</includes>
</resource>
</resources>
Next change is to remove
<warSourceDirectory>WebContent</warSourceDirectory> from the war plugin. This is preventing from processing the web resources.
<plugin>
<artifactId>maven-war-plugin</artifactId>
</plugin>
Next step is to run maven clean install and You should end up the below structure inside your war and spring would be able to locate your jsps correctly.
WEB-INF
classes
org
META-INF
static
templates
lib
spring
tags
views
resources
Update - Finally was able to checkout your project. To run spring boot application as a traditional war inside a container you need to make few more changes.
Web.xml change to locate the app servlet correctly and remove the SpringBoot ServletIntializer and remove the import resources annotation.
That's all the changes.
Changes available in github - https://github.com/saagar2000/springboot-traditional

How can I add jar file to project instead of adding to Tomcat lib folder?

Via this github project, I store Tomcat sessions in Redis:
https://github.com/chexagon/redis-session-manager
And in src/webapp/META-INF/context.xml file I added new commands:
<Manager className="com.crimsonhexagon.rsm.redisson.SingleServerSessionManager"
endpoint="redis://localhost:6379"
sessionKeyPrefix="_ib_"
saveOnChange="false"
forceSaveAfterRequest="false"
dirtyOnMutation="false"
ignorePattern=".*\\.(ico|png|gif|jpg|jpeg|swf|css|js)$"
maxSessionAttributeSize="-1"
maxSessionSize="-1"
allowOversizedSessions="false"
connectionPoolSize="100"
database="0"
timeout="60000"
pingTimeout="1000"
retryAttempts="20"
retryInterval="1000"
/>
If jar file is in Tomcat lib folder, then everything is fine. But in production if I add jar to lib folder it causes errors. Is there any other way for solving this problem? Can I change context.xml in such way that when I will deploy project, manager className will be able found relevant class?
P.S. There are some examples but I couldn't catch the sense:
Adding external resources to class-path in Tomcat 8
If someone can enlighten me, I will be grateful.
Thanks in advance
I could find solving. There is a plugin in maven for deploying war file. With this plugin it is possible to add files to war file. For example, I created folder which is named redis and add into it jar file. Then I added plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<webResources>
<resource>
<!-- this is relative to the pom.xml directory -->
<directory>redis</directory>
<targetPath>WEB-INF/lib</targetPath>
</resource>
</webResources>
</configuration>
</plugin>

Java webapp : How to map/direct webapp to your BASE URL/IP?

Typically when you create a webapp you will access your webapp when you hit the url
<your_IP>/<Project_name>/
Example:
127.0.0.1/MyWebapp/
Question: How do you configure your webapp to run from base URL
Example
127.0.0.1/
Moreover, when the browser navigates to your IP (and not your IP + name of your webapp) you can hit your webpage
Question: Is this a configuration file that needs to be edited in your Application web server?
It depends on your container, but generally you will name your file ROOT.war or specify the context explicitly.
For example, since you've tagged this question with jetty, here is the plugin in my pom.xml for embedded testing using mvn jetty:run. Notice the contextPath element.
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.25</version>
<configuration>
<contextPath>/</contextPath>
<scanIntervalSeconds>5</scanIntervalSeconds>
<connectors>
<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
<port>8081</port>
<maxIdleTime>60000</maxIdleTime>
</connector>
</connectors>
</configuration>
</plugin>
When I deploy to Tomcat, I simply name my file ROOT.war and drop it into the webapps folder. Note that you'll need to move or remove the existing ROOT content from webapps first.
Doing this will allow you to access your application at http[s]://<host>[:<port>]/ with no extra context needed.
Assuming you're using maven to build your application, you can avoid manually re-naming your WAR by specifying the finalName in your pom.xml.
<build>
<finalName>ROOT</finalName>
[...]
</build>

Categories

Resources