Regarding application.properties file and environment variable
Asked Answered
E

8

56

Java successfully recognizes the path in my application.properties file when I have the path configured as below:

pathToInputFile=/kcs/data/incoming/ready/
pathToInputFileProcess=/kcs/data/incoming/work/

If I try using an environment variable, the Java program doesn't recognize the path.

(the environmental variable TOM_DATA is set as /kcs.)

pathToInputFile=${TOM_DATA}/data/incoming/ready/
pathToInputFileProcess=${TOM_DATA}/data/incoming/work/

Can I use an environment variable inside application.properties file?

Eddy answered 15/2, 2010 at 3:29 Comment(0)
P
39

You can put environment variables in your properties file, but Java will not automatically recognise them as environment variables and therefore will not resolve them.

In order to do this you will have to parse the values and resolve any environment variables you find.

You can get at environment variables from Java using various methods. For example: Map<String, String> env = System.getenv();

There's a basic tutorial here: http://java.sun.com/docs/books/tutorial/essential/environment/env.html

Hope that's of some help.

Partheniaparthenocarpy answered 15/2, 2010 at 3:37 Comment(0)
C
23

Tom Duckering's answer is correct. Java doesn't handle this for you.

Here's some code utilizing regular expressions that I wrote to handle environment variable substitution:

/*
 * Returns input string with environment variable references expanded, e.g. $SOME_VAR or ${SOME_VAR}
 */
private String resolveEnvVars(String input)
{
    if (null == input)
    {
        return null;
    }
    // match ${ENV_VAR_NAME} or $ENV_VAR_NAME
    Pattern p = Pattern.compile("\\$\\{(\\w+)\\}|\\$(\\w+)");
    Matcher m = p.matcher(input); // get a matcher object
    StringBuffer sb = new StringBuffer();
    while(m.find()){
        String envVarName = null == m.group(1) ? m.group(2) : m.group(1);
        String envVarValue = System.getenv(envVarName);
        m.appendReplacement(sb, null == envVarValue ? "" : envVarValue);
    }
    m.appendTail(sb);
    return sb.toString();
}
Camenae answered 15/3, 2012 at 17:52 Comment(2)
Then, how do you connect it to application.properties ?Burberry
FYI - this code fails (java.lang.IndexOutOfBoundsException: No group 3) for environment values that themselves contain dollar signs.Invercargill
P
17

The Apache Commons project has expanded handling of properties files that lets you use environment variables (in particular, see the Variable Interpolation section). Then you should be able to get what you want using:

pathToInputFile=${env:TOM_DATA}/data/incoming/ready/
Pifer answered 15/3, 2018 at 14:13 Comment(0)
A
16

That is right. Java does not handle substituting the value of the environment variables. Also Java might not recognise variables like $EXT_DIR. While using such variables you might encounter FileNotFoundException. But Java will recognise the variables that are defined with -D in catalina.sh. What I mean by this, is suppose you have such a definition in catalina.sh

CATALINA_OPTS="-Dweb.external.dir="$EXT_DIR"

In your properties file use ${web.external.dir} instead of using *$EXT_DIR*. And while accessing this property in your code you could do it this way:

String webExtDir = System.getProperty("web.external.dir");

Hope this will help a lot of people so they won't have to pick bits and pieces from everywhere which takes really long to resolve an issue at hand.

Arsonist answered 13/8, 2013 at 6:23 Comment(0)
C
9

Have a look at Commons configuration

Or alternatively use relative paths in your properties file, and load the base directory via command line as a system property. That way the property files remain independent of where the application is actually deployed.

Coenobite answered 15/2, 2010 at 4:21 Comment(0)
S
1

You can do:

your.key=${YOUR_ENV_VAR:#{false}}

Which will pick up the value of $YOUR_ENV_VAR or false in this case

Softball answered 29/6, 2023 at 11:58 Comment(0)
O
0

Apache Tomcat has an optional script for setting environment variables. In the documentation, it says "all environment variables can be specified in the "setenv" script" (.bat for Windows and .sh for Linux).

Section 3.4 in https://tomcat.apache.org/tomcat-9.0-doc/RUNNING.txt

Since it is a script and not a static configuration, the properties file can be created from it. This patterned works for me for an environment configured S3 connection, but here it is re-written for your example, along with the bonus of how to set the properties file's location:

cat > "${CATALINA_HOME}/conf/application.properties" <<EOF
pathToInputFile=${TOM_DATA}/data/incoming/ready/
pathToInputFileProcess=${TOM_DATA}/data/incoming/work/
EOF
CATALINA_OPTS="${CATALINA_OPTS} -DTOM_DATA=${TOM_DATA}"
CATALINA_OPTS="${CATALINA_OPTS} -Dapplication.properties.location=${CATALINA_HOME}/conf/application.properties"

export CATALINA_OPTS

You may already be using this file if you configure runtime things like memory constraints, headless mode, or which garbage collect to use.

NOTE: the documentation has caveats about when setenv would not be called and some exceptions as to a few environment variable that cannot configured in it.

Occurrence answered 9/10, 2020 at 14:22 Comment(0)
A
0

Here I leave a class for using as complement for the solution of @tim-lewis

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public final class Configuration {
    public static String get(String envVarName) throws IOException {
        try (FileInputStream in = new FileInputStream("src/main/resources/application.properties")) {
            Properties properties = new Properties();
            properties.load(in);
            return resolveEnvVars(properties.getProperty(envVarName));
        }
    }

    private static String resolveEnvVars(String input) {
        if (null == input) throw new IllegalArgumentException();
        Pattern p = Pattern.compile("\\$\\{(\\w+)\\}|\\$(\\w+)");
        Matcher m = p.matcher(input);

        StringBuilder sb = new StringBuilder();
        while (m.find()) {
            var envVarName = null == m.group(1) ? m.group(2) : m.group(1);
            var envVarValue = System.getenv(envVarName);
            m.appendReplacement(sb, null == envVarValue ? "" : envVarValue);
        }
        m.appendTail(sb);
        return sb.toString();
    }
}
Amphimixis answered 18/8, 2023 at 4:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.