Environment Variables For Datasource

Adding onto a question discussed prior at this post 2 years ago:

The instructions work well with Gradle and Jmix 2.3.1 (My current version) for everything except datasource parameters. I’m probably doing something wrong, but when I set the following in my application.properties:

main.datasource.url = ${DB_CONNECTION_STRING:jdbc:postgresql://localhost:5432/development}
main.datasource.username = ${DB_USER:postgres}
main.datasource.password = ${DB_PASSWORD:postgres}

And then set the following Environment Variables in my Run/Debug Configuration for IntelliJIdea:

DB_CONNECTION_STRING=jdbc:postgresql://xxx.xxx.xxxx/projectDB?stringtype=unspecified;
DB_PASSWORD=password;
DB_USER=developmentUser

I am unable to get the project to start. From my understanding I should just need to declare the variable and then pass it in, and this does work for several other areas such as setting up my ldaps connection and passwords for my keystore files, it does not work for specifically setting the Database parameters.

I’m probably misapplying something, so any help would be appreciated.

Thank you,
Oran

Jmix 2.3.1 using Gradle

Hi

try to use every part of connection string as variable like follows:

main.datasource.url=jdbc:${DB_VENDOR}://${DB_HOST}:${DB_PORT}/${DB_NAME}?${DB_PARAMS}

and DB_PARAMS can be specified as:

stringtype=unspecified&otherparam=value&…

1 Like

I’ll try it in a few hours (waiting in election lines here). I can say from my prior testing though. That even when I declared a static url for the data source I still had failure to connect with the variables on username and password.

I can confirm that the variable syntax was working as when I did ${DB_PASSWORD:long complex password} it did work as long as the default entered was correct. But it didn’t pull the password from context of my build variables in Gradle.

Thank you,
Oran

according to the link you provided default values must have correct values when you run application locally without containers.
The problem with connection can be due to varous kinds of problems: the syntax for gradle can differs, database setup can differs, there can be other tricky things. For instance, when I tried to test the example I provided above it haven’t running until I replaced back DB_VENDOR with previously hardcoded value. In some configurations I had “password not matched” problems until spaces were not removed from parameters assign.
So, It can be more reliable and easy way for you to use spring profiles and keep hardcoded values for local development properties file and variables substitution with docker compose/helm envs in production. You can find tips for profiles setup for Jmix project from the following link: Well-done Java Containers: Simplifying Web App Development | by Jmix | Sep, 2024 | Medium

1 Like

Thank you everyone for the help. It’s pretty well described above so I’m just going to leave my additional findings and rephrase a few things for the eventual future readers in my much lower skill level:

  1. Defaults are not fully required, but there was a bug that caused them to be required. As a precaution I’m including them in all circumstances to make it easier on myself, and as a precaution as this appears to be a syntax bug that could reappear.
  2. After a phone call with a more experienced developer, they explained that my issues are very common because the order of operations for initializing Spring, I’ll try to reiterate best I can. Basically the build order wont allow DB url, username, and passwords to be interpreted correctly if they are defined as variables. They can be placed as variables for an implementation like Docker, but this has limited applicability in development so the spring profiles setup is the best overall way to handle this type of problem.
  3. Generally this limitation will only apply to things like Database connections (again, complex order of operations and the DB pretty much comes first). So it doesn’t effect things like ldap properties which is why I was so confused. Additionally the username and password properties can be passed but will only use the default property provided, so it would be safe for example to place your development db and password in if this is allready distributed to the development team and then use the environment variables in the docker deployment to set password and username for the active deployment user and password. The limitation will occur on setting the url though, which has to be statically defined leading us back to the spring profiles setup.

Its pretty complicated (spend nearly an hour getting a walk through from and this is the short version), so if you’re stuck like me either set the variables with working defaults for the dev environment, or figure out spring profiles. Neither of them are great but they are significantly better than keeping production credentials in source control.

1 Like