AlleXyS
AlleXyS

Reputation: 2598

Overwriting application.conf using Maven and generating jar file

I have a Scala app (v2.13) created using Maven v3. My resources path is:

src -> main -> resources -> application.conf and aplication.prod.conf

When I generate the JAR file for production, I want to take configuration resources from application.conf, but being overwriten by application.prod.conf.

I can not found a solution for that, all founded examples are for Play framework or previous maven versions.

The JAR file is generated using maven package cmd.

application.prod.conf file

include "application.conf"

# override default (DEV) settings

http {
  host = "99.999.999.9"
  port = 1111
}

The following example doesn't works for me, because from target path I get only the JAR file to move it on production:

<plugin>
     <artifactId>maven-antrun-plugin</artifactId>
     <version>3.0.0</version>
     <executions>
         <execution>
             <phase>package</phase>
             <goals>
                 <goal>run</goal>
             </goals>
             <configuration>
                 <target>
                    <delete file="${project.build.outputDirectory}/application.conf"/>
                    <copy file="src/main/resources/application.prod.conf"
                          tofile="${project.build.outputDirectory}/application.conf"/>
                 </target>
             </configuration>
         </execution>
     </executions>
</plugin>

Upvotes: 0

Views: 893

Answers (2)

Mark Bramnik
Mark Bramnik

Reputation: 42451

Maven has a concept of phases (we're talking about the phase package here to be precise) which are logical places in the life cycle where the plugins can be invoked. Some plugins, like the one that creates the jar, for example, are associated to phases automatically (out-of-the-box), others you define explicitly and associate with the phase (like maven-antrun-plugin which is executed during the phase package as you've showed in the code snippet).

With that in mind, Is it possible that the file is attempted to get copied after the jar was packaged, so that the antrun plugin is invoked after the artifacts were packaged into the jar?

If so, the easiest solution will be moving it to one phase before, for example prepare-package:

<plugin>
     <artifactId>maven-antrun-plugin</artifactId>
     <version>3.0.0</version>
     <executions>
         <execution>
             <phase>prepare-package</phase>  <!-- Note the change here -->
             <goals>
                 <goal>run</goal>
             </goals>
             <configuration>
                 <target>
                    <delete file="${project.build.outputDirectory}/application.conf"/>
                    <copy file="src/main/resources/application.prod.conf"
                          tofile="${project.build.outputDirectory}/application.conf"/>
                 </target>
             </configuration>
         </execution>
     </executions>
</plugin>

Assuming you have maven 3 (there is no maven version 4 yet so it might be a typo), the information about which phases are available in maven here

Having said that, probably its not a good idea to "bake" the configuration file of production into the artifact, two issues here:

  1. Your source code contains the information about production - hosts, ports, maybe even sensitive information like passwords or keys - this shouldn't really happen
  2. From the point of view of build, your artifact is coupled to concrete environment, which is also considered a bad practice basically.

The techniques to resolve this are beyond the scope of the question but at least you've been warned :)

Upvotes: 0

Pritam Kadam
Pritam Kadam

Reputation: 2527

Few options here:

  1. If your application.prod.cont is static and gets shipped with jar, why cant you have a logic in the code which loads appropriate app conf based on the environment app is getting executed

  2. Is it a typesafe config, if so, while running in prod you can pass -Dconfig.resource=/application.prod.conf java command line argument

  3. or application.prod.conf is not shipped with jar then you can pass -Dconfig.file=/path/to/application.prod.conf

Upvotes: 2

Related Questions