Maven Profile for testing - java

I am developing a java web application (No Spring).I wanted to use separate db for production and testing.I have two files in src/main/resources - env.properties and env.test.properties.
I have defined the profile in pom.xml as mentioned in https://maven.apache.org/guides/mini/guide-building-for-different-environments.html.
<profiles>
<profile>
<id>test</id>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<delete file="${project.build.outputDirectory}/environment.properties"/>
<copy file="src/main/resources/environment.test.properties"
tofile="${project.build.outputDirectory}/environment.properties"/>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>test</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
However, when I run test by maven test -Ptest, I see that my test is getting executed with the db from env.properties and then after completion of test , the profile switching happens.
I am also having a jebkins pipeline which builds tests and deploys.
Am I missing something here ? What is the correct way to read the properties from env.test.properties(activate the profile and run test) ?
Thanks a lot.

You're doing this the hard way.
Get rid of the profiles and move the file from src/main/resources/environment.test.properties to src/test/resources/environment.properties
Resources in src/test/resources/ will be found and loaded before those in src/main/resources when unit tests are being executed.

Related

Building with JIB give Multiple valid main classes were found even though the mainClass is define

When building my service project with jib command mvn clean compile jib:build it's give the following error:
Failed to execute goal
com.google.cloud.tools:jib-maven-plugin:1.0.2:build
(build-image-and-tag-image) on project my-service: Multiple valid
main classes were found: com.myservice.MyServiceApplication,
io.swagger.Swagger2SpringBoot, perhaps you should add a mainClass
configuration to jib-maven-plugin -> [Help 1]
However I have set the main classes for spring-boot
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.myservice.MyServiceApplication</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
It's still doesn't work.
I've tried to add it to the jib config to:
<plugins>
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<configuration>
<container>
<mainClass>com.myservice.MyServiceApplication</mainClass>
</container>
</configuration>
<executions>
<execution>
<id>build-image-and-tag-image</id>
<phase>package</phase>
<goals>
<goal>dockerBuild</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
It's still doesn't work.
Any other way to force jib to ignore the other class and use com.myservice.MyServiceApplication instead.
Note: mvn clean install work fine and I have no problem using it has a stand alone spring boot app.
The main class need to be set in the < plugins > define in < build > of the pom.xml file.
It would look like this to fix the problem:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.myservice.MyServiceApplication</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<configuration>
<container>
<mainClass>com.myservice.MyServiceApplication</mainClass>
<ports>
<port>8080</port>
</ports>
<environment>
<application.title>${project.name}</application.title>
<application.version>${project.version}</application.version>
</environment>
<jvmFlags>
<jvmFlag>-javaagent:/usr/local/newrelic/newrelic.jar</jvmFlag>
</jvmFlags>
</container>
</configuration>
</plugin>
.... (more plugin)
</plugins>
</build>

Unit tests getting executed during integration test phase even after excluding them

