web-dev-qa-db-ja.com

GradleからのBuildProperties Beanの自動配線-NoSuchBeanDefinitionException

私のJavaアプリケーションのバージョンをGradleビルドファイルから取得しようとしています。ここの指示に従います。

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')
 }

Gradleでビルドした後、build-info.propertiesファイルはbuild/resources/main/META-INF/build-info.propertiesにあります

私の@RestControllerビルドプロパティBeanを自動配線しようとしています

@Autowired
private BuildProperties buildProperties;

次のエラーが発生します。

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

BuildProperties Beanは、build-info.propertiesが存在するときに自動的に作成されると思います。それはそうではないようです。

20
Jags

私が持っていた問題は異なっていたかもしれませんが、解決策をグーグルで探そうとしてここに着陸したので、誰かが同じ問題に遭遇した場合に備えて、これをここに投稿します。私のエラーメッセージは:

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

IntelliJ内で実行しようとした場合のみで、コマンドラインからgradleを使用して実行した場合ではありません。 (そしてこれはおそらくSpringBootに固有です)

「ビルド、実行、配置->ビルドツール->グラドル」内から「デリゲートIDEビルド/実行アクションをグラドルする」」を設定するだけで、「bootBuildInfo」タスクが実行されますIDEからビルドする場合。

4
Brian Deacon

あなたの仮定は正しいです、BuildProperties BeanはMETA-INF/build-info.propertiesが存在するときに自動的に作成されます

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"));
}

ただし、アプリケーションコンテキストでBeanがまだ使用できない場合は、次のいずれかを試してください。

  1. buildInfo gradleタスクが適切に構成されていることを確認し、gradlew bootBuildInfo --debugを実行して結果を確認します
  2. IDE出力ディレクトリがgradleのビルドディレクトリと異なるかどうかを確認します。たとえば、intellijはoutディレクトリを使用します(私の場合はbuild-info.propertiesファイルがありませんでした)。
  3. あなたのgradleプラグインをアップグレードしてください、おそらくあなたはこの問題に遭遇します https://github.com/spring-projects/spring-boot/issues/12266 ここで、もしそうでなければ、次のハックを使用することができますパッチがリリースされるのを待ちたい

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

それが役に立てば幸い。

3
Carlos Quijano

Gradle Runnerを使用するようにIntelijを構成して、outフォルダーにbuild.propertiesファイルを生成する必要があります。設定(環境設定)|ビルド、実行、配置|ビルドツール| Gradle |ランナータブでデリゲートIDEアクションをGradleにビルド/実行オプションを有効にします。

2
Casper

私も同じ問題に直面していました、それはmavenの問題でした。私はmaven verion(3.3.9)をアップグレードし、IDEでビルドする代わりにコマンドプロンプトを組み込みました。これは奇妙なことですが、そうです。

1
Ravi Wadje

この質問が古いことは知っていますが、今日私はそれに遭遇し、別の解決策を共有したいと思いました。別のパッケージにあるIntelliJのテストを実行していました(この構成の読み込みを制限するために注釈を追加することはできますが、メインパッケージにのみ置くことができます)。

例は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")
    }
}

これにより、必要に応じてGradleを実行しなくても、必要に応じてIntelliJで実行し続けることができます。

1
Mike Emery

上記の設定は正しかったが、私はまだ問題が何であったのかわかりません。

結局のところ、最善の解決策は、代わりにSpring-boot-actuatorに切り替えることです。アクチュエータには、事前設定された残りのエンドポイントにすべてのビルド情報が含まれています。

0
Jags