3

I have some data in my gradle.properties file:

appVersion=1.4.31
appGroup=com.business
appName=projectName

I want to be able to access them in a .java project. I am attempting to access the variable like this:

@Value("${appVersion}")
private int version; 

However, when I try to run the application from the main class, I get the following error:

Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'appVersion' in value "${appVersion}"

Which shows that it can't find the correct variable.

Attempts at solving the problem

Adding a @propertySource Annotation

I have tried adding this to the main class @PropertySource(value = "file:build.gradle", ignoreResourceNotFound = true) which was unsuccessful.

Making changes in build.gradle

I attempted the following, taken from this StackOverflow answer:

processResources {
    filesMatching('application.properties'){
        expand(gradle.properties)
    }
}

Which was also unsuccessful.

This answer below

I did what was said in this answer (I had to add an application.properties file) and I got this error message:

Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Circular placeholder reference 'appVersion' in property definitions

I thought that it might be getting mixed up with using the same names (appVersion = appVersion), so I changed the application.properties line to

version=${appVersion}

And then in my .java file, I changed the line to:

@Value("${version}")
private String version;

And got the error:

Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'appVersion' in value "${appVersion}"
Community
  • 1
  • 1
Haych
  • 932
  • 13
  • 36
  • how do you launch your application : from an IDE (eclipse/IDEA )? or from gradle task (run or bootRun) ? – M.Ricciuti Oct 18 '18 at 14:57
  • [This](https://docs.spring.io/spring-boot/docs/current/reference/html/howto-properties-and-configuration.html) might help. – Andrew S Oct 18 '18 at 15:09
  • I launch the project from IDEA. – Haych Oct 18 '18 at 15:09
  • `application.properties` file should have already existed. Well, unless you didn't use a boot initializer I suppose. Did you place it in `src/main/resources`? – FGreg Oct 19 '18 at 15:54
  • Try running the gradle process resources task before launching your app from Idea – FGreg Oct 19 '18 at 16:04
  • Yes, when hovering over appVersion in IntelliJ, the following appears: `Cannot resolve configuration property 'appVersion'...`. So, maybe something else is wrong. `build.gradle` and `gradle.propeties` are in the root of the project. `application.properties` is in `src.man.resources`. The java class is in `src.main.java.com.business`. – Haych Oct 22 '18 at 07:51
  • Did you try running `processResources` before running it in Idea? Alternatively, you can try running `bootRun` and it should work. – FGreg Oct 22 '18 at 16:20

1 Answers1

2

This should work:

processResources {
    filesMatching('application.properties'){
        expand(gradle.properties)
    }
}

But it seems like you forgot the other part. This just tells Gradle to process your application.properties file and replace any placeholders it finds. You need to also put a placeholder into your application.properties:

version=${appVersion}

Then your value annotation should work (but it should be a String not an int)

@Value("${version}")
private String version; 

Finally, since you are launching via IDEA, you may need to make sure that gradle:processResources runs before your application starts so that Gradle has a chance to replace the placeholder you put in application.properties. You should be able to utilize the "Before Launch Options" section in your run configuration to have IDEA run the processResources Gradle Task after the build task. This should cause the placeholder to be properly replaced every time you run the application.


Also, just to help with the understanding. Gradle is the build system for the application, it's not part of the application itself. Once the project is built, everything related to Gradle is irrelevant. This is why you can't just do @Value("${appVersion}") and have it work. The application/Spring doesn't know anything about the tool that's being used to build it (and it shouldn't). So you need to somehow, at build time, inject the Gradle project version into the application if you want access to it. There are a number of ways of accomplishing this but the resource processing method above is a pretty common approach.

FGreg
  • 14,110
  • 10
  • 68
  • 110
  • I gave that a go and still have a problem (I added an explanation to my question). Thank you for the explanation about Gradle. I found it useful. – Haych Oct 19 '18 at 08:32