0

My SpringBoot 2.0.3 java 8 program works fine on Eclipse Photon (using Maven), however, when I build it into a jar file and install on AWS Linux and run there I get:

2019-06-10 10:07:14.395  WARN 18316 --- [           main]s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt:org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ccWrapperApplication': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'tmp.dir' in value "${tmp.dir}"
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ccWrapperApplication': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'tmp.dir' in value "${tmp.dir}"

so it looks like spring can't find the application.properties vars when running on Linux. Why not?

tmp.dir is defined in src/main/resources/application.properties as:

tmp.dir=tmp

and ccWrapperApplication.java has:

@SpringBootApplication
// SpringBoot likes to use a database, we don't need one, so we exclude the default dB.
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class})

public class CcWrapperApplication implements CommandLineRunner {

    @Value("${tmp.dir}")
    public  String tmpDir;

    public static void main(String[] args) {
        logger.info("running CcWrapperApplication on " + System.getProperty("os.name"))
        SpringApplication.run(CcWrapperApplication.class, args);
    }

    @Override
    public void run(String... args) {
    ...
    }

    public String getTmpDir() {
        return tmpDir;
    }

    public void setTmpDir(String tmpDir) {
        this.tmpDir = tmpDir;
    }

}

I built the application jar using eclipse: export->Runnable JAR file

Installed the jar on Linux, added the jar to the CLASSPATH (and all the SpringBoot jars) and ran from a shell script using:

java  com.clarivate.singulatiry.chemworkbench.chemcurator.chemcurator_wrapper.CcWrapperApplication $inputDir $outputDir 2>&1 >>$logfile | tee -a $logfile >>$errorfile

Any help appreciated.

DS.
  • 604
  • 2
  • 6
  • 24
  • Spring boot builds a fully executable jar with all its dependencies when you run `mvn clean install`. Why not run the jar as java -jar . My bet is that there are chances some dependencies might have been missed and hence the property is not loaded. Eclipse, however would have added all the right set of dependencies when you run – Malathi Jun 10 '19 at 10:52
  • Try to build with mvn -Dhttps.protocols=TLSv1.2 clean install -DskipTests then run jar file. Looks like some dependency are missing and give exact path of tmp.dir like /tmp – DHARMENDRA SINGH Jun 10 '19 at 10:58
  • @malathi I tried your suggestion but then, in the jar file : BOOT-INF/classes/ was prepended to the classpath of all *.class entries so I got a "Could not find or load main class" error. – DS. Jun 10 '19 at 11:51
  • @dharmmendra_singh When I use maven it creates a thick jar, I want a thin jar, with just the classes from my program – DS. Jun 10 '19 at 11:55
  • 1
    You can't have both. You have to create the fat JAR to run it outside the IDE. The Spring Boot Maven plug knows how to create the executable JAR correctly. You must have done something else wrong. – duffymo Jun 10 '19 at 12:44
  • @duffymo If you create a fat jar then you deploy all the spring jars for every program you install on prod, which takes up a lot of space. That's why we create a thin jar and add the rest of the required spring jars into a lib folder once then add into the classpath as required – DS. Jun 10 '19 at 13:07
  • 1
    Yes, I'm aware. "Takes up a lot of space" - not an issue anymore. Disk space is cheap. You need those JARs to be independent and decoupled. Your idea of a /lib folder and classpath is not recommended. Putting everything in a common /lib folder means that you have to upgrade every service if you upgrade a single JAR. Sorry, you're using 90s thinking. – duffymo Jun 10 '19 at 13:19
  • @duffymo what about your backend dependencies? If you package up say ojdbc6.jar into your myProject.jar and the version of your Oracle dB changes and you now need ojdbc8.jar, you have to rebuild all your myProjectx.jars. Our way is to have one copy of ojdbc6.jar, set in the CLASSPATH using an env variable. If the dB changes we just change the env variable to point to say ojdbc8.jar. – DS. Jun 10 '19 at 14:13
  • @DS, If you want to upgrade the ojdbc from version 6 to 8, there could possibly be a code change required. In that case you definitely need to rebuild the jars. – Malathi Jun 11 '19 at 04:50

2 Answers2

1

Eclipse built in exporter to generate jar only includes the target folder files which are actually generated in the project.

In order to have a "fat", "thin" (standalone executable) jar/war, you should use Spring Boot Maven or Gradle plugin to "repackage" the jar/war.

This can further help you out.

Ankur Singhal
  • 26,012
  • 16
  • 82
  • 116
0

I used mvn install as suggested by @Malathi and created a thin jar using the method suggested here: thin jar and it worked fine, though I still don't know why the original method failed.

DS.
  • 604
  • 2
  • 6
  • 24