I have a a unit test (ProductDaoTest.java) and an integration test (ProductDaoIT.java) in my maven application.
I would like to execute only the integration test during the mvn verify command call but the unit test also gets executed even after excluding it using the <exclude> tag in the maven-failsafe-plugin configuration.
How can I fix this problem?
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<excludes>
<exclude>**/*Test.java</exclude>
</excludes>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
Updated POM (with solution):
<!-- For skipping unit tests execution during execution of IT's -->
<profiles>
<profile>
<id>integration-test</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<!-- Skips UTs -->
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
<!-- Binding the verify goal with IT -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.19.1</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>5000</port>
<path>${project.artifactId}</path>
</configuration>
<executions>
<execution>
<id>start-tomcat</id>
<phase>pre-integration-test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<fork>true</fork>
</configuration>
</execution>
<execution>
<id>stop-tomcat</id>
<phase>post-integration-test</phase>
<goals>
<goal>shutdown</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
mvn clean install - Runs only unit tests by default
mvn clean install -Pintegration-test - Runs only integration tests by default
In Maven, test step is before verify step in the lifecycle.
So it you don't skip this step, it is bound to execute.
If you want to skip test , either use -Dmaven.test.skip=tr‌​ue as khmarbaise suggested, either create a dedicated Maven profile for IT where you will ignore unit-tests in this way :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
Generally, you create a Maven profile for integration tests, so if it is the case, gathering all the configuration in a place is better that scattering it.

Binding to lifecycle in maven does not work on failsafe and integration-test

When trying to get failsafe bound to the lifecycle, nothing is executed at all. I have read this guide and this related question, and according to this information, it should be possible to make maven execute an the goal integration-test of failsafe in the integration-test, when I specify it in the build/pluginManagement/plugins-section in the pom.xml like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.17</version>
<configuration>
<includes>
<include>**/*IT</include>
</includes>
</configuration>
<executions>
<execution>
<id>failsafe-integration-tests</id>
<phase>integration-test</phase>
<goals>
<goal>integration-test</goal>
</goals>
</execution>
<execution>
<id>failsafe-verify</id>
<phase>verify</phase>
<goals>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
Unfortunately, this does not force maven to run failsafe:integration-test at all (neither with mvn integration-test nor mvn verify)
But if I try to use failsafe with the plugin-specification like this (from here with added configuration):
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.17</version>
<executions>
<execution>
<id>integration-test</id>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<phase>integration-test</phase>
<configuration>
<includes>
<include>**/*IT</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
At least maven compile failsafe:integration-test runs. But unfortunately, this does not call pre- and post-integration-test. I am struggeling for this for a while now, and have no clue - it should be bound as it is.
Does anybody know why this happens, or how I can fix it?
The thing you did is to define it only in pluginManagement but you have to run it really like this. The definition in pluginManagement is good practice to pin the version of the plugin.
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
</project>
Apart from that it's not necessary to give include rules for the maven-failsafe-plugin cause it has already defaults defined so no need for that.

Maven Profiles not working and failing tests

I'm starting to use profiles with Maven in order to build multi-environment jars.
I followed the official docs to do this.
First, validation question:
I have read that you should always have one package generated by Maven project, but I only want to generate multi-environment jars (i.e.: only changing a properties file for each jar). I don't consider necessary to generate multiple projects to do this, am I right?
Now the explanation:
I have an app that reads a file and applies a certain set of reviews before going to insert some of the information to the database. I want to test that this validations are ok, and that I get correct results whether or not it fails later at the database. So in this app I use a dynamically set DAO. This is: my app gets the DAO class from the config.properties file at runtime. I created some facade DAOs that will simulate the real DAO (for example: DAOApproveAll, that will simulate that all the transactions in the database went ok).
In the unit testing I load config.properties to change (and later revert the change) of the value of the param daoimplclass that is the one that holds the class. For example:
Properties prop = Configurator.getProperties("config");
final String DAODEFAULT = prop.getProperty("daoimplclass");
final static String DAOAPPROVEALL = "com.package.dao.DAOAllApproved";
public void testAllAproved() {
try {
Processor processor = Processor.getInstance();
prop.setProperty("daoimplclass", DAOAPPROVEALL);
...
}
finally{prop.setProperty("daoimplclass", DAODEFAULT);}
I do many tests (using different DAO facades) in order to validate what would happen if different results occur in the database.
Now, I changed my config.properties to 2 files: config-dev.properties and config-prod.properties. And changed the original pom.xml to use profiles like this:
<profiles>
<profile>
<id>dev</id>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<delete file="${project.build.outputDirectory}/config.properties"/>
<copy file="src/main/resources/config-dev.properties"
tofile="${project.build.outputDirectory}/config.properties"/>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>dev</classifier>
<source>1.6</source>
<target>1.6</target>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>prod</id>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<delete file="${project.build.outputDirectory}/config.properties"/>
<copy file="src/main/resources/config-prod.properties"
tofile="${project.build.outputDirectory}/config.properties"/>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>prod</classifier>
<source>1.6</source>
<target>1.6</target>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
Now when I do "Clean and build" in Netbeans I get errors executing the tests because it can't find the config.properties. Of course I create a third config.properties (the other two will be with the -dev and -prod) ant it compiles but doesn't generate 2 jars but only one.
My formal questions:
What am I doing wrong with the profiles?
How can I allow that the tests run Ok and only for dev?
To active the profile via Netbeans, you may try the following task: -
Right click at your project and select properties from the context menu.
Select the Configurations from Categories on the left panel.
At the right panel you will see the various profiles defined in your pom. You can Activate them by selecting them and click Activate button or you can create the new on by clicking the Add button.
I hope this may help.

Two build profiles are active, but Maven executes antrun plugin tasks in one profile only

Our application can be built for several application servers, and used in several environments.
Type of application server and target environment should be specified using Maven profiles. One and only one of each profile type should be present when compiling the code. All profiles cause execution of one or several mavent-antrun-plugin copy tasks in order to include correct setting files to the generated JAR.
Below is part of the pom.xml file. Part of AS profile "oracle" is included, as well as part of environment profile "development". The purpose is, that in order to create JAR which can be deployed to Oracle AS in development environment, the code is compiled using two profile switches mvn -P oracle,development
AS profiles have also other tasks (not shown below) which have to be executed before the environment profile tasks take place (that's the reason profiles have different phases).
My issue is, that Maven refuses to execute tasks in both of the selected profiles.
mvn -Poracle works just as it's supposed. So does mvn -Pdevelopment. However, mvn -Poracle,development results in execution of only the tasks in oracle profile. If all the tasks in oracle profile's antrun plugin are commented out, then the tasks in development profile do get executed.
My questions are:
* Why does Maven refuse to execute ant tasks in both of these profiles?
* Is there a way to fix this?
Combining the profiles (oracle-development, jboss-development etc.) is not an option for us, because this module is part of a bigger project and would require modifications to several other projects.
We use currently Maven 2.2.0.
<profile>
<id>oracle</id>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<copy .../>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
...jboss, glassfish profiles...
<profile>
<id>development</id>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<copy .../>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
...production, test profiles...
Add a unique execution id to each <execution>:
<profile>
<id>oracle</id>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>execution1</id>
<phase>validate</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<echo>ORACLE</echo>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>development</id>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>execution2</id>
<phase>compile</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<echo>DEV</echo>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
Tested working solution :) Without the <id> element, I guess that one <execution> overrides the other.

Categories

Resources