29

I am trying to obtain the version in my Java application from the Gradle build file. I am following the instructions here;

https://docs.spring.io/spring-boot/docs/current/reference/html/howto-build.html

build.gradle

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-
        plugin:1.5.7.RELEASE")
    }
}

project.version = '0.1.0'

apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'

springBoot  {
    buildInfo()
}

jar {
    baseName = 'ci-backend'
}

war {
   baseName = 'ci-backend'
}

repositories {
    mavenCentral()
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web")
    compile("org.springframework:spring-jdbc")
    compile("joda-time:joda-time")

    compile("com.opencsv:opencsv:3.9")
    compile("org.springframework.batch:spring-batch-core")

    testCompile('org.springframework.boot:spring-boot-starter-test')
    providedRuntime('org.springframework.boot:spring-boot-starter-tomcat')
 }

After building with gradle the build-info.properties file is present in build/resources/main/META-INF/build-info.properties

In my @RestController I am trying to autowire the build properties bean

@Autowired
private BuildProperties buildProperties;

I am getting the following error;

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.boot.info.BuildProperties' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1493)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
... 41 more

I would assume that the BuildProperties bean is automatically created when the build-info.properties is present. It does not seem to be the case.

Jags
  • 1,639
  • 1
  • 16
  • 30
  • @Autowired private BuildProperties buildProperties; was working and instantiating, if "build-info" file was generated by dependency management framework. – Oleksii Kyslytsyn Mar 08 '18 at 11:05

11 Answers11

33

The problem I had may have been different, but I landed here trying to google the solution, so I'll post this here in case anybody else runs into the same problem. My error message was:

Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.boot.info.BuildProperties' available

It was only when trying to run within IntelliJ, not when run with gradle from the command line. (AND this is possibly specific to SpringBoot)

I just needed to set "Delegate IDE build/run actions to gradle" from within "Build, Execution, Deployment->Build Tools->Gradle" which then got the "bootBuildInfo" task to run when building from the IDE.

Brian Deacon
  • 21,384
  • 13
  • 39
  • 41
  • Unfortunately I no longer have access to the repo that had this issue, so I won't be able to confirm what the original issue was. However having a few answers here will certainly help people facing this same issue. – Jags Sep 12 '18 at 00:24
  • I just copied the file `build/resources/main/META-INF/build-info.properties` to `out/production/resources/META-INF/build-info.properties`. – andy Sep 07 '22 at 13:49
21

For a Maven project, in IntelliJ "Preferences...", under Build, Execution, Deployment > Build Tools > Maven > Runner, select the option "Delegate IDE build/run actions to Maven."

izilotti
  • 4,757
  • 1
  • 48
  • 55
  • You may get unit tests being run every time you start your application if you select that option. – ACV Aug 19 '22 at 17:20
12

Your assumption is right, the BuildProperties bean is automatically created when the META-INF/build-info.properties is present.

See the following autoconfiguration code in ProjectInfoAutoConfiguration

@ConditionalOnResource(
    resources = {"${spring.info.build.location:classpath:META-INF/build-info.properties}"}
)
@ConditionalOnMissingBean
@Bean
public BuildProperties buildProperties() throws Exception {
    return new BuildProperties(this.loadFrom(this.properties.getBuild().getLocation(), "build"));
}

However, if the bean is still not available in your application context, try any of the following:

  1. Make sure the buildInfo gradle task is properly configured, run gradlew bootBuildInfo --debug and verify the results
  2. Check if your IDE output directory differs from gradle's build directory, for example intellij make use of the out directory (in my case the build-info.properties file was not present)
  3. Upgrade your gradle plugin, perhaps you hit this issue https://github.com/spring-projects/spring-boot/issues/12266, where you can try to use the following hack if you don't want to wait for the patch to be released

    def removeBootBuildInfoWorkaround12266 = task(type: Delete, 'removeBootBuildInfoWorkaround12266') {
        delete new File(buildDir, 'resources/main/META-INF/build-info.properties')
    }
    tasks.find { it.name == 'bootBuildInfo' }.dependsOn(removeBootBuildInfoWorkaround12266)
    

