BuildProperties Spring Boot 2.1.5 和 Spring Boot 2.1.5 的自动装配失败蚀

发布于 2025-01-09 02:03:02 字数 3523 浏览 0 评论 0原文

我正在使用一些 REST API 创建一个非常简单的应用程序,它目前工作正常,直到我尝试在运行状况检查 API 上使用 BuildProperties。在启动我的应用程序时,我收到以下错误:

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2019-06-17 09:54:29.210 ERROR 10796 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 

***************************
APPLICATION FAILED TO START
***************************

Description:

Field buildProperties in com.controller.HealthCheck required a bean of type 'org.springframework.boot.info.BuildProperties' that could not be found.

The injection point has the following annotations:
    - @org.springframework.beans.factory.annotation.Autowired(required=true)

The following candidates were found but could not be injected:
    - Bean method 'buildProperties' in 'ProjectInfoAutoConfiguration' not loaded because @ConditionalOnResource did not find resource '${spring.info.build.location:classpath:META-INF/build-info.properties}'


Action:

Consider revisiting the entries above or defining a bean of type 'org.springframework.boot.info.BuildProperties' in your configuration.

我转到构建文件,还查看了构建创建的 jar 文件,我发现 build-info.properties 实际上就在那里。在 jar 文件中,文件的路径是“BOOT-INF\classes\META-INF\”。我还有其他没有问题的“自动连线”元素。

我的代码失败的地方:

@RestController
public class HealthCheck {

    @Autowired
    Environment environment;

    @Autowired 
    BuildProperties buildProperties;


    @GetMapping("/health")
    public HealthCheckResponse healthCheck() {
        return getHealthCheckResponse();
    }

    private HealthCheckResponse getHealthCheckResponse(){
        HealthCheckResponse healthResponse = new HealthCheckResponse();
        String[] profiles = environment.getActiveProfiles();

        healthResponse.setServerTime(new Date());
        healthResponse.setVersion(buildProperties.getVersion());
        healthResponse.setEnvironment(profiles[0]);

        return healthResponse;
    }

我的 gradle 构建文件:

plugins {
    id 'org.asciidoctor.convert' version '1.5.3'
    id 'org.springframework.boot' version '2.1.5.RELEASE'
    id 'java'
}

apply plugin: 'io.spring.dependency-management'
apply plugin: 'eclipse'
apply plugin: 'java'

group = 'com'
version = '0.0.1'
sourceCompatibility = '12'

repositories {
    mavenCentral()
}

ext {
    set('snippetsDir', file("build/generated-snippets"))
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-jersey'
    implementation 'org.springframework.boot:spring-boot-starter-security'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'com.github.ulisesbocchio:jasypt-spring-boot-starter:2.1.1'
    runtimeOnly 'mysql:mysql-connector-java'
    annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'org.springframework.restdocs:spring-restdocs-webtestclient'
    testImplementation 'org.springframework.security:spring-security-test'
}

test {
    outputs.dir snippetsDir
}

asciidoctor {
    inputs.dir snippetsDir
    dependsOn test
}

springBoot {
    buildInfo()
}

build-info.properties:

#Properties
#Mon Jun 17 10:52:04 EDT 2019
build.version=0.0.1
build.group=com
build.name=app
build.artifact=app
build.time=2019-06-17T14\:52\:04.829909200Z

I'm creating a very simple application with a few REST API's and it's currently working correctly until I try to use the BuildProperties on my health check API. While starting my application I get the following error:

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2019-06-17 09:54:29.210 ERROR 10796 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 

***************************
APPLICATION FAILED TO START
***************************

Description:

Field buildProperties in com.controller.HealthCheck required a bean of type 'org.springframework.boot.info.BuildProperties' that could not be found.

The injection point has the following annotations:
    - @org.springframework.beans.factory.annotation.Autowired(required=true)

The following candidates were found but could not be injected:
    - Bean method 'buildProperties' in 'ProjectInfoAutoConfiguration' not loaded because @ConditionalOnResource did not find resource '${spring.info.build.location:classpath:META-INF/build-info.properties}'


Action:

Consider revisiting the entries above or defining a bean of type 'org.springframework.boot.info.BuildProperties' in your configuration.

I went to the build file and I also looked in the jar file created by the build and I see the build-info.properties is in fact there. In the jar file the path to the file is "BOOT-INF\classes\META-INF\". I also have other "Autowired" elements that are not having issues.

Where my code fails:

@RestController
public class HealthCheck {

