Greetings. I have a Java/Spring Boot project where I need to decrypt some sops encrypted .env files when the app starts up. The encrypted files are checked into the BitBucket repo, and I need to 1) use the Java class path to find the appropriate file, 2) decrypt it when the app starts using a fixed directory structure/naming convention, and 3) make sure that neither the encrypted or decrypted files are part of the Jar file that gets built in the project. The sops .env files reside in a directory directly below the project root, and the name and location of the directory are fixed. So it looks like this:
The conf name and location are not changeable, and for internal reasons, I need to be able to find the .env files using classpath:conf/dev.env. I have tried a million things in my build.gradle file like using processResources, sourceSets, and configurations to try to add the conf directory to the class path and retain the project structure. At one point, I had it working, but when I excluded the files from the jar, things broke again. I’ve tried so many different things, read the Gradle documentation, and changed the code to a point where I’m dizzy, and now I can’t for the life of me figure out what I did.
This is a runtime thing only. I’ll be using sops to decrypt the *.env files when the app starts up, and neither the encrypted or decrypted files should ever be included in the jar. I’m totally stuck on this, and much appreciate any help to get unblocked.
I’m looking for guidance here. Maybe I should have been more thorough in explaining the context. The Spring Boot app’s configuration files (application.yml and profile specific ones) contain environment variables that need to be set before the Spring Boot Application starts. In the case of cloud deployment of the app inside a Docker container, the environment variables are set through a DevOps process. The other scenario is that I’m looking for help to solve. As I stated, I need to search for the .env files from the class path, but I need to make sure the files don’t end up in the jar file that we deploy to the cloud.
The other scenario is local development, where we need to start/restart the app frequently, either via ./gradlew bootRun, or by using a Run Configuration in the IDE (right click -> Run <app name>.main(). All environment variables listed in the .env file(s) need to be set before Spring Boot starts, so I’ve created an ApplicationContextInitializer implementation that searches for the sops .env files, decrypts them, and parses the decrypted file into key/value pairs that are fed to a PropertySource that is added to the application context. That way, Spring Boot starts successfully.
I wasn’t sure if bootRun or the Run Configuration simply use what’s underneath the build directory after compiling, or if it packages up the fat jar and uses it. I’m not exactly sure what happens when I run the Spring Boot application from within the IDE. I’m not sure it uses the bootRun task. There isn’t much info in the automatically created Run Configuration in IntelliJ. Maybe I can create a task that removes them from the jar file, and then use that jar file in the Docker container in the deployment? Any suggestions are welcome. I’ve stated the problem, and I’m looking for a solution. Thanks.
What IntelliJ does when you click “Run” is even less a Gradle question, but more a question to JetBrains.
And it heavily depends on your configuration, for example whether you configured to use the “IntelliJ” runner or the default “Gradle” runner in the Gradle settings of IntelliJ. But even in the latter case, it will usually not use bootRun or the boot jar, unless the Spring Boot plugin or your build scripts take some measures to do that or similar.
So as a conclusion, you might achieve what you want by simply doing sourceSets { main { resources { srcDir("conf") } } } or similar and excluding the files from the boot jar task. But it is hard to give concrete advice without an MCVE.
I appreciate the response. But since I was trying to solve the problem using Gradle, and wasn’t successful initially, I posted the question here. It turns out that neither running the application from a Run Configuration in IntelliJ, or starting it with ./gradlew bootRun creates the fat jar. They both seem to use classes and resources from the build directory. I was able to bypass the issue with sops insisting on the files residing under conf (which is what I had trouble accomplishing in Gradle), so now everything works. I find that even after many years of using Gradle in various Java projects, I struggle with understanding all the mechanisms for configuration.