I am looking for a way to access static resources (e.g. video files) from my web app JEE.
In my local environment, I added an aliases attribute in the context of my webapp under the config of my tomcat server in Eclipse. This works verywell.
Doing that my context in Eclipse Tomcat server.xml is:
<Context path="/maWebApp" docBase="path/vers/ma/webApp" aliases="/video=/chemin/sur/mon/PC">
Now I want to do the same thing in my production server. But:
under this server (linux, tomcat7), the file etc/tomcat7/server.xml doesn't contains any "Context" for my webapp. I suppose that the context is created automatically during webApp deployment
if I add a "Context" for my application, in order to define the "aliase" attribute, my server tomcat doesn't restart anymore.
So my question is: where should I define the "aliase" attribute when I use Tomcat7 and when I deploy my application with .war generated from Eclipse.
Important note: I don't want to manage the aliases in the webapp, because the aliases change depending on the server (local dev or prod).
Thank you very much for any advise and best practise,
Have a good day!
Adrien
You should be able to add a context attribute to your server.xml.
https://tomcat.apache.org/tomcat-4.1-doc/config/context.html
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.core.AprLifecycleListener"
SSLEngine="on" /> <Listener
className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"
/> <Listener
className="org.apache.catalina.core.ThreadLocalLeakPreventionListener"
/>
<Context path="/maWebApp" docBase="path/vers/ma/webApp"
aliases="/video=/chemin/sur/mon/PC" />
</Server>
My tomcat is starting fine with this.
What error do you have when starting it with the "< Context .. />" attribute ?
Take a look over here: https://tomcat.apache.org/tomcat-7.0-doc/config/context.html#Defining_a_context
Defining Context elements in server.xml is discouraged. Instead put context.xml in
$CATALINA_BASE/conf/[enginename]/[hostname]/
enginename will most likely be Catalina, so e.g if your tomcat directory is /opt/tomcat7/ and your hostname is www.mysite.com then put the context in this directory:
/opt/tomcat7/conf/Catalina/www.mysite.com
And rename your context file maWebApp.xml
Update: Unless you need the static resources to be available to your app, and if only you need a virtual directory for visitors to access static resources you do not need the aliases attribute. Create a context in a file named video.xml in the same directory as above:
<Context docBase="/chemin/sur/mon/PC/" path="/video/"></Context>
Static resources will then be available at www.mysite.com/video
Related
My question is this - Say I have a war file called my-app-123.war. I want to deploy it on a Tomcat server (9.0.x), let it auto unpack.
The application would then be accessible by http://localhost:8080/my-app-123
Is there a way, without renaming the war file, to make the application accessible from http://localhost:8080/my-app?
I will preface this by saying I realize the easiest solution is to just name the war file. I'm curious if there is a way to do this in Tomcat configurations.
I did do this already (inside the host section of my server.xml file):
<Context path="/my-app" docBase="my-app-123"></Context>
But I read this online (https://tomcat.apache.org/tomcat-7.0-doc/config/context.html) in the path variable description:
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.
And I can access the app now at http://localhost:8080/my-app and http://localhost:8080/my-app-123, which isn't a real solution.
The following works for Tomcat deployments I have used - there are no double-deployment issues.
In the example I will use here, I have a simple "hello world" webapp in TomcatDemo-1.0-SNAPSHOT.war. It is deployed on Tomcat 9.0 in the standard location (webapps directory).
I want the application's context path to be /my-foo-app.
I use the following context entry in server.xml:
<Context path="/my-foo-app" docBase="TomcatDemo-1.0-SNAPSHOT.war"></Context>
I also use the following in server.xml:
<Host name="localhost"
appBase="webapps"
deployOnStartup="true"
deployIgnore="TomcatDemo-1.0-SNAPSHOT.war"
unpackWARs="true"
autoDeploy="false">
The important item here is deployIgnore. It is described here:
https://tomcat.apache.org/tomcat-9.0-doc/config/host.html#Automatic_Application_Deployment
When using automatic deployment, the docBase defined by an XML Context file should be outside of the appBase directory. If this is not the case, difficulties may be experienced deploying the web application or the application may be deployed twice. The deployIgnore attribute can be used to avoid this situation.
Alternatively, if you don't mind about automatic start-up deployments, you can set deployOnStartup="false" - in which case you don't need deployIgnore.
In these scenarios, the web app is available only here:
http://localhost:8080/my-foo-app/ <-- OK
Otherwise, as you note, with double-deployment the web app would also be available here (and you would see two exploded directories in webapps):
http://localhost:8080/TomcatDemo-1.0-SNAPSHOT/ <-- BAD!
Hope that helps.
Finally, it can get a little complicated, with all the various auto-deployment options. This page provides a set of summary tables and explanations:
https://tomcat.apache.org/tomcat-9.0-doc/config/automatic-deployment.html
I do have a Spring Boot Application which uses custom context.xml for the tomcat.
The context.xml contains property, defining the spring active profile
<Context>
<Environment name="spring.profiles.active" value="profileName" type="java.lang.String" override="false" />
</Context>
File location is the /src/main/webapps/META-INF
I was expecting that after the file is deployed to the tomcat, context xml will be automatically picked by tomcat and thrown to the conf/catalina/localhost/
As it turned out, the war was deployed, but the conf/catalina/localhost stayed empty.
After reading the docs i've found out that the server.xml has to be updated with the copyXML parameter as Host container.
The documentation says:
copyXML
Set to true if you want a context XML descriptor embedded inside the application (located at /META-INF/context.xml) to be copied to xmlBase when the application is deployed. On subsequent starts, the copied context XML descriptor will be used in preference to any context XML descriptor embedded inside the application even if the descriptor embedded inside the application is more recent. The flag's value defaults to false. Note if deployXML is false, this attribute will have no effect.
My Host looks like
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true" copyXML="true">
</Host>
After restarting the server and redeploying the app, the /conf/Catalina/localhost still stayed empty.
Do you have any suggestions, what actions have to be taken in order to use custom context.xml?
I've figured it out.
My build script did not copy the file correctly, the file name was not "context.xml" but "appName.xml" and tomcat didn't pick it up.
I've got Tomcat (7 or 8) with two virtual hosts with two clones of application should work.
Each application should have it's own configuration file. And it shouldn't be placed in *.war - only somewhere in server environment.
When I have a single application in Tomcat, I can place configuration file in
<context:property-placeholder location="file:${catalina.home}/conf/myapp.properties"/>
This is how Spring will find my configuration file due to applicationContext.xml.
But when I have two hosts, I should place my configuration files in different directories.
I've added Context attribute in Host in server.xml
<Context docBase="" path="XXX">
<Environment name="app.name" value="myapp1" type="java.lang.String" override="false"/>
</Context>
Here first host gets environment variable "app.name" like "myapp1". Second host gets this variable with "myapp2" value.
I've modified
But Tomcat falls with FileNotFoundException
Context initialization failed
org.springframework.beans.factory.BeanInitializationException: Could not load properties; nested exception is java.io.FileNotFoundException: ...\conf\${app.name}\myapp.properties (The system cannot find the path specified)
Why?
The environment property that you have configured is a JNDI lookup property.
I do not think it can be read as a normal system property as in the case of
"CATALINA_HOME".
Environment - Configure names and values for scalar environment entries that will be exposed to the web application through the JNDI InitialContext (equivalent to the inclusion of an <env-entry> element in the web application deployment descriptor).
I have defined property in Spring application.
#Configuration
public class WebappConfiguration {
#Value("${ext.storage.path}")
private String extDirectoryPath;
public String getExtDirectoryPath() {
return extDirectoryPath;
}
}
Default value for ext.storage.path property is defined in application.properties file.
application.properties
ext.storage.path=/home/user/ext/
When I deploy WAR to tomcat with VM options -Dext.storage.path=/var/webapp-data/, this value is loaded successfully. But I would like to load property values more smarter from context files for every environment.
So I deploy the WAR to ROOT of Tomcat, name of WAR file is ROOT.war and it is exploded to ROOT directory. I created context file on path {CATALINA_BASE}/Catalina/localhost/ROOT.xml with following content.
ROOT.xml
<Context
docBase="/opt/webapp-tomcat/webapps/ROOT.war"
path=""
reloadable="true">
<Parameter name="ext.storage.path" value="file:/var/webapp-data/" override="true"/>
</Context>
Unfortunately, the param is not loaded according to the way, it has default value from application.properties.
EDIT:
After a little investigation, I put the Parameter into main context.xml file of Tomcat and the value is overridden.
<Parameter name="ext.storage.path" value="file:/var/webapp-data/" override="true"/>
The best technique I know of is to put environment-specific stuff into Tomcat's conf/context.xml file.
<Environment name="myApp/extStoragePath" type="java.lang.String" value="/var/data/myapp"/>
This defines a JNDI variable that you lookup in your code with something like this:
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
String extStoragePath = (String) envCtx.lookup("myApp/extStoragePath");
You can also use this technique to load complex objects like database datasources etc. It has huge advantages:
The configuration is personal to the environment, not the application
You don't need to mess with Tomcat startup scripts
The same binary will run in DEV, UAT and PROD without modification. This much simplifies the build process.
Also, Spring provides a org.springframework.jndi.JndiObjectFactoryBean which can access JNDI from your spring configuration files.
I want to have a web app and then configure it to load static files from a direct path.
This is the webapp configuration:
<Context docBase="E:\webapp1" path="/" reloadable="true"/>
How do I setup the static resources.
I assume your Tomcat already can run at http://localhost:8080/
All you need to do then is to put your static resources in sub-folders of
E:\webapp1
like
E:\webapp1\jpg\1.jpg
E:\webapp1\css\style.css
E:\webapp1\html\abc.html
Change the path in Context to "" so this webapp can run as the default webapp i.e. the webapp name will not be part of the URL
and you can directly serve these as
http://localhost:8080/jpg/1.jpg
http://localhost:8080/css/style.css
http://localhost:8080/html/abc.html
Is this what you were looking for? This is my understanding of your question