    @Autowired
    Environment environment;

    @Autowired 
    BuildProperties buildProperties;


    @GetMapping("/health")
    public HealthCheckResponse healthCheck() {
        return getHealthCheckResponse();
    }

    private HealthCheckResponse getHealthCheckResponse(){
        HealthCheckResponse healthResponse = new HealthCheckResponse();
        String[] profiles = environment.getActiveProfiles();

        healthResponse.setServerTime(new Date());
        healthResponse.setVersion(buildProperties.getVersion());
        healthResponse.setEnvironment(profiles[0]);

        return healthResponse;
    }

My gradle build file:

plugins {
    id 'org.asciidoctor.convert' version '1.5.3'
    id 'org.springframework.boot' version '2.1.5.RELEASE'
    id 'java'
}

apply plugin: 'io.spring.dependency-management'
apply plugin: 'eclipse'
apply plugin: 'java'

group = 'com'
version = '0.0.1'
sourceCompatibility = '12'

repositories {
    mavenCentral()
}

ext {
    set('snippetsDir', file("build/generated-snippets"))
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-jersey'
    implementation 'org.springframework.boot:spring-boot-starter-security'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'com.github.ulisesbocchio:jasypt-spring-boot-starter:2.1.1'
    runtimeOnly 'mysql:mysql-connector-java'
    annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'org.springframework.restdocs:spring-restdocs-webtestclient'
    testImplementation 'org.springframework.security:spring-security-test'
}

test {
    outputs.dir snippetsDir
}

asciidoctor {
    inputs.dir snippetsDir
    dependsOn test
}

springBoot {
    buildInfo()
}

build-info.properties:

#Properties
#Mon Jun 17 10:52:04 EDT 2019
build.version=0.0.1
build.group=com
build.name=app
build.artifact=app
build.time=2019-06-17T14\:52\:04.829909200Z

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(15

葬花如无物 2025-01-16 02:03:02

只需运行 mvn clean package,然后从 Eclipse/IntelliJ 重新启动 Spring Boot 应用程序。

Just run a mvn clean package and then restart the spring boot application from either Eclipse/IntelliJ.

北城孤痞 2025-01-16 02:03:02

在pom.xml末尾添加/修改:

<build>
        <finalName>{NAME_YOUR_PROJECT}</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>build-info</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

Add/Modify at the end of pom.xml:

<build>
        <finalName>{NAME_YOUR_PROJECT}</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>build-info</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
巴黎夜雨 2025-01-16 02:03:02

简而言之:这个问题与 IDE 相关(我在 Eclipse 和 Idea 上进行了检查),并且这不会影响通过 gradle 构建系统在启动脚本中运行/调试 spring boot 应用程序。

另外,eclipse 和 JDK 的启动插件产生此问题的前提并不完全正确。

此问题的根源:使用不同编译器编译的构建工件的位置不同,并且缺少 build-info.properties

说明:

当 gradle 执行构建时,它通常使用 JDK 编译器来生成 Java 工件,并将输出放置到构建目录中。

另一方面,当 eclipse 执行构建时,它会使用 Eclipse JDT 生成 arifacts,并将输出放入 bin 目录中。

请注意,混合这两者可能会导致意外的行为。这个“功能”已经被 Eclipse 团队分析并被拒绝(因无效而关闭)。更多信息请参见此处

根据 gradle 任务 buildInfo 由 gradle 运行的事实,这解释了 build-info.properties 文件存在于 gradle 的默认输出文件夹中的事实(默认情况下它必须位于此处:build/resources/main/META-INF/)。

从@ROOTKILL的问题中可以看出,他试图从BuildProperties类中获取信息。在底层,当 Spring 检测到类路径上有 build-info.properties 文件时,它会创建 BuildProperties bean,除非显式声明它。
有用的信息是 这里

请看一下这个方法:

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

根据 IDE 使用不同输出目录的事实,缺少 build-info.properties 文件,这会产生显示错误 (Bean method 'buildProperties' in 'ProjectInfoAutoConfiguration' not returned因为@ConditionalOnResource没有找到资源'${spring.info.build.location:classpath:META-INF/build-info.properties}')。
另一方面,这解释了为什么一切都可以通过 gradle 运行。

解决方案:

根据这些事实,解决方案很明确:Eclipse 和 IntelliJ Idea IDE 都必须使用 gradle 的任务而不是它自己的任务来运行/调试。

  • 对于 Eclipse IDE:可以通过 gradle 任务启动应用程序(从 gradle 任务视图中 bootRun)。
  • 对于 Idea IDE:可以添加将 IDE 构建/运行操作委托给 gradle 的设置,这是 @user666 之前已经指出的。

由于此解决方案使用 gradle,因此将从 build/resources/main/META-INF/ 位置(gradle 的默认值)使用 build-info.properties 文件,当然它将可见。结果,bean BuildProperties 将被创建并且可用。

In short: This problem is IDE related (I'm checked on Eclipse and Idea), and this is not affecting running/debugging spring boot application in startup scripts over the gradle build system.

Also, premise that boot plugin for eclipse and JDK are producing this problem is not entirely correct.

Root of this problem: Different location of build artifacts which are compiled with different compilers and missing build-info.properties.

Explanation:

When gradle performs the build, it ussually uses JDK compiler to produce Java artifacts and output is placed into build directory.

On the other side, when eclipse performs the build, it produces arifacts with Eclipse JDT and output is placed into bin directory.

Note that mixing those two could lead to unexpected behaviours. This 'feature' is already analyzed by eclipse team and it is rejected (closed as invalid). More information here.

According to fact that gradle task buildInfo is ran by gradle, that is explaining the fact that build-info.properties file exists in gradle's default output folder (by default it has to be located here: build/resources/main/META-INF/).

From @ROOTKILL's question, visible is that he is tried to obtain information from BuildProperties class. Under the hood, when Spring detects there is build-info.properties file on the classpath, it creates BuildProperties bean unless it is explicitly declared.
Useful information is here.

Please, take a look at this method:

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

According to the fact that IDE is using different output dir, there is missing build-info.properties file and this produces displayed error (Bean method 'buildProperties' in 'ProjectInfoAutoConfiguration' not loaded because @ConditionalOnResource did not find resource '${spring.info.build.location:classpath:META-INF/build-info.properties}').
And on other side, this explains why everything is runnable with gradle.

Solution:

According to those facts, solution is clear: Both eclipse and IntelliJ Idea IDE's must use gradle's tasks instead of it's own for running/debugging.

  • For the Eclipse IDE: Application can be started over the gradle task (bootRun from gradle tasks view).
  • For the Idea IDE: There can be added setting that delegates IDE build/run actions to gradle, which is @user666 already pointed before.

Since this solution uses gradle, build-info.properties file will be used from build/resources/main/META-INF/ location (gradle's default), and off course it will be visible. As a consequence, bean BuildProperties will be created and will be usable.

复古式 2025-01-16 02:03:02

正如 @André Schonrock 正确提到的,问题的原因是 此处

Maven 插件和 Gradle 插件都允许生成构建
包含坐标、名称和版本的信息
项目。插件还可以配置为添加额外的
通过配置的属性。当存在这样的文件时,Spring
引导自动配置 BuildProperties bean。

因此,您需要在 POM 中添加 spring-boot-maven-plugin

<executions>
    <execution>
        <goals>
            <goal>build-info</goal>
        </goals>
    </execution>
</executions> 

或在 build.gradle 中添加:

springBoot {
    buildInfo()
}

作为替代方式可以以比 @djangofan 显示的更短的形式显式添加 Bean

@Bean @ConditionalOnMissingBean(BuildProperties.class)
BuildProperties buildProperties() {
    return new BuildProperties(new Properties());
}

在配置文件中。

注意:如果您更新了POMbuild.gradle,但错误仍然出现,请尝试使用(例如对于Maven)生命周期命令clean,然后install并再次运行该项目。

As correctly mentioned by @André Schonrock, the cause of issue is here:

Both the Maven plugin and the Gradle plugin allow generating build
information containing the coordinates, name, and version of the
project. The plugins can also be configured to add additional
properties through configuration. When such a file is present, Spring
Boot auto-configures a BuildProperties bean.

So you need either to add for spring-boot-maven-plugin in POM:

<executions>
    <execution>
        <goals>
            <goal>build-info</goal>
        </goals>
    </execution>
</executions> 

or to add in build.gradle:

springBoot {
    buildInfo()
}

As alternative way can be explicitly added Bean in a shorter form than was shown by @djangofan:

@Bean @ConditionalOnMissingBean(BuildProperties.class)
BuildProperties buildProperties() {
    return new BuildProperties(new Properties());
}

in configuration file.

Notice: if you updated POM or build.gradle, but the error still appears, try to use (e.g. for Maven) lifecycle commands clean and then install and run again the project.

缘字诀 2025-01-16 02:03:02

如果使用 Intelli 和 Maven,这里是有关如何更改运行器和使用 Maven 运行器的屏幕截图。理想情况下,这是最好的建议,因为我们也可以按照 Maven 在 IDE 中运行的方式运行。

输入图像描述这里

If using Intelli and maven, here is screenshot on how to change the runner and use maven runner. Ideally this is best suggested, as we can run exactly how maven runs in the ide also.

enter image description here

っ〆星空下的拥抱 2025-01-16 02:03:02

正如@Borislav Markov 建议的那样,我尝试通过命令行运行它,无论我使用 JDK 12 还是 JDK 8,它似乎都能完美工作。我认为这个问题与我用来通过 IDE 运行应用程序的 Eclipse 插件有关。

As @Borislav Markov suggested I tried running it via command line and it seems to work perfectly regardless if I use JDK 12 or JDK 8. I think the issue has to do with the eclipse plugin I am using to run the application via the IDE.

神也荒唐 2025-01-16 02:03:02

我的 Spring Boot 服务在 maven-spring-boot 插件中有一个 Maven 构建信息部分,因此当我尝试运行该服务时,如果该服务不是来自 . jar 存档。因此,为了将我的服务作为常规 Spring Boot 运行配置运行,我必须添加此条件 bean,现在一切正常,既作为 .jar 版本运行,又作为调试非版本运行:

@ConditionalOnMissingBean
@Bean
public BuildProperties buildProperties() {
    Properties properties = new Properties();
    properties.put("group", "com.example");
    properties.put("artifact", "demo");
    properties.put("version", "not-jarred");
    return new BuildProperties(properties);
}

My Spring Boot service has a Maven build-info section in the maven-spring-boot plugin and so I get this error BuildProperties cannot be found when I try to run the service when it is not from a .jar archive. So, to run my service as a regular Spring Boot run configuration, I had to add this condition bean and now everything works , both as a .jar release and also it runs as a debug non-release:

@ConditionalOnMissingBean
@Bean
public BuildProperties buildProperties() {
    Properties properties = new Properties();
    properties.put("group", "com.example");
    properties.put("artifact", "demo");
    properties.put("version", "not-jarred");
    return new BuildProperties(properties);
}
如梦亦如幻 2025-01-16 02:03:02

如果您使用 lombok,请确保排除 spring-boot-maven-plugin 的配置,例如,

    <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <configuration>
            <excludes>
                <exclude>
                    <groupId>org.projectlombok</groupId>
                    <artifactId>lombok</artifactId>
                </exclude>
            </excludes>
        </configuration>
        <executions>
            <execution>
                <id>build-info</id>
                <goals>
                    <goal>build-info</goal>
                </goals>
            </execution>
        </executions>
    </plugin>

If you are using lombok, make sure to exclude it configuration for spring-boot-maven-plugin, e.g.,

    <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <configuration>
            <excludes>
                <exclude>
                    <groupId>org.projectlombok</groupId>
                    <artifactId>lombok</artifactId>
                </exclude>
            </excludes>
        </configuration>
        <executions>
            <execution>
                <id>build-info</id>
                <goals>
                    <goal>build-info</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
笙痞 2025-01-16 02:03:02

正如其他人正确指出的那样,问题出在 IDE 上。对于 IntelliJ,替代解决方案是将 spring-boot:build-info 修改为“重建后执行”,如下所示。
输入图片此处描述

As others rightly pointed, the problem is with the IDE. For IntelliJ, the alternative solution is modifying the spring-boot:build-info to "Execute After Rebuild" as shown below.
enter image description here

留蓝 2025-01-16 02:03:02

正如其他答案所明确的,这是由于 IDE 未创建该文件。对于 vscode,我通过定义一个任务将 build-info.properties 文件从 Gradle 的 build/resources/main/META-INF 目录复制到 vscode 的 来解决这个问题bin/main/META-INF 以便构建期望找到它。

通常我最近运行了 Gradle 构建,并且 build-info.properties 的稍微过时的版本对于我在 vscode 中的调试运行来说已经足够了。

创建与此类似的 .vscode/tasks.json

{
    "version": "2.0.0",
    "tasks": [
        {
            // This task keeps vscode from failing when using BuildProperties
            "label": "Copy build-info from Gradle",
            "type": "shell",
            "command": "mkdir -p ./bin/main/META-INF/ && cp ./build/resources/main/META-INF/build-info.properties ./bin/main/META-INF/build-info.properties"
        }
    ]
}

然后将任务作为 preLaunchTask 添加到 .vscode/launch.json 中:

{
    "configurations": [
        {
            "type": "java",
            "name": "Spring Boot-Application<example>",
            "request": "launch",
            "cwd": "${workspaceFolder}",
            "console": "internalConsole",
            "mainClass": "com.example.Application",
            "projectName": "example",
            "args": "",
            "preLaunchTask": "Copy build-info from Gradle"
        }
    ]
}

As other answers have made clear, this is due to the IDE not creating the file. For vscode, I solved it by defining a task to copy the build-info.properties file from Gradle's build/resources/main/META-INF directory into vscode's bin/main/META-INF so that it would be where the build expects to find it.

Normally I have run a Gradle build recently, and that slightly stale version of build-info.properties is good enough for my debugging run in vscode.

Create a .vscode/tasks.json similar to this:

{
    "version": "2.0.0",
    "tasks": [
        {
            // This task keeps vscode from failing when using BuildProperties
            "label": "Copy build-info from Gradle",
            "type": "shell",
            "command": "mkdir -p ./bin/main/META-INF/ && cp ./build/resources/main/META-INF/build-info.properties ./bin/main/META-INF/build-info.properties"
        }
    ]
}

Then add the task as a preLaunchTask in your .vscode/launch.json:

{
    "configurations": [
        {
            "type": "java",
            "name": "Spring Boot-Application<example>",
            "request": "launch",
            "cwd": "${workspaceFolder}",
            "console": "internalConsole",
            "mainClass": "com.example.Application",
            "projectName": "example",
            "args": "",
            "preLaunchTask": "Copy build-info from Gradle"
        }
    ]
}
被翻牌 2025-01-16 02:03:02

我建议尝试在 JDK 8 下运行并从命令行运行
java -jar 只是为了确保您正确获取构建属性。

也许Jdk 12还不适合spring-boot。我想你可能还有其他问题。许多 Java 框架并未 100% 认证它们可以与 JDK 12 配合使用。

我认为计划是从 Spring Boot 2.2 开始正式支持 Java 12

I would suggest to try running under JDK 8 and to run from the command line with
java -jar <your jar name> just to be sure you get the build properties correctly.

Maybe Jdk 12 is not suitable for spring-boot yet. I think you might have other problems as well. Many Java frameworks are not 100% certified that they will work with JDK 12.

I think the plan is to officially support Java 12 as of Spring Boot 2.2

战皆罪 2025-01-16 02:03:02

我认为您的 IDE 对“fat jar”覆盖普通 jar 的事实感到困惑。 IDE 理解普通 jar + 生成的 `build-info.properties 资源的类路径。

我总是以不同的名称构建 jar,因此我可以避免部分构建的此类问题。

https:// /docs.spring.io/spring-boot/docs/current/gradle-plugin/reference/html/#packaging-executable-and-normal

为了避免将可执行存档和普通存档写入同一位置,应将其中之一配置为使用不同的位置。一种方法是配置分类器:

bootJar {
    classifier = 'boot'
}

I think your IDE is confused by the fact that the "fat jar" overwrites the normal jar. The IDE understands the classpath of the normal jar + generated resource of `build-info.properties.

I always build the jars under different names, so I can avoid this kind of issues with partial builds.

https://docs.spring.io/spring-boot/docs/current/gradle-plugin/reference/html/#packaging-executable-and-normal

To avoid the executable archive and the normal archive from being written to the same location, one or the other should be configured to use a different location. One way to do so is by configuring a classifier:

bootJar {
    classifier = 'boot'
}
垂暮老矣 2025-01-16 02:03:02

我试过 ProjectInfoAutoConfiguration 解决方案,并认为最好使用 @ConditionalOnMissingBean (BuildProperties.class) 代替
@ConditionalOnResource(资源=“$ {spring.info.build.location:类路径:META-INF / build-info.properties}”)

因为我可以控制 BuildProperties 的创建方式:

    @ConditionalOnMissingBean(BuildProperties.class)
    @Bean
    public BuildProperties buildProperties() throws IOException {
            Resource r = this.properties.getBuild().getLocation();
            if (r.exists())
                // build-info.properties exists in my jar
                return new BuildProperties(
                    loadFrom(r, "build")); // see ProjectInfoAutoConfiguration code
            else {
                // No, we running via IDE. So let's build a stub:
                Properties properties = new Properties();
                properties.put("group", "com.example");
                properties.put("artifact", "demo");
                properties.put("version", "not-jarred");
                return new BuildProperties(properties);
            }
    }

I tried ProjectInfoAutoConfiguration solution and thought it was better to use @ConditionalOnMissingBean (BuildProperties.class) instead
@ConditionalOnResource (resources = "$ {spring.info.build.location: classpath: META-INF / build-info.properties}").

Because I can control the way BuildProperties are created:

    @ConditionalOnMissingBean(BuildProperties.class)
    @Bean
    public BuildProperties buildProperties() throws IOException {
            Resource r = this.properties.getBuild().getLocation();
            if (r.exists())
                // build-info.properties exists in my jar
                return new BuildProperties(
                    loadFrom(r, "build")); // see ProjectInfoAutoConfiguration code
            else {
                // No, we running via IDE. So let's build a stub:
                Properties properties = new Properties();
                properties.put("group", "com.example");
                properties.put("artifact", "demo");
                properties.put("version", "not-jarred");
                return new BuildProperties(properties);
            }
    }
丑疤怪 2025-01-16 02:03:02

对于 Gradle 项目:将其添加到 build.gradle 文件中

    springBoot {
        buildInfo {
            properties {
                name = PROJECT_NAME
                additional = [
                        'yourCustomInfo': 'someInfo'
                ]
            }
        }
    }

For Gradle Project: add this on build.gradle file

    springBoot {
        buildInfo {
            properties {
                name = PROJECT_NAME
                additional = [
                        'yourCustomInfo': 'someInfo'
                ]
            }
        }
    }
无风消散 2025-01-16 02:03:02

问题是 STS 和 Intellij 在将应用程序作为 Spring Boot 应用程序运行时不运行 buildinfo 任务。由于大多数开发人员通过这种机制运行应用程序而不是使用 gradle / maven 构建,因此需要有一个适用于两者的解决方案。我遵循了 Sergey K 的回答,它适用于基于 IDE 的 Spring boot 运行。但对于 gradle run 来说,它失败了,因为 BuildProperties 是从配置文件而不是生成的 build-info.properties 文件自动装配的。

我能够通过使用以下组件并自动装配它来克服这个问题

@Component
public BuildValues{
   @Autowired(required = false)
   private buildProperties;
   
   public getBuildProperties(){
       if(buildProperties==null) {
          ResourceLoader resourceLoader = new DefaultResourceLoader();
          Resource r = resourceLoader.getResource("classpath:META-INF/build- 
        info.properties");
    if (r.exists()) {
        // build-info.properties exists in my jar
        Properties prop = PropertiesLoaderUtils.loadProperties(r);
        buildProperties =  new BuildProperties(prop);
    }else {
    // No, we running via IDE. So let's build a stub:
        Properties properties = new Properties();
        properties.put("buildTime", "2022-01-13T14:38:06.567Z");
        buildProperties = new BuildProperties(properties);
    }
    }
    return buildProperties;
   }

} 

The issue is STS and Intellij doesn't run the buildinfo task while running the application as a Spring Boot Application. Since most developers run the app through this mechanism rather than using gradle / maven build need to have a solution that works for both. I followed Sergey K's answer and it worked for IDE based Spring boot run. But for gradle run it failed because the BuildProperties was getting autowired from the Configuration file instead of the generated build-info.properties file.

I was able to overcome this by having the following Component and autowiring it

@Component
public BuildValues{
   @Autowired(required = false)
   private buildProperties;
   
   public getBuildProperties(){
       if(buildProperties==null) {
          ResourceLoader resourceLoader = new DefaultResourceLoader();
          Resource r = resourceLoader.getResource("classpath:META-INF/build- 
        info.properties");
    if (r.exists()) {
        // build-info.properties exists in my jar
        Properties prop = PropertiesLoaderUtils.loadProperties(r);
        buildProperties =  new BuildProperties(prop);
    }else {
    // No, we running via IDE. So let's build a stub:
        Properties properties = new Properties();
        properties.put("buildTime", "2022-01-13T14:38:06.567Z");
        buildProperties = new BuildProperties(properties);
    }
    }
    return buildProperties;
   }

} 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文