6

How to read system environment variables in a properties file. I am using MyBatis maven plugin for database migrations. MyBatis use properties file basing on the environment. I am trying to read environment variable inside properties file like:

development.properties

username=${env.username}
password=${env.password}

Error: FATAL: role "${env.username}" does not exist

I stored username and password in a ".profile" file on a mac. What's the correct way to read those variables?

lch
  • 4,569
  • 13
  • 42
  • 75
  • https://stackoverflow.com/questions/10463077/how-to-refer-environment-variable-in-pom-xml – OldProgrammer Feb 08 '18 at 20:49
  • it did not work. maven is not replacing those variables. If I specify ${var}, it is taking "${var}" as value without replacing var – lch Feb 08 '18 at 23:29
  • The best way to handle the username and password with maven is [encrypting](https://maven.apache.org/guides/mini/guide-encryption.html) it. But [MyBatis Migrations Maven plugin](http://www.mybatis.org/migrations-maven-plugin/) does not support the the `serverid` mechanism to use username and password. Thus at this moment, your solution to keep the username and password in your local environment make sense and you use those with maven resource filtering in your properties file. @Christian 's solution should work for you! – Rishikesh Darandale Feb 15 '18 at 13:37

3 Answers3

15

You should probably first filter the properties file with the maven resources plugin. Afterwards myBatis plugin should work as intended.

See following gist for a short example to the resources plugin.

development.properties

# place in src/main/resources
username=${env.username}
password=${env.password}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.stackoverflow</groupId>
    <artifactId>question-48693420</artifactId>
    <version>1.0-SNAPSHOT</version>

    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>
</project>

Command line:

username=user1 password=pass1 mvn resources:resources && cat target/classes/development.properties

Console log:

(...)
[INFO] --- maven-resources-plugin:2.3:resources (default-cli) @ question-48693420 ---
(...)
[INFO] Copying 1 resource
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
(...)

username=user1
password=pass1
kriegaex
  • 63,017
  • 15
  • 111
  • 202
Christian
  • 3,503
  • 1
  • 26
  • 47
  • Sorry, but `project.build.resourceDirectory` is either cyclic or not resolvable. See https://stackoverflow.com/questions/9216557/referencing-resources-directory-from-project-object-model-variables – Christian Feb 15 '18 at 14:49
  • As you probably know, Christian, answers consisting of not much more than an external link are not particularly welcome on SO. Because I am not busy right now, I did what I normally would have asked you to do: I pasted the gist content into your answer so as to avoid you getting downvotes for an otherwise helpful answer. Please remember to do it yourself next time. Thank you. – kriegaex Feb 18 '18 at 02:51
  • @kriegaex Thank you – Christian Feb 19 '18 at 15:04
  • 1
    In case of **Spring Boot** use `@` as the delimeter. `$` won't work. – rustyx Sep 21 '18 at 15:20
2

That seems to be discusses in mybatis/migrations issue 114:

Migrations or migrations-maven-plugin itself does not provide filtering (i.e. variable substitution).
But Maven's resource plugin does. See Maven Filtering.

You can use the filtering along with env/system/even settings.xml values using pom.xml properties.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
-1

If you want get and load the property value in class. You can use below code :

String userName = DatabasePropertyHandler.resolveEnvVars(${env.username});

public static 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();
      }
Alin
  • 314
  • 1
  • 3
  • 9