Dynamically get JAR filename in DockerFile - maven

I am new to Docker. I am using spring boot and when we build the project using maven, it will create jar file like app-.jar and then I am coping this jar file using ADD command in DockerFile. Now If I change the version number in pom.xml, then I need to manually update the JAR file name in DockerFile.
Is there anyway by which I can dynamically get the version number which is in the pom.xml and update the JAR file name automatically in the DockerFile?

Instead of copying the jar file inside the dockerfile, you can mount the folder in which jar is created. And you will not be needed to be worried with the filename.
What you want can be done using environment variables. You can create an --env-file and keep your version number there. And inside dockerfile, refer to value of variable declared in env file with {VERSIION}. By following this process, you may want to use this same version in your pom file. For that, take a look at this question.
The answer links environment variables by setting env.path and detailed guide is here.

Related

How to get jar name in start.sh script

I am deploying a spring boot app + maven. I have written a start.sh script using link https://dzone.com/articles/packaging-springboot-application-with-external-dep
The jar name can change as per the version , so I don't want to hard code the jar name in start.sh like -jar ../lib/gs-spring-boot-0.1.0.jar
How can I make it dependent on jar name? any variable substitution possible?
If you know there's only one JAR file, how about something like this
JAR_FILE=`ls ../lib/gs-spring-boot-*.jar`
java -jar ${JAR_FILE}
You have to create your start.sh script automatically and paste correct jar name there. Please check http://www.mojohaus.org/appassembler/appassembler-maven-plugin/
Examples: http://www.mojohaus.org/appassembler/appassembler-maven-plugin/usage-program.html
In combination with maven-assembly you can create a tar.gz or zip archive which contains everything that you need.

Spring boot external properties not working

My project structure looks like as attached file. Even though I have profile specific properties, I would like to run my app with external properties file i.e., outside of jar file.
I tried with following command:
java -jar test_service.jar --spring.config.location=file:///C:/external_props/test.properties
But its taking application-default.properties file.
from log file:
No active profile set, falling back to default profiles: default
Why it is not taking external properties file ?
When you pass --spring.config.location command line argument SpringBoot won't consider application-*.properties files in src/main/resources directory. The filename you mentioned for --spring.config.location is taken as base filename, in your case test. So, it will only load test.properties file from that path you provided as default profile.
If you want to enable certain profile, say prod, you need to create file C:/external_props/application-prod.properties and enable prod profile using --spring.profiles.active=prod.
Spring will automatically look for some property file in a specific location.
From where you execute the jar file, Spring will look in that directory for a property file called application.properties
An other way is to put a config directory in the directory you execute the jar from and put the application properties in there.
There is one more option and that is the -Dspring.profiles.active={profiles} parameter.
Spring will then look in the directory or config directory to application-{profile}.properties
Reference:
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html
Also i think you use the
--spring.config.location=file:///C:/external_props/test.properties
is not used correctly for a windows based file path.
Windows uses the \ instead of the /.

How to get maven repo location in pom file

I have a maven goal which will execute a groovy file. This groovy file uses a path which is like below
System.getProperty("user.home");
This root path is used to build the another path which points to a jar file inside the local repository.
Unfortunately, I don't have permissions in C drive and I am using D drive. So my repository is also in D drive.
Because of this my build failed. To pass my build I am passing a command line arguments to maven like below
mvn clean install -Duser.home=D:\users\krishna
I want to know if there is a pom variable/place-holder something like {m2RepoHome} so that I can use the same variable in my groovy file.
Thanks in advance
Maven provides a convenient place-holder settings.X where X is any element in settings.xml file.
I used ${settings.localRepository} and it worked.
Properties section in https://maven.apache.org/settings.html explains how to use it.

Spring boot running a fully executable JAR and specify -D properties

The Spring Boot Maven and Gradle plugins can now generate full executable archives for Linux/Unix operating systems.Running a fully executable JAR is as easy as typing:
$ ./myapp.jar
My question is in this case how to set -D properties, e.g.
-Dspring.profiles.active=test
In addition, if server does not install jdk , could this fully executable jar still run?
There are two ways to configure properties like that:
1:
By specifying them in a separate configuration file. Spring Boot will look for a file named like JARfilename.conf which should be stored in the same folder like the JAR file. There you can add the environment variable JAVA_OPTS:
JAVA_OPTS="-Dpropertykey=propvalue"
2:
Or you can just specify the value for the environment variable in the shell before you execute the application:
JAVA_OPTS="-Dpropertykey=propvalue" ./myapp.jar
Have a look at the documentation for the complete list of available variables: http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#deployment-service
Regarding your second question: To execute a JAR, you don't need a JDK, a JRE is sufficient (but you need at least that, if you don't have any java installed on the server, the application won't run).
By default SpringApplication will convert any command line option arguments (starting with ‘--’, e.g. --server.port=9000) to a property and add it to the Spring Environment. As mentioned above, command line properties always take precedence over other property sources.
e.g.
$ java -jar myapp.jar --spring.application.json='{"foo":"bar"}'
please see http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/

Activate a profile based on environment

Here's my scenario:
Maven 2.0.9 is our build system
We install code to multiple environments
All of our environment-specific properties are contained in property files, one for each environment
We currently read these properties into maven using the properties-maven-plugin; this sub-bullet is not a requirement, just our current solution
Goal:
Perform certain parts of the build (ie. plugin executions) only for certain environments
Control which parts are run by setting values in the environment-specific property files
What I've tried so far:
Maven allows plugins executions to be put inside pom profiles, which can be activated by properties; unfortunately these must be system properties - ie. from settings.xml or the command-line, not from properties loaded by the properties-maven-plugin
If possible, we'd like to keep everything encapsulated within the build workspace, which looks something like this:
project
pom.xml
src
...
conf
dev.properties
test.properties
prod.properties
build-scripts
build.groovy <-- the script that wraps maven to do the build
install.groovy <-- ... wraps maven to do the install
Running a build looks like:
cd build-scripts
./build.groovy
./install.groovy -e prod
Is there any possible way to accomplish these goals with the version of maven we are using? If not, is it possible with a newer version of maven?
This isn't possible using just Maven. (See also How to activate profile by means of maven property?) The reason is that profiles are the first thing evaluated before anything else to determine the effective POM.
My suggestion is to write some preprocessor that parses your environment specific property files and converts them to the required system properties before launching Maven. This script can be included in your ~/.mavenrc so that it runs automatically before Maven is launched. Here is an example script that that assumes the properties file is in a fixed location:
properties=`cat /etc/build-env.properties`
while read line; do
MAVEN_OPTS="$MAVEN_OPTS -D$line"
done <<< "$properties"
If the properties file is not fixed, you'll just need to add something to the script to discover the location (assuming it is discoverable).

Resources