understanding property file in a java spring application

I saw the following settings.properties file in a java spring application :

include = environments/${env}_paypal_config.properties
include = environments/${env}.properties
include = mail.properties
include = notification.properties


Open in new window

under environment folder i saw there are property file for all the environments. somwhow using this property file
the line env=${sys:KUBER_ENV} it is able to read the environment of the system and then choose the correct properties file corresponding to them at run time.

But i couldnt find how its doing it ?

I saw some related java files which might be doing this :
package olympus.kuber;

import com.google.inject.AbstractModule;
import com.google.inject.name.Names;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

public class SettingsModule extends AbstractModule {
    private static Logger log = LoggerFactory.getLogger(SettingsModule.class);

    protected final void configure() {
        PropertiesService propertiesService = new PropertiesService();
        Names.bindProperties(binder(), propertiesService.properties);

    private void logProperties(Properties properties) {
        StringBuilder builder = new StringBuilder("Binding properties: \n");
        for (Map.Entry entry : properties.entrySet()) {
            builder.append(String.format("  %s=%s\n", entry.getKey(), entry.getValue()));

    public static class PropertiesService {
        private final Properties properties;

        public PropertiesService() {
            properties = loadConfig("settings");

        private static Properties loadConfig(String propertiesFileName) {
            try {
                Properties properties = new Properties();
                Configuration config = new PropertiesConfiguration(propertiesFileName + ".properties");
                Iterator<String> keys = config.getKeys();
                while (keys.hasNext()) {
                    String key = keys.next();
                    properties.put(key, config.getString(key));

                return properties;
            } catch (ConfigurationException e) {
                throw new RuntimeException(e);

        public Properties properties() {
            return properties;

        public String getProperty(String key) {
            return properties.getProperty(key);

        public String getProperty(String key, String defaultValue) {
            String property = properties.getProperty(key);
            if (property == null || property.isEmpty()) {
                return defaultValue;
            return property;


Open in new window

package olympus.kuber;

import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import olympus.common.Country;
import olympus.kuber.core.accounting.Money;
import olympus.kuber.model.User;
import olympus.kuber.services.CurrencyService;

import javax.annotation.Nullable;
import java.util.*;

import static olympus.kuber.util.EmailFactory.Email;
import static olympus.kuber.util.EmailFactory.EmailName;
import static olympus.kuber.util.NotificationFactory.Notification;
import static olympus.kuber.util.NotificationFactory.NotificationName;

public class AppPropertiesService {
    private final SettingsModule.PropertiesService propertiesService;
    private final CurrencyService currencyService;

    public AppPropertiesService(SettingsModule.PropertiesService propertiesService, CurrencyService currencyService) {
        this.propertiesService = propertiesService;
        this.currencyService = currencyService;

    public String getPayPwMerchantId(User user) {
        return getProperty(user.getAppDomain().concat(".payment.pay.pw.merchant-id"));

    public String getHmacGeneratorSecret(User user) {
        return getProperty(user.getAppDomain().concat(".payment.pay.pw.hmac.generator.secret"));

    public String getAppStoreValidateBundleId(User user) {
        return getProperty(user.getAppDomain().concat(".apple-store.validate.bundle-id"));

    public Money getNewUserPromoCreditAmount(User user, String countryCode) {
        Money creditAmount;
        String specificCountryCreditAmount;
        if (countryCode != null && (specificCountryCreditAmount = getProperty(user.getAppDomain().concat("." +
                countryCode.toLowerCase() +
                ".new.user" + ".promo.credit.amount"))) != null) {
            creditAmount = convertInDefaultCurrency(specificCountryCreditAmount);
        } else {
            String anyCountryCreditAmount = getProperty(user.getAppDomain().concat(".default" + ".new.user.promo" +
                    ".credit" +
            creditAmount = convertInDefaultCurrency(anyCountryCreditAmount);
        return creditAmount;

    private Money convertInDefaultCurrency(String amountAndCurrency) {
        String[] tokens = amountAndCurrency.split(",");
        Currency currency = Currency.getInstance(tokens[0].toUpperCase());
        String amount = tokens[1];
        return currencyService.convertTo(new Money(amount), currency, Kuber.DEFAULT_CURRENCY);

    public Double getLowBalanceThreshold(User user, Country country) {
        String lowBalanceAmountStr = getProperty(user.getAppDomain().concat(".").concat(country.getISOAlpha2Code()
        if (lowBalanceAmountStr == null) {
            lowBalanceAmountStr = getProperty(user.getAppDomain().concat(".low.balance.threshold"));
        return Double.parseDouble(lowBalanceAmountStr);

    public Boolean getEmailEnabled(User user, Email email) {
        String key = user.getAppDomain().concat(".").concat(email.getMailName()).concat(".email");
        return Boolean.parseBoolean(getProperty(key, Boolean.TRUE.toString()));

    public Boolean getNotificationEnabled(User user, Notification notification) {
        String key = user.getAppDomain().concat(".").concat(notification.getMessageId()).concat(".notification");
        return Boolean.parseBoolean(getProperty(key, Boolean.TRUE.toString()));

    public String getMailSenderName(User user, EmailName emailName) {
        return getProperty(user.getAppDomain().concat(".").concat(emailName.toString()).concat(".mail.sender.name"));

    public String getMailSenderEmail(User user, EmailName emailName) {
        return getProperty(user.getAppDomain().concat(".").concat(emailName.toString()).concat(".mail.sender.email"));

    public Boolean getIsNotificationDevicePlatformSpecific(NotificationName notificationName) {
        String key = notificationName.toString().concat(".notification.device.platform.specific");
        return Boolean.parseBoolean(getProperty(key, Boolean.TRUE.toString()));

    public String getNotificationXmlString(NotificationName notificationName) {
        return getProperty(notificationName.toString().concat(".notification.xml.string"));

    public String getMailTemplateSuffix(User user, EmailName emailName, Country country) {
        return getProperty(user.getAppDomain().concat(".").concat(emailName.toString()).concat(".").concat(country

    public String getNotificationNameSuffix(User user, NotificationName notificationName, Country country) {
        return getProperty(user.getAppDomain().concat(".").concat(notificationName.toString()).concat(".").concat

    public String getProperty(String key) {
        return propertiesService.getProperty(key);

    public String getProperty(String key, String defaultValue) {
        return propertiesService.getProperty(key, defaultValue);

    public Set<String> getPayPwBlacklistedReasons() {
        String blacklistedReasonsStr = getProperty("payment.pay.pw.blacklisted.reasons");
        Set<String> blacklistedReasons = new HashSet<>();
        return blacklistedReasons;

    public Double getMaxReferralCreditAmountFor(User user) {
        return Double.parseDouble(getProperty(user.getAppDomain().concat(".max.referral-credit.amount")));

    public List<Currency> getCurrencyUpdateIgnoreList() {
        String property = getProperty("ignore.currency.update.list");
        if ("".equals(property) || property == null) {
            return new ArrayList<>();
        } else {
            List<String> currencies = Arrays.asList(property.split(","));
            return Lists.transform(currencies, new Function<String, Currency>() {
                public Currency apply(String input) {
                    return Currency.getInstance(input);

    public boolean isSaveCardAllowed(Country country) {
        return Boolean.parseBoolean(getProperty("payment.save.card.allowed." + country.getISOAlpha2Code(), Boolean

    public boolean isAutoTopupFeatureEnabledFor(Country country) {
        return Boolean.parseBoolean(getProperty("feature.autotopup.enabled." + country.getISOAlpha2Code(), Boolean

    public boolean isLocaleBlockedForPayment(String locale) {
        return Arrays.asList(getProperty("payment.init.blocked.locales").split(",")).contains(locale);

Open in new window

There is probably these two java files which are doing the magic.
Also what are the lines include= doing ?

Rohit BajajAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

mccarlIT Business Systems Analyst / Software DeveloperCommented:
Looks like they are using this... https://commons.apache.org/proper/commons-configuration/  and possibly some of their own code to support this.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Rohit BajajAuthor Commented:
But how are the lines :
include = environments/${env}_paypal_config.properties
include = environments/${env}.properties
include = mail.properties
include = notification.properties

Open in new window

getting handled ?
Rohit BajajAuthor Commented:
also what are the pros n cons of using this type of approach
1) where the build itself is environment dependent. and i dont have to care which environment files to pick
2) build is independent of environment variable and so at runtime the code automatically reads the correct property files.   this is what is happening in the top post
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.