【问题标题】:Runnable jar unable to load application.properties file?可运行的 jar 无法加载 application.properties 文件?
【发布时间】:2018-01-08 09:44:50
【问题描述】:

我在 Eclipse(不是 STS-Eclipse)上使用 SpringBoot 开发了一个应用程序。项目结构如下:

虽然应用程序在 Eclipse 中运行得非常好但在制作可执行的 jar(比如说 MyApp.jar)时无法运行。在我看来,可执行文件无法加载application.properties 文件,或者无法解析所需的属性字段值。我使用调试模式运行该应用程序,但找不到任何关于缺少application.properties 文件的线索。它只包含NumberFormatException

日志错误详情:-

[ERROR] 2017-08-04 12:03:36.301 [main] SpringApplication - Application startup failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'myBusiness': Unsatisfied dependency expressed through fiel
d 'myCommonProperty'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myCommonConfig' define
d in URL [jar:file:/app/Keygen/bin/MyApp.jar!/com/keygen/config/MyCommonConfig.class]: Bean instantiation via constructor failed; neste
d exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.keygen.config.MyCommonConfig$$EnhancerBySpringCGLI
B$$f47f0d]: Constructor threw exception; nested exception is java.lang.NumberFormatException: For input string: "${thread.core.pool.size}"
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor
.java:588) ~[MyApp.jar:?]

MyCommonConfig.java

@Configuration
public class MyCommonConfig {
       .
       .
       .
    @Autowired
    public MyCommonConfig(@Value("${thread.core.pool.size}")String corePoolSize,@Value("${thread.max.pool.size}")String maxPoolSize,@Value("${sys.blacklisted.keywords}")String blackListedKeywords,@Value("${sys.sleep.time}")String sleepTime,@Value("${sys.keyword.size}")String keywordSize,@Value("${sys.queue.size}")String queueSize) {
        this.corePoolSize=Integer.parseInt(corePoolSize);//Getting Number format exception as the value parsed is "${thread.core.pool.size}" which should be "500"
        this.maxPoolSize=Integer.parseInt(maxPoolSize);
        this.blackListedKeywords=blackListedKeywords;
        this.sleepTime=Integer.parseInt(sleepTime);
        this.keywordSize=Integer.parseInt(keywordSize);
        this.queueSize=Long.parseLong(queueSize);
        LOGGER.info("Loading MyCommonConfig complete");
    }
        .
        .
        .
}

下面是我的SpringBoot应用类

@SpringBootApplication
public class MyApp{
    public static void main(String[] args) {
        SpringApplication springApplication = new SpringApplication(MyApp.class);
        springApplication.addListeners(new ApplicationPidFileWriter());
        springApplication.setRegisterShutdownHook(true);
        ApplicationContext applicationContext = springApplication.run(args);
        MyAppBusiness myAppBusiness = applicationContext.getBean(MyAppBusiness.class);
        myAppBusiness.serve();
    }
}

我正在执行脚本./keygen.sh,其中包含以下命令:

java -jar MyApp.jar

二进制结构如下:

提前致谢。

更新

请注意,我没有使用任何构建工具或 STS-Eclipse 来制作可执行的可运行 jar。

更新 2

添加 jar 文件详细信息

【问题讨论】:

  • 可能是重复的。但是如何在没有 maven 的情况下处理它,因为我没有使用任何 bulding 工具。
  • 这里没有足够的信息来提供解决方案。堆栈跟踪会有所帮助。哪些属性文件没有被加载?最终解决此类问题的方法是首先确定哪些属性加载失败,找到包含所需属性值的属性文件,检查属性文件是否在正确的位置,并检查弹簧配置以确保它从正确的位置加载属性。您还可以打开额外的 spring 日志记录,让您了解程序加载属性的位置。
  • 看,这里 Spring Boot 在使用可执行 jar 运行时可能会加载一些 default 属性文件,例如 application.properties 和 log4j2.xml,而不是 my application.properies 和 logj4j2.xml。这就是为什么我在解析我的一个自定义属性时得到NumberFormatException 的原因,因为Spring Boot 正在加载的default 属性文件中不存在该属性。我现在清楚了吗@Adam
  • 问题与 Abdullah Khan 在上述评论中的建议相同,但解决方案对我没有帮助。我正在寻找不使用任何构建工具或 pom.xml 的解决方案。

标签: eclipse spring-boot


【解决方案1】:

终于解决了。在这里,我将介绍您将面临此类问题的案例场景:

1) 您在不使用 STS-Eclipse IDE 的情况下开发 Spring Boot 应用程序。

2) 您没有使用 Maven/Gradle 之类的构建工具来构建 jar 文件。

3) 您只是在使用传统 Eclipse IDE 的 hepl 制作简单的可运行 jar。

解决方案:-

1) 如果上述情况符合,那么我提醒您,您正在挑战推荐的 Spring Boot 应用程序开发方式。

2) 所以你必须做与@Abdullah Khan 在comment 中建议的完全相反的事情。意味着你必须删除 spring-boot-maven-plugin-1.5.4.RELEASE.jar 如果它在那里,因为它不是一个 maven 项目。

3) 即使application.properties 文件隐式加载并在Eclipse IDE 中运行良好且没有任何问题,但这并不意味着您的构建jar 将运行。因此,您必须明确提供属性文件的位置,如下所示:

@SpringBootApplication
@PropertySource("file:application.properties")//See here
public class MyApp{
    public static void main(String[] args) {
        SpringApplication springApplication = new SpringApplication(MyApp.class);
        springApplication.addListeners(new ApplicationPidFileWriter());
        springApplication.setRegisterShutdownHook(true);
        ApplicationContext applicationContext = springApplication.run(args);
        MyAppBusiness myAppBusiness = applicationContext.getBean(MyAppBusiness.class);
        myAppBusiness.serve();
    }
}

4) 现在改变你的项目结构如下:

5) 现在您可以制作 jar 文件并使用以下结构在任何环境中运行:

注意:-即使您在 root 调试模式下运行日志文件,您也可能无法在日志文件中找到任何预期的消息,例如 "missing application.properties""report of application.properties not found" 消息。

所以这绝对不是重复的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-19
    • 2019-12-12
    • 1970-01-01
    • 2020-11-07
    • 2017-02-07
    • 2020-02-18
    • 2013-07-04
    • 1970-01-01
    相关资源
    最近更新 更多