Note Well
Please see the edit section of the question below, as further investigation has rendered the majority of this question redundant.
Similar to this question, I can't seem to pass environment variables to my app on startup while using VSCode. The problem is, I have no idea what (or if an) extension is causing the issue.
I have VSCode 1.38.1 with the following extensions;
- Language support for Java 0.48.0
- Java Extension Pack 0.8.0
- Maven for Java 0.18.2
- Spring Boot Dashboard 0.1.6
- Spring Boot Tools 1.10.0
- and several others that I don't feel are the culprits.
What I want to do is use maven profiles to conditionally bring in dependencies, and use environment variables to trigger that. In my pom.xml, I have;
<profiles>
<profile>
<id>dev-mysql</id>
<activation>
<!-- activate if system properties 'env=dev-mysql' passed in on launch.json env property from VSCode -->
<!-- Following does not work :( -->
<property>
<name>env</name>
<value>dev-mysql</value>
</property>
<!-- Obtain the following info by running - mvn enforcer:display-info -->
<!-- <os>
<name>windows 7</name>
<family>windows</family>
<arch>amd64</arch>
<version>6.1</version>
</os> -->
</activation>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.17</version>
</dependency>
</dependencies>
</profile>
</profiles>
I try and pass that env
value in by setting it in launch.json via something like;
{
"type": "java",
"name": "Debug (Launch)-MyServiceApplication<my-service>",
"request": "launch",
"mainClass": "myapp.MyServiceApplication",
"projectName": "my-service",
"vmArgs": "-Dspring.profiles.active=local-mysql",
"env": {
"env": "dev-mysql"
}
}
I've also tried adding in maven customEnv through settings.json as the Maven for Java extension seems to suggest that "...These environment variable values will be added to the terminal session before Maven is first executed". My settings.json file looks like;
{
"java.configuration.updateBuildConfiguration": "automatic",
"files.exclude": {
"**/.classpath": true,
"**/.project": true,
"**/.settings": true,
"**/.factorypath": true
},
"maven.terminal.customEnv": [
{
"environmentVariable": "env",
"value": "dev-mysql"
}
]
}
I execute my application by hitting F5, which to my understanding executes what is shown in the launch.json snippet above. I don't quite understand how maven is invoked here. However, no matter what, it doesn't seem to ever find the environment variable and therefore include the profile specific mysql dependency. Even if I use Spring Boot Dashboard, I get the same result; the mysql dependency isn't recognised so I end up with Cannot load driver class: com.mysql.cj.jdbc.Driver
If I comment out the <property>
element of my pom.xml and uncomment the <os>
element, then it does bring in the profile specific mysql dependency. So I am guessing it uses the pom file correctly.
Does anyone have any clue how to set environment variables so that they'll be recognised with this configuation? Also, any further information as to what is actually executed when I hit F5
with this setup (is it maven, is it Java), it would be much appreciated.
Edit:
Some further investigation has shown that I was "...confusing Environment Variables with System Properties" comment by Wouter Lievens.
This post also suggests that "you cannot activate profiles based on system properties defined after the build plan has started execution", which may well be what happens when I just hit F5 to execute my application. This also links to some further information in this answer which clarifies that if won't work as "...profiles are the first thing evaluated before anything else to determine the effective POM.".
My workaround is to not use F5, but instead, when I have set the spring-profiles-active=local-mysql
, I have to use the Maven for Java Explorer to execute a custom target of spring-boot:run -Pdev-mysql
So my last questions are;
Given the extensions I have added to VSCode combined with the above launch.json, what is actually executed when I hit F5
with this setup - is it Maven, Java or something else? If it is Java, how does the pom.xml come into play? If it is Java, is there a way of adjusting the launch.json to use mvn
instead?
Is there a way to up the verbosity of the logging when I hit F5 to get a better understanding of what is actually being executed?