exclude data.sql from Spring boot jar - maven

I am trying to exclude my data.sql and schema.sql from the Spring boot application jar.
So far I have tried several options but they do not seem to work. This is my POM configuration.
<profiles>
<profile>
<id>dev</id>
<properties>
<activatedProperties>dev</activatedProperties>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>prod</id>
<properties>
<activatedProperties>prod</activatedProperties>
</properties>
<build>
<resources>
<resource>
<filtering>true</filtering>
<directory>src/main/resources</directory>
<excludes>
<exclude>data.sql</exclude>
<exclude>schema.sql</exclude>
</excludes>
</resource>
</resources>
</build>
</profile>
</profiles>

Spring Boot enables it by default and loads SQL from the standard locations schema.sql and data.sql.If you want to disable this you can try,
spring.datasource.initialize=false
in application.properties or if you want to change default scheme or data scripts locations you can do it with,
spring.datasource.schema=
spring.datasource.data=

You can write this annotation on top of your test method
#TestPropertySource(locations = "classpath:application-test.properties")
Your application-test.properties should have something like this
spring.datasource.data=classpath:/database/seed.sql

Related

Spring boot change pom configuration with active profile

I was trying to change configuration of the pom based on the active profile (dev, test, qa, prod). but every time it was calling the default one (prod)
I have given the profile info in VM arguments in intellij
arguments : -Dspring.profiles.active=dev
Decleration (in POM.xml)
<profiles>
<profile>
<id>dev</id>
<properties>
<currentRegion>run build_dev</currentRegion>
</properties>
</profile>
<profile>
<id>test</id>
<properties>
<currentRegion>run build_test</currentRegion>
</properties>
</profile>
<profile>
<id>qa</id>
<properties>
<currentRegion>run build_qa</currentRegion>
</properties>
</profile>
<profile>
<id>prod</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<currentRegion>run build_prod</currentRegion>
</properties>
</profile>
</profiles>
Usage(in POM.xml)
<build>
<plugins>
<plugin>
<executions>
<execution>
<configuration>
<arguments>${currentRegion}</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Every time, this is retuning run build_prod (the default one)
Actually i have combined the spring boot and angular for some testing purpose and i want to run the angular on environment with different environment.ts file , when i hardcode the arguments in pom like run build_dev/test it works file , i want to automate it arguments based on the active profile .
Any Suggestions/Solution is highly appreciated.

Providing external arguments to Maven pom and replace same in application.properties file

I am working on testNg project where I need to provide external arguments to the pom.xml which should get replaced in application.properties file which further will be used in my project.
Could anyone list out the steps and plugins i need to use.
I have resolved the issue. I have added a profile in pom.xml and configuration for property substitution.
<profiles>
<profile>
<id>profile1</id>
<properties>
<url>https://www.bing.com</url>
<search>bitcoin</search>
</properties>
</profile>
</profiles>
<build>
<testOutputDirectory>${basedir}/target/classes</testOutputDirectory>
<filters>
<filter>src/main/resources/runtime.properties</filter>
</filters>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
runtime.properties
url=${url}
search=${search}
To Run the test:
mvn test -Pprofile1 -Durl=https://www.google.com -Dsearch=Blockchain
The value of url and search variable will be replaced in runtime.properties file by the value given in arguments of the above command .
-Durl=https://www.google.com and
-Dsearch=Blockchain

Maven filtering resources

I am running a simple maven project (maven version 3.3.9) with profiles and filtering on resources. It seems like the filtering is done always on the default profile.
There is 2 configuration files in src/main/filters (default) : config-dev.properties and config-prod.properties which contains only one variable
application.env=development
application.env=production
And a resource file in src/main/resources (default) with this content :
We are working on ${application.env}
Command line used is
mvn clean resources:resources -Pprod
The expected output is
We are working on production
But the filtered resource file contains
We are working on development
Maven pom snippet looks like:
<build>
<finalName>test-maven-module</finalName>
<filters>
<filter>src/main/filters/config-${build.profile.id}.properties</filter>
</filters>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
and profiles configuration
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<build.profile.id>dev</build.profile.id>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<build.profile.id>prod</build.profile.id>
</properties>
</profile>
</profiles>
Any suggestion?
I found the solution on the post Eclipse + maven : profile ignored
The issue was with the use of the "refresh using native hooks or polling" option ( preferences > general > workspace > refresh using native hooks ). Unchecking this option resolves the problem.

