Why does profiles defined with modules are executed first -maven? - maven

I have case where i want to download the jar and unpack the jar.
Within that jar i need to invoke the pom.xml from particular location ,
For eg: I downloaded jar and unpacked at
/home/sohanb/admin/target/com/tooling/admin/dockerfiles/cfg
Now at,
/home/sohanb/admin/target/com/tooling/admin/dockerfiles/cfg there is pom.xml which i need to call to build my docker image.
To do this i thought of doing something like this as below,
I have profiles where i want to invoke it sequentially.
unpack-jar
build-tools
Some how my modules profile is always getting called. I am not sure why this is happening or it is default nature of maven to invoke modules profile first.
Here is sample pom
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>smp</artifactId>
<packaging>pom</packaging>
<name>dockerize</name>
<description>docker image creation</description>
<dependencies>
</dependencies>
<properties />
<profiles>
<profile>
<id>unpack_jar</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack</id>
<phase>prepare-package</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.sigma.samp</groupId>
<artifactId>tooling.sigmaadmin</artifactId>
<version>6.0.0-20160405.213109-41</version>
<type>jar</type>
<excludes>**/*.class</excludes>
<outputDirectory>${project.build.directory}</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>build_tools</id>
<modules>
<module>target/com/tooling/admin/dockerfiles/cfg</module>
<module>target/com/tooling/admin/dockerfiles/logs</module>
</modules>
</profile>
</profiles>
mvn install -Punpack_jar -Pbuild_tools
when i execute above command, it always calls the modules profiles giving error,
[ERROR] Child module .... does not exist #
Please suggest.

Related

maven - build once to generate separate war files for separate environment

My pom.xml -
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>test-application</artifactId>
<packaging>war</packaging>
<version>0.2.0</version>
<profiles>
<profile>
<id>local</id>
<activation>
<property>
<name>envType</name>
<value>local</value>
</property>
</activation>
<properties>
<envType>local</envType>
</properties>
</profile>
<profile>
<id>local2</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<envType>local2</envType>
</properties>
</profile>
<profile>
<id>dev</id>
<activation>
<property>
<name>envType</name>
<value>dev</value>
</property>
</activation>
<properties>
<envType>dev</envType>
</properties>
</profile>
<profile>
<id>sit</id>
<activation>
<property>
<name>envType</name>
<value>sit</value>
</property>
</activation>
<properties>
<envType>sit</envType>
</properties>
</profile>
<profile>
<id>uat</id>
<activation>
<property>
<name>envType</name>
<value>uat</value>
</property>
</activation>
<properties>
<envType>uat</envType>
</properties>
</profile>
</profiles>
<build>
<finalName>my-application</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<id>install node and npm</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<nodeVersion>v6.10.0</nodeVersion>
<npmVersion>3.10.10</npmVersion>
</configuration>
</execution>
<execution>
<id>npm install</id>
<goals>
<goal>npm</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<arguments>install</arguments>
</configuration>
</execution>
<execution>
<id>bower install</id>
<goals>
<goal>bower</goal>
</goals>
<configuration>
<arguments>install</arguments>
</configuration>
</execution>
<execution>
<id>gulp build</id>
<goals>
<goal>gulp</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<arguments>optimize --env ${envType}</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Front end maven plugin installs node, all required npm and bower packages and initiates the gulp task for optimizing all the front end code. Gulp places all the front end code into the below -
/src/main/webapp/index.html
/src/main/webapp/js/
etc
web.xml is at -
/src/main/webapp/WEB-INF/web.xml
Command to build the war package for local,SIT,DEV, etc environment -
mvn clean install -DenvType=local
mvn clean install -DenvType=sit
mvn clean install -DenvType=uat
This builds the war file - my-application.war in /target directory.
I need to run the maven command separately each time in order to build the war package for each environment. (because the front-end code uses separate environment variables for each environment).
How can I change the build process so that I need to build only once and maven takes care of running the gulp tasks for each environment (gulp optimize --env ${envType}) one after the other and produces separate war files in the target directory -
my-application-local.war
my-application-sit.war
my-application-uat.war
etc
I need maven to run the gulp task in sequence. I can make each run of gulp to output the front-end code to separate directories. The maven should pick from these separate directories and create separate war files. Not sure whether this is the right approach. Please let me know on this.

Maven module order changes on the same profile

I have project which has 3 pom files, and 2 maven profiles :prod and dev. The problems is that when I run my dev profile with cmd
mvn clean install -Pdev
it builds project with order :
backend,
frontend
When I build project with prod profile, it builds project with order :
frontend
backend
Which is the way i want. But when I run cmd
mvn clean install
It needs to build project with dev profile, and it does it but in this order : 1.frontend, 2.backend.
and this is the problem, it changes module order. Here is the main pom.xml
<groupId>com.main</groupId>
<artifactId>Main</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Main</name>
<description>Main Parent Project</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<modules>
<module>backend</module>
<module>frontend</module>
</modules>
here is backend pom.xml
<artifactId>backend</artifactId>
<name>backend</name>
<description>Backend Project</description>
<parent>
<groupId>com.main</groupId>
<artifactId>Main</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<dependencies>
...
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
<profiles>${spring-profiles}</profiles>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<build.profile.id>dev</build.profile.id>
<profileActive>dev</profileActive>
</properties>
</profile>
<profile>
<id>prod</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<build.profile.id>prod</build.profile.id>
<profileActive>prod</profileActive>
</properties>
<dependencies>
<dependency>
<groupId>com.main</groupId>
<artifactId>frontend</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
</dependencies>
</profile>
</profiles>
and here is frontend pom.xml
<artifactId>frontend</artifactId>
<name>frontend</name>
<description>Frontend Project</description>
<parent>
<groupId>com.main</groupId>
<artifactId>Main</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<build>
<plugins>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.0</version>
<configuration>
<workingDirectory>src/main/webapp</workingDirectory>
<nodeVersion>v6.0.0</nodeVersion>
<npmVersion>2.7.1</npmVersion>
<nodeDownloadRoot>https://nodejs.org/dist/</nodeDownloadRoot>
<npmDownloadRoot>https://registry.npmjs.org/npm/-/</npmDownloadRoot>
</configuration>
<executions>
<execution>
<id>install node and npm</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
<phase>generate-resources</phase>
</execution>
<execution>
<id>npm install</id>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<arguments>install</arguments>
</configuration>
</execution>
<execution>
<id>npm rebuild node-sass</id>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<arguments>rebuild node-sass</arguments>
</configuration>
</execution>
<execution>
<id>bower install</id>
<goals>
<goal>bower</goal>
</goals>
<configuration>
<arguments>install</arguments>
</configuration>
</execution>
<execution>
<id>gulp</id>
<goals>
<goal>gulp</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<arguments>${gulpProfile}</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<build.profile.id>dev</build.profile.id>
<profileActive>dev</profileActive>
<gulpProfile>-d</gulpProfile>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<build.profile.id>prod</build.profile.id>
<profileActive>prod</profileActive>
<gulpProfile>-p</gulpProfile>
</properties>
</profile>
</profiles>
Can you help me and tell why is this happening?
Normally this kind of thing is resolved because your frontend would be dependent upon the jar produced by your backend.
So, even if it does not have a compile time dependency you can still add one at provided scope:
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>backend</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
This will tell the maven reactor that it must always build the backend first, without changing the resulting artifact that is built.
First remove <activation> tag from backend/pom.xml. I hoping that you need keep only one profile active at a time by default and which should be dev
Remove the dependency mentioned in backend/pom.xml from prod profile. Your fronend project should be depend on backend.
Add the backend dependency in frontend/pom.xml as below (not in any specific profile)
Code:
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>backend</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
Now try below commands
mvn clean // (default profile `dev`)
mvn clean --activate-profiles prod // (with override profile `prod`)

Can't bind maven-remote-resources-plugin to both bundle and process goals

I use the maven-remote-resources-plugin to get some resources from an artifact and also need to bundle some resources for use in another project.
I bind the maven-remote-resources-plugin to the bundle goal in the default section (not in a profile). And I bind the maven-remote-resources-plugin to the process goal in a profile.
My problem is that I don't get the shared resources when using the profile (I don't get the target\maven-shared-archive-resources folder).
If I remove the maven-remote-resources-plugin in the default section (the bundle binding) it works fine.
Any suggestions?
Below is my pom:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>
<name>my-app</name>
<dependencies>
<dependency>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app-common</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-remote-resources-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>bundle</goal>
</goals>
</execution>
</executions>
<configuration>
<outputDirectory>${project.build.testOutputDirectory}</outputDirectory>
<resourcesDirectory>${basedir}/src/test/resources</resourcesDirectory>
<includes>
<include>**/*.sql</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>create-test-data</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<testResources>
<testResource>
<directory>${basedir}/src/test/resources</directory>
</testResource>
<testResource>
<directory>${project.build.directory}/maven-shared-archive-resources</directory>
</testResource>
</testResources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-remote-resources-plugin</artifactId>
<version>1.5</version>
<configuration>
<resourceBundles>
<resourceBundle>com.mycompany.app:my-app-common:1.0-SNAPSHOT:test-jar</resourceBundle>
</resourceBundles>
<attachToMain>false</attachToMain>
</configuration>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>process</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
The problem was that the property outputDirectory is defined for both the process and bundle goals and I redefined it in the bundle goal.

