-3

I developed an application using SpringBoot on Eclipse(not STS-Eclipse). The project structure looks as below:

enter image description here

While the application running absolutely fine in Eclipse but unable to run when making an excecutable jar (lets say MyApp.jar). It seems to me that the executable is unable to load the application.properties file or it is unable to parse the required property field value. I ran the application using debug mode but unable to find any clue regarding missing of application.properties file. All it contains is NumberFormatException.

Log Error details:-

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

Below is my SpringBoot application class

@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();
    }
}

I am executing the script ./keygen.sh which contains the following command:

java -jar MyApp.jar

The binary structure looks as below: enter image description here

Thanks in advance.

Update

Please note I am not using any building tool or STS-Eclipse to make execuatble runnable jar.

Update 2

Adding jar file details

enter image description here

  • 3
    Possible duplicate of [resources in a Spring Boot application are missing from jar file when using Spring Boot Maven Plugin](https://stackoverflow.com/questions/33197230/resources-in-a-spring-boot-application-are-missing-from-jar-file-when-using-spri) – Abdullah Khan Aug 01 '17 at 13:33
  • Might be it is duplicate. But how to deal it without maven as I am not using any bulding tool. – Satyaprakash Nayak Aug 01 '17 at 13:45
  • There is not enough information here to provide a solution. A stacktrace would help. Which properties files are not being loaded? Ultimately the way to approach this type of problem is to first identify what property is failing to be loaded, find the property file that contains the desired property value, check to see if the property file is in the correct location, and check the spring configuration to ensure it is loading properties from the correct location. You can also turn on additional spring logging that will give you insight as to where your program is loading properties. – Adam Aug 01 '17 at 17:12
  • See, here Spring Boot might loading some `default` property file like application.properties and log4j2.xml instead `my` application.properies and logj4j2.xml when running using an executable jar. So that is why I am getting `NumberFormatException` while parsing one of my custom property as that property does not exist in the `default` property file which Spring Boot is loading. Am I clear now @Adam – Satyaprakash Nayak Aug 02 '17 at 06:47
  • The problem is same as what Abdullah Khan is suggesting in above comment but the solution is not helpful for me. I am looking for a solution without using any building tool or pom.xml. – Satyaprakash Nayak Aug 02 '17 at 06:53
  • Dear @Adam I updated my post. Please look into the dependent jar files. Is there anything wrong? I need a solution. Please help. – Satyaprakash Nayak Aug 02 '17 at 07:35

1 Answers1

2

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.