tsuda7
tsuda7

Reputation: 413

External properties file for an executable jar

I'm trying to add an external properties file to an executable jar, but not in succeed for now.

Question: Is it impossible to include an external properties file into an executable jar?

When I run my program locally, with putting batch.properties under src/main/resources, it works fine. But it fails after deploying the jar and batch.properties, linking it under /etc/init.d/, putting the jar and batch.properties

/usr/local/myapp/myapp.jar
/usr/local/myapp/batch.properties
/etc/init.d/my-app    --(symlink)-->   /usr/local/myapp/myapp.jar

my-app can be executable just like an usual service:

/etc/init.d/my-app start

But it says that some beans cannot be instantiated due to missing placeholders.

Invalid bean definition with name 'dataSource' defined in class path resource [batch.xml]: Could not resolve placeholder 'spring.datasource.batch.class_name' in string value "${spring.datasource.batch.class_name}"; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'spring.datasource.batch.class_name' in string value "${spring.datasource.batch.class_name}"

My pom.xml is like this:

<project ...>
  // Some other definitions...

  <build>
    <resources>
      <resource>
        <directory>src/main/resources</directory>
      </resource>
    </resources>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <configuration>
          <mainClass>my.project.Bootstrap</mainClass>
          <executable>true</executable>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

And the Spring setting is just like this:

<?xml version="1.0" encoding="UTF-8"?>
<beans ...">
  <context:property-placeholder location="classpath*:batch.properties" />
  <!-- Some bean definitions -->
</beans>

Any help or comments would be appreciated so much.

EDIT

I couldn't succeed it for now, but alternately I decided to split profiles and include a properties file accordingly into the executable jar.

However it's better to be able to read an external properties file, any help would still be welcomed.

Upvotes: 2

Views: 10159

Answers (1)

Arnaud Denoyelle
Arnaud Denoyelle

Reputation: 31215

You can add an external properties file next to the .jar provided that you call it application.properties.

If you cannot rename the properties file, you can also give the path of the external properties file as an option :

java -jar myproject.jar --spring.config.location=/path/to/batch.properties

#Or for executable jars
./myproject.jar --spring.config.location=/path/to/batch.properties

You can also create a symlink application.properties -> batch.properties.

See Externalized configuration.

EDIT

This is my maven config :

<build>
  <plugins>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
      <version>1.3.3.RELEASE</version>
      <configuration>
        <executable>true</executable>
      </configuration>
      <executions>
        <execution>
          <goals>
            <goal>repackage</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

After mvn clean install, I get 2 jars :

backend/target [ ll
total 53M
-rwxr--r-- 1 adenoyelle adenoyelle  53M avril 22 10:56 backend-1.0-SNAPSHOT.jar
-rw-r--r-- 1 adenoyelle adenoyelle 353K avril 22 10:56 backend-1.0-SNAPSHOT.jar.original

Then, I copy the first jar to the destination folder and place a configuration.properties next to it :

backend@[...]:~/backend$ ll
total 53900
drwxrwxr-x 2 backend backend     4096 Apr 21 13:56 ./
drwxr-xr-x 6 backend backend     4096 Apr 21 13:56 ../
-rw-rw-r-- 1 backend backend      511 Apr 20 16:13 application.properties
-rwxr--r-- 1 backend backend 55175294 Apr 20 19:06 backend-1.0-SNAPSHOT.jar*
lrwxrwxrwx 1 backend backend       24 Apr 20 19:20 backend -> backend-1.0-SNAPSHOT.jar*
-rw-r--r-- 1 backend backend      179 Apr 20 19:26 backend.service

You can see that I also created a file called backend.service in order to install the jar as a service via systemd.

Here is the content of the file :

[Unit]
Description=backend
After=syslog.target

[Service]
User=backend
ExecStart=/home/backend/backend
SuccessExitStatus=143

[Install]
WantedBy=multi-user.target

And there is a symlink to this file in /etc/systemd/system :

backend@[...]:/etc/systemd/system$ ll | grep backend
lrwxrwxrwx  1 root root   37 Apr 20 19:23 backend.service -> /home/backend/backend.service

Upvotes: 4

Related Questions