Externalizing Tomcat webapp config from .war file
Your tomcat/conf/Catalina/<host>
can contain context descriptors that let you configure lots of things including defining "environment entries", which are accessible from Java via JNDI. There are lots of ways to go about using it. Personally, I set an environment entry which is the file system path to my properties file. My app is built to check for this entry, and if it doesn't exist, look for the file on the classpath instead. That way, in dev, we have the dev properties right there on the classpath, but when we build and deploy, we point it to an external file.
There's good documentation for configuring a context on the Tomcat website. See the Defining a Context section on details of how to create the file and where to put it.
As an example, if your host is named myHost
and your app is a war file named myApp.war
in the webapps
directory, then you could create tomcat/conf/Catalina/myHost/myApp.xml
with this content:
<Context>
<Environment name="configurationPath" value="/home/tomcat/myApp.properties" type="java.lang.String"/>
</Context>
Then from your code, you'd do a JNDI lookup on java:comp/env/configurationPath
(95% certainty here) to get that string value.
separate application.properties from .war for tomcat container
You can run your application with spring.config.location
property set to the path to your properties file using the file:
protocol:
# will look for /etc/myapp/application.properties
-Dspring.config.location=file:/etc/myapp/
# will look for /etc/myapp/custom.properties
-Dspring.config.location=file:/etc/myapp/custom.properties
Default config locations that are always searched:
- file:./config/
- file:./
- classpath:/config/
- classpath:/
There is a lot more info in the Externalized Configuration section of the documentation for Spring Boot.
How to read a properties file outside my webapp context in Tomcat
There are multiple approaches .
- Use an Environmental variable
- Use a System Property
- Set it as a Application Context Param in Web.xml
Heres a sample ,that showsOption 1 and Option 2
try {
//Use Any Environmental Variable , here i have used CATALINA_HOME
String propertyHome = System.getenv("CATALINA_HOME");
if(null == propertyHome){
//This is a system property that is passed
// using the -D option in the Tomcat startup script
propertyHome = System.getProperty("PROPERTY_HOME");
}
String filePath= propertyHome+"/properties/myapp.properties";
Properties property = new Properties();
property.load(SystemTest.class.getClassLoader().getResourceAsStream(filePath));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Tomcat: specify different properties for different webapps
Edit: Looking at your code (particularly configuration.clj) it appears that you are using system environment variables (which are shared among all web applications). You should use environment entries instead and retrieve them through a call to InitialContext.lookup("java:comp/env/FOO")
instead of System.getenv("FOO")
.
Technically every application has its own <Context>
, which is composed by (cf. Tomcat documentation):
- the values from
$CATALINA_BASE/conf/context.xml
, - the values from
$CATALINA_BASE/conf/<enginename>/<host>/context.xml.default
- the values from
$CATALINA_BASE/conf/<enginename>/<host>/<path>.xml
or (if it is missing anddeployXML
of the<Host>
is not false) the entries inMETA-INF/context.xml
of your application.
Each more specific configuration file can overwrite the attributes of the more general configuration files, while the nested components are added up. Therefore you should probably define:
- the environment entries specific to each application in
$CATALINA_BASE/conf/<enginename>/<host>/<path>.xml
, - the environment entries common to all applications in
$CATALINA_BASE/conf/context.xml
.
Remark: Usually <enginename>
is Catalina
, while <host>
is localhost
.
If you are using the same WAR file you can just place it outside of the document base (let's say /usr/share/my.war
) and create a bunch of <path>.xml
files in $CATALINA_BASE/conf/<enginename>/<host>
:
<Context docBase="/usr/share/my.war">
<!--
environment entries
-->
</Context>
The path under which they will be deployed will be inferred from the name of the XML.
loading of property file outside of war file in spring boot
You can try setting properties via XML and or Java configuration and @PropertySource.
@Configuration
@PropertySource("classpath:foo.properties")
public class PropertiesWithJavaConfig {
//...
}
source :- https://www.baeldung.com/properties-with-spring
Elegant ways to separate configuration from WAR in Tomcat
If I have a specific set of beans that I'd like to configure, and this configuration must be separated from the WAR file, I usually do the following:
In applicationContext.xml:
<!-- here you have a configurer based on a *.properties file -->
<bean id="configurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="file://${configDir}/configuration.properties"/>
<property name="ignoreResourceNotFound" value="false" />
<property name="ignoreUnresolvablePlaceholders" value="false" />
<property name="searchSystemEnvironment" value="false" />
</bean>
<!-- this is how you can use configuration properties -->
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="${smtp.host}"/>
</bean>
In configuration.properties:
smtp.host=smtp.your-isp.com
You also need to start Tomcat with -DconfigDir=/path/to/configuration/directory
Read common external property file in Java Webapp and java normal app
You can add a <context>
to tomcat/conf/server.xml (in this example, linux path):
<Context docBase="/home/yourusername/tomcat/assests" path="/assets" />
If you are using Windows:
<Context docBase="C:\path\to\myapp\assets" path="/assets" />
And then you can access it like any other resource within your webapp (e.g.: /assets/myappConfig.property).
If you are using JDBC for example, you could store the connection properties in a Singleton and request it from there, and that class could take care of change checks on that file.
Related Topics
How to Display Number to Two Decimal Places in Bash Function
How to Use Variables in Bash Sed Command, Specific Example
Best Practices When Running Node.Js With Port 80 (Ubuntu/Linode)
Looping Through the Content of a File in Bash
How to Prevent a Background Process from Being Stopped After Closing Ssh Client in Linux
What Does Set -E Mean in a Bash Script
Is There a Way For Non-Root Processes to Bind to "Privileged" Ports on Linux
What Registers Are Preserved Through a Linux X86-64 Function Call
Can You Run Gui Applications in a Linux Docker Container
How to Use Sudo to Redirect Output to a Location I Don't Have Permission to Write To
What Does "&" At the End of a Linux Command Mean
How to Merge Two Files Using Awk
How to Symlink a File in Linux
Performing Http Requests With Curl (Using Proxy)
How to Fix 'Sudo: No Tty Present and No Askpass Program Specified' Error
Given Two Directory Trees, How to Find Out Which Files Differ by Content