Sonar with multi-module maven project and profiles

I have a main project pom.xml which has one module not bound to any profile (module A) and one module bound to profile rest (module module.REST). In jenkins profile, there is a build configuration with a cobertura and sonar plugin.
When Jenkins executes the sonar build, the maven runner only analyses modules which are not bound to profiles and the project module itself. Is there any other way to tell sonar to analyze all modules without specifying those modules again in the profile where the plugin itself is located (in my case this is jenkins profile)? I think cobertura plugin does perform code coverage on ALL modules.
Example:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>group</groupId>
<artifactId>project</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>A</module>
</modules>
<profiles>
<profile>
<id>rest</id>
<modules>
<module>module.REST</module>
</modules>
</profile>
<profile>
<id>jenkins</id>
<activation>
<property>
<name>BUILD_NUMBER</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<aggregate>true</aggregate>
<formats>
<format>xml</format>
</formats>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>cobertura</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>1.0</version>
</plugin>
</plugins>
</build>
<modules>
<module>module.REST</module>
</modules>
</profile>
</profiles>
</project>

Maven not detecting existing file

I'm writing a pom file to conditionally checkout or update a subdirectory from git. However, it always does a clean checkout. I'm doing this to wrap CI scripts around existing projects without having to change them.
Here's the code (slightly censored, and with the update ommitted):
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>standard-php-project</artifactId>
<version>1.0</version>
<properties>
<git.project>Test/Project</git.project>
<git.project.checkout.directory>${basedir}/src/php/main/${git.project}</git.project.checkout.directory>
<git.project.checkout.exists.file>${git.project.checkout.directory}/.git/index</git.project.checkout.exists.file>
</properties>
<scm>
<connection>scm:git:ssh://server/git/${git.project}</connection>
</scm>
<profiles>
<profile>
<id>scm-checkout</id>
<activation>
<file>
<missing>${git.project.checkout.exists.file}</missing>
</file>
</activation>
<build>
<plugins>
<plugin>
<groupId>com.soebes.maven.plugins</groupId>
<artifactId>maven-echo-plugin</artifactId>
<version>0.1</version>
<executions>
<execution>
<id>echo-missing-file</id>
<phase>generate-sources</phase>
<goals>
<goal>echo</goal>
</goals>
<configuration>
<echos>
<echo>Couldn't find ${git.project.checkout.exists.file}</echo>
</echos>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-scm-plugin</artifactId>
<version>1.8.1</version>
<executions>
<execution>
<id>scm-generate-sources-phase</id>
<phase>generate-sources</phase>
<goals>
<goal>checkout</goal>
</goals>
<configuration>
<checkoutDirectory>${git.project.checkout.directory}</checkoutDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<!-- And another profile for when the file exists, not shown for brevity -->
</profiles>
</project>
I've run mvn compile which tells me the file it tests for, done ls -l on the file to verify it exists, and then run again. For some reason, the test fails.
Help!
Profiles are determined prior to applying properties from the pom
<missing>${git.project.checkout.exists.file}</missing> won't work from the value in your pom.xml
If it was provided on commandline then I believe it would work
Otherwise you need to include the value directly
<missing>/src/php/main/Test/Project/.git/index</missing>
See also Maven profile by user defined property

Resources