Runnable jar无法加载application.properties文件?

时间:2017-08-01 13:29:36

标签: eclipse spring-boot

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

enter image description here

虽然应用程序在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

二进制结构如下所示: enter image description here

提前致谢。

更新

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

更新2

添加jar文件详细信息

enter image description here

1 个答案:

答案 0 :(得分:0)

Finally got the solution. Here I am briefing the case scenario wherein you will face such problem:

1) You're developing a Spring Boot application without using STS-Eclipse IDE.

2) You're not using any bulding tool like Maven/Gradle to build the jar file.

3) You're just making simple runnable jar with the hepl of traditional Eclipse IDE.

Solution:-

1) If above cases matches, then let me remind you that you're challenging the recommended way of developing a Spring Boot application.

2) So you've to do exactly opposite what @Abdullah Khan Suggesting in comment. Means you've to remove the spring-boot-maven-plugin-1.5.4.RELEASE.jar if it is there, cuz it's not a maven project.

3) Even if the application.properties file loading implicitly and running fine without any problem in Eclipse IDE, that does not mean that your build jar will run. So you've to explicitly provide the location of your property file as follow:

@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) Now change your project structure as follow:

enter image description here

5) So now you're ready to make your jar file and run in any environment with following stucture:

enter image description here

Note:-You might not able find any expected message like "missing application.properties" or "report of application.properties not found" message in log file even if you're running it in root debug mode.

So definietely this is not a duplicate question.