How to configure maven to use different log4j.properties files in different environments

I want to be able to use different log4j configuration for different environments.
In my development environment, I want to use log4j.properties (A). But when I build in Maven for the production environment, I want to use log4j.properties (B).
Please tell me how to configure this in my pom.xml?
You can use profiles to achieve the desired behavior:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>log4j</id>
<phase>process-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>output_directory</outputDirectory>
<resources>
<resource>${log4j.file}</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<log4j.file>path_to_file_A</log4j.file>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<log4j.file>path_to_file_B</log4j.file>
</properties>
</profile>
</profiles>
1. in your project add 3 folders :
Your Project\src\main\resources\
\A > log4j.properties
\B > log4j.properties
\Default > log4j.properties
2. in pom.xml
<properties>
<param>Default</param>
</properties>
<build>
<resources>
<resource>
<directory>src/main/resources/${param}</directory>
</resource>
</resources>
</build>
3.
- if : mvn clean install : classpath => log4j.properties(Default)
- if : mvn clean install -Dparam=A : classpath => log4j.properties(A)
- if : mvn clean install -Dparam=B : classpath => log4j.properties(B)
> much better than using profiles is more extensible without touching the pom
You don't need the maven-resources-plugin if you have a simple environment.
In this example, log4j.properties B is the file you use for production and is in the directory src/main/java and log4j.properties A is the file you use for development and is in the directory /Users/junger/.m2/.
In your pom.xml:
<properties>
<log4j.properties.directory>src/main/java</log4j.properties.directory>
</properties>
<build>
<resources>
<resource>
<directory>${log4j.properties.directory}</directory>
<includes>
<include>log4j.properties</include>
</includes>
</resource>
</resources>
</build>
Now, in your /Users/junger/.m2/settings.xml (create one if it doesn't exist):
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<log4j.properties.directory>/Users/devuser/.m2/</log4j.properties.directory>
</properties>
</profile>
</profile>
By using this method, each developer can have a different log4j.properties directory and you keep your pom.xml clean.
Simplest way for me,
Define a system variable ENV and set its value _dev for your development env.
Where you refer this file use like this log4j${ENV}.properties
So,
In production it simply use log4j.xml and for your dev log4j_dev.xml
In order to prevent problems it would be better to create also ENV variable for production as _pro so for production log4j_pro.xml, for dev log4j_dev.xml will be used.
I believe that relying on different files than copying resource is better practice.
There is a very simple solution good for small projects with jar packaging (I haven't tested it on war packaged projects). The only disadvantage is that you have to duplicate all resources, but if your only resource is log4j.properties this is not a problem.
If you have a directory tree like this:
...
You should have the following pom:
<build>
<finalName>${project.artifactId}</finalName>
<sourceDirectory>src/</sourceDirectory>
<resources>
<resource>
<directory>${resources.path}</directory>
</resource>
</resources>
</build>
<profiles>
<profile>
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<resources.path>resources/prod</resources.path>
</properties>
</profile>
<profile>
<id>dev</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<resources.path>resources/dev</resources.path>
</properties>
</profile>
</profiles>
Then when you use dev profile log4j.properties from resources/dev is used. When you use any other profile or no profile at all then log4j.properties from resources/prod is used. So your *.jar should look like this:
Of course if you have different resources location, for example main/java/resources/..., you should specify it instead of resources/...
To some extent you can reference environment variables inside a log4j.properties to add environment dependent behavior.
e.g.
log4j.rootLogger=${rootLoggerLevel}, ${appender}

maven super pom's profile properties inheritance at child poms

at my project there is 2 profiles and each profile has one property.
But I could not use master's properties at child's resources.
Here is described clearly but it seems that there is only one pom file and the sample shown at there is not an multi-module maven project.
All I want to do is use this properties at spring level like changing the location of properties file.
<profile>
<id>p1</id>
<properties>
<properties.location>file:/apps-core1.properties</properties.location>
</properties>
</profile>
<profile>
<profile>
<id>p2</id>
<properties>
<properties.location>file:/apps-core2.properties</properties.location>
</properties>
</profile>
<profile>
and I want to use "properties.location" at every pom file I had, either main-resources or test-resources.
here is the spring usage
<context:property-placeholder location="\${properties.location}" />
i got it working with a multi-module project with:
parent pom with <modules /> config and your profiles
module pom with following config
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
see maven resources and filtering

Resources