Externalizing Tomcat Webapp Config from .War File

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:

  1. file:./config/
  2. file:./
  3. classpath:/config/
  4. 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 .

  1. Use an Environmental variable
  2. Use a System Property
  3. 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 and deployXML of the <Host> is not false) the entries in META-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



Leave a reply



Submit