Hope it helps.

Carlos Quijano
  • 1,566
  • 15
  • 23
  • Unfortunately I no longer have access to the repo that had this issue, so I won't be able to confirm what the original issue was. However having a few answers here will certainly help people facing this same issue. – Jags Sep 12 '18 at 00:24
  • 2
    This answer concluded my half day of searching thanks a lot! – Ahmet Eroğlu Nov 10 '20 at 20:06
8

You would need to configure Intelij to use Gradle Runner so it generates build.properties file in out folder. Enable Delegate IDE build/run actions to Gradle option in Settings (Preferences) | Build, Execution, Deployment | Build Tools | Gradle | Runner tab.

Casper
  • 265
  • 4
  • 12
3

I know this question is old, but I ran into it today and wanted to share an alternate solution. I was running tests from IntelliJ that live in a separate package (although you could add annotations to restrict this configuration from loading, then it could just live in the main package)

Example is in kotlin:

@Configuration
class IntegrationAppConfig {
    @Bean
    @ConditionalOnMissingBean(BuildProperties::class)
    fun buildProperties(): BuildProperties = BuildProperties(Properties()).also {
        logger.error("BuildProperties bean did not auto-load, creating mock BuildProperties")
    }
}

This allows you to keep running with IntelliJ if you like, without having to go through Gradle if you don't want to.

Mike Emery
  • 807
  • 1
  • 11
  • 23
2

Newest versions of Intellij do not have the path "Build, Execution, Deployment->Build Tools->Gradle->Runner" anymore.

To achieve the same result go to "Build, Execution, Deployment->Build Tools->Gradle->Gradle projects" and select Gradle at "Build and run using:".

marcellorvalle
  • 1,631
  • 3
  • 17
  • 30
2

to add to @Mike Emery response, found the equivalent Java's code bellow:

@Bean @ConditionalOnMissingBean(BuildProperties.class)
BuildProperties buildProperties() {
    log.error("BuildProperties bean did not auto-load, creating it");
    return new BuildProperties(new Properties());
}
aki
  • 91
  • 4
1

I was also facing the same problem, it was maven issue I upgraded my maven verion(3.3.9) and built in command prompt instead of building it in the IDE. I know this is something weird but YES this is what worked for me.

Ravi Wadje
  • 1,145
  • 1
  • 10
  • 15
  • This is because, similar to what @Casper said, the build-info.properties is not built by IntelliJ. When you mvn clean the project it is removed. If someone knows how to get IntelliJ to build that it would be appreciated. – Bryan Pugh Sep 04 '19 at 14:06
  • In Intellij, when editing a run configuration, I am able to add a Before launch Maven goal of `spring-boot:build-info`. It's a bit of a pain to have to do to all configurations, and I suspect @izilotti solution would be a one-time thing – James Render Jan 30 '20 at 09:17
1

When the issue with IDE, you can try this fix.

Go to File -> Settings

then go to option "Build, Execution, Deployment"->Build Tools->Gradle->Runner

enter image description here

Sathiamoorthy
  • 8,831
  • 9
  • 65
  • 77
1

Adding the following in build.gradle resolved this issue for me:

springBoot {
    buildInfo()
}
Paul Roub
  • 36,322
  • 27
  • 84
  • 93
sg811
  • 11
  • 2
0

This step was already done by the author, but I found myself in the same error as the author and nothing helped. But this helped:

I solved it by adding this to build.gradle:

springBoot {
    buildInfo()
}
Superluminal
  • 947
  • 10
  • 23
  • As said: the author already has this in his build file, but maybe my answer will help some people searching for answers on this question – Superluminal Jun 05 '20 at 12:47