want to run exec-maven-plugin when spring-boot running - maven

My Spring-boot project structure is below
-Project
- src
- main
- java
- resources
- webapp
- test
- frontend
- src
- static
- config
- package.json
- (after "npm install") node_modules
- (after "npm run build") dist
what I want to do is
when a project is installed, run "npm install"
when "spring-boot:run" runs, run "npm run build" and moves contents in front/dist to /main/webapp
here is my pom.xml
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<id>exec-npm-install</id>
<phase>generate-sources</phase>
<configuration>
<executable>npm</executable>
<workingDirectory>./frontend</workingDirectory>
<arguments>
<argument>install</argument>
</arguments>
</configuration>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
I don't know how can I trigger exec-npm-install exection
with Eclipse maven build, I tried generate-sources, spring-boot:run, install and compile, package but it didn't run.
and I want to know what command should I put, to move dist when "spring-boot:run"

Few things -
As pointed by #khmarbaise as well, you should move your <plugins> tree out of the <pluginManagement> and also use <version> for the plugins you are using.
I don't know how can I trigger exec-npm-install exection
Since the execution is tied to the generate-sources phase of the execution. If you try and execute mvn generate-sources from command line on the project directory, you shall get the execution triggered. Also executing mvn test, mvn install, mvn package should do the needful. Take a look at the Maven - Lifecycle Reference for this.
I want to know what command should I put, to move dist when
"spring-boot:run"
If you want to copy the resources to the /webapp directory, you shall take a look at maven-resources-plugin and change its phase accordingly.

Related

Is there any shortcut/command available to skip karma tests? like -DskipTests for Maven

I have created Maven Web application and I generally use
mvn clean install
So it execute npm install command as its one of the execution goal and then it run karma tests
So my question is, is there any shortcut or command available to skip karma tests conditionally?
Like we have -DskipTests for Maven project to skip tests.
Off course we can simply remove the npm run test from the package.json file but I want to skip tests using command.
pom.xml
<build>
<plugins>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>npm install</id>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<workingDirectory>web/app</workingDirectory>
<installDirectory>build</installDirectory>
<arguments>install
--registry=${npm.registry}
</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Since I am using the frontend-maven-plugin I had to add below execution to plugin.
<executions>
<execution>
<id>javascript tests</id>
<goals>
<goal>karma</goal>
</goals>
<phase>test</phase>
</execution>
</executions>
After that, just using -DskipTest build argument able to skip karma tests.
mvn clean install -DskipTests
You can define a system property -Dmaven.test.skip=true to skip the unit test.
mvn package -Dmaven.test.skip=true
Define properties in pom.xml
<properties>
<maven.test.skip>true</maven.test.skip>
</properties>
Use -DskipTests in surefire plugin
mvn package -DskipTests
Define surefire plugin in pox.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M1</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
use
mvn clean install -DskipTests
-DskipTests will skip the Karma tests. Please refer to the following snippet available at https://github.com/eirslett/frontend-maven-plugin
"Skipping tests: If you run maven with the -DskipTests flag, karma tests will be skipped."
So, Front end test cases are getting executed under "frontend-maven-plugin" which seems to recognize only -DskipTests to skip test cases execution unlike "maven-surefire-plugin" which recognizes both "-DskipTests" as well as "-Dmaven.test.skip=true" command parameters. So, if we use -DskipTests rather -Dmaven.test.skip=true command parameters, both backend as well as front end test cases get skipped.
This is what has been tested locally using -DskipTests
Skip FE Tests

Watch SCSS with a Spring-boot application

I have a Spring-boot application, in which I'd like to use SCSS to improve my CSS. I have successfully configured my pom for my SCSSfile to be compiled into a valid CSS during maven compilation. I now would like to have a hot deploy of the SCSS. Any time the SCSS is changed, I'd like it to be recompiled and redeployed in my launched spring-boot app, so that I just have to refresh my browser to see the changes.
My goal is just having to execute the maven command:
mvn install spring-boot:run sass:watch
for it to work. Is it possible?
I have not yet managed to make the sass:watch work when run from another terminal, but I assume this is just a pom configuration issue.
EDIT: My application is built as a fat (or uber) jar
Because I had the same issue:
You cannot run spring-boot:run sass:watch as a single command.
Maven is not (really) multi-threaded and the tasks are executed as a sequence. Since both tasks are blocking, the second one will never be executed.
So you need to run two commands from two consoles
mvn spring-boot:run
mvn sass:watch
the mvn install is not really needed. If you still want it, put it in the first command.
You can use the exec-maven-plugin to execute the sass:watch maven goal asynchronously:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
<configuration>
<executable>mvn</executable>
<async>true</async>
<arguments>
<argument>sass:watch</argument>
</arguments>
</configuration>
</plugin>
To execute:
mvn exec:exec spring-boot:run
Or you can bind the exec goal to a particular phase (e.g. validate) and/or wrap this in a profile so it only executes when you want it:
mvn spring-boot:run -P sass
<profile>
<id>sass</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
<configuration>
<executable>mvn</executable>
<async>true</async>
<arguments>
<argument>sass:watch</argument>
</arguments>
</configuration>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>

How do I force Maven to use maven-resources-plugin version 2.6?

When I run $mvn -q clean install, I see a bunch of [debug] execute contextualize statements printed to the console.
After doing some searching, I determined that this is a problem with version 2.5 of the Maven Resources Plugin. This problem has been fixed in version 2.6, but I cant figure out how to get my project to use it. (http://jira.codehaus.org/browse/MRESOURCES-140)
None of my projects have this plugin listed in their poms, so I am not sure where Maven is getting it from, maybe it is used in one of the other Apache dependencies or something? (I don't really even understand what this plugin does or how plugins in Maven are used in general)
I tried adding the following to my root pom:
<build>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
</plugin>
</plugins>
</build>
However, this doesn't seem to solve the problem. I still see the [debug] execute contextualize output and when I run $mvn help:effective-pom, the output still shows:
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>default-resources</id>
<phase>process-resources</phase>
<goals>
<goal>resources</goal>
</goals>
</execution>
<execution>
<id>default-testResources</id>
<phase>process-test-resources</phase>
<goals>
<goal>testResources</goal>
</goals>
</execution>
</executions>
</plugin>
How can I force Maven to use the newer version of this plugin so that I can suppress the annoying [debug] execute contextualize outputs?
Try do add the groupId of the plugin in your build settings :
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
</plugin>
</plugins>
</build>
The maven-resources-plugin is bound to the lifecycle by default for jars, wars, & ears. Adding a definition to your corporate root POM as you did should work to update the version used. Things to check:
Is the inheriting project specifying the version of the corporate parent POM that includes the change?
Did you run mvn clean install on the root POM prior to running the project build?
If the answer is "yes" and "yes", try cleaning out your local artifact repo, then run mvn clean install for the root, and try the build again.

How can I skip tests in maven install goal, while running them in maven test goal?

I have a multi-module maven project with both integration and unit tests in the same folder (src/test/java). Integration tests are marked with #Category(IntegrationTest.class). I want to end up with the following setup:
If I run mvn install, I want all tests to compile, but I do not want to execute any.
If I run mvn test, I want all tests to compile, but execute only unit tests.
If I run mvn integration-test, I want to compile and execute all tests.
The important point is, I want this configured in the pom.xml without any extra commandline arguments.
Currently I came up with the following setup in my parent pom.xml, where the only problem is #1, where all tests are executed:
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${project.java.version}</source>
<target>${project.java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.14.1</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
<version>2.14.1</version>
</dependency>
</dependencies>
<configuration>
<includes>
<include>**/*.class</include>
</includes>
<excludedGroups>cz.cuni.xrg.intlib.commons.IntegrationTest</excludedGroups>
</configuration>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.14.1</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
<version>2.14.1</version>
</dependency>
</dependencies>
<configuration>
<groups>cz.cuni.xrg.intlib.commons.IntegrationTest</groups>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<includes>
<include>**/*.class</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
All child modules have the following plugin configuration in their pom.xml, which I believe should inherit from the parent pom:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
</plugins>
</build>
I tried using <skipTests>true</skipTests>, but it disables test execution for all goals, which is not what I want (violates #2 and #3). It is also quite weird, that mvn test honors the skipTests=true option...why would I want to run it in the first place??
After hours of googling and trying different combinations, I am hesitant whether it is even possible to not run tests in mvn install, while at the same time run them in mvn test. I hope someone proves this wrong. ;)
I am also willing to accept a solution, where mvn install would execute only unit tests, but I don't think it makes much difference.
It sounds like you didn't understand the concept of the build life-cycle in Maven. If you run mvn install all life-cycle phases (including the install phase itself) run before the install phase. This means running the following phases:
validate
initialize
generate-sources
process-sources
generate-resources
process-resources
compile
process-classes
generate-test-sources
process-test-sources
generate-test-resources
process-test-resources
test-compile
process-test-classes
test
prepare-package
package
pre-integration-test
integration-test
post-integration-test
verify
install
which means in other words the test as well as integration-test life-cycle phases are included. So without any supplemental information it's not possible to change the behaviour as you wish it.
It could be achieved by using a profile in Maven:
<project>
[...]
<profiles>
<profile>
<id>no-unit-tests</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
[...]
</project>
So your first requirement:
If I run mvn install, I want all tests to compile, but I do not want to execute any.
can be achieved by using the following:
mvn -Pno-unit-test test
If I run mvn test, I want all tests to compile, but execute only unit tests.
This can simply achieved by using the plain call:
mvn test
cause the integration tests phase is not run (see the build life cycle).
If I run mvn integration-test, I want to compile and execute all tests.
This means running the default which includes running the test phase which will run the unit tests (maven-surefire-plugin) and furthermore running the integration test which are handled by the maven-failsafe-plugin. But you should be aware that if you like to call the integration tests you should using the following command:
mvn verify
instead, cause you missed the post-integration-test phase in your previous call.
Apart from the above you should follow the naming conventions for unit and integration tests where unit tests should be named like the following:
<includes>
<include>**/*Test*.java</include>
<include>**/*Test.java</include>
<include>**/*TestCase.java</include>
</includes>
and integration tests should be named like the following:
<includes>
<include>**/IT*.java</include>
<include>**/*IT.java</include>
<include>**/*ITCase.java</include>
</includes>
I hope you have configured the maven-failsafe-plugin like the following which is needed to bound the maven-failsafe-plugin to the correct life-cycle-phases:
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.15</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
</project>
as you correctly did, but you should be aware that the include tags work on the source code (.java) and not on the compiled names (.class). I wouldn't use the Category annotation, just simply using the naming conventions makes the pom simpler and shorter.
According to the Failsafe Plugin documentation
mvn install -DskipITs
is what you want.
What OP stated in his question:
If I run mvn install, I want all tests to compile, but I do not want
to execute any.
If I run mvn test, I want all tests to compile, but execute only unit tests.
If I run mvn integration-test, I want to compile and execute all tests.
is perfectly valid and extremely easy to achieve.
EDIT: except first condition, which acts againts the maven nature. The best way here would be simply do mvn install -DskipTests
All you need is following snippet in pom.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.17</version>
<executions>
<execution>
<id>integration-tests</id>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
and to stick to the maven naming conventions for unit and integration tests (as #khmarbaise already stated). So generally name you integration tests with IT suffix (for example MyIntegrationTestIT.java) and let maven-failsafe do its job.
In that way, you do not even need JUnit categories (although sometimes they can be quite useful).
That's it :)
mvn test executes only unit tests
mvn integration-test executes all tests
mvn failsafe:integration-test runs only integration tests
mvn clean verify when you want to be sure, that whole project just works
Some personal advices
Keeping integration tests separately from unit tests lets you easily run within your IDE all tests in some package. Usually additional directory called test-integration (or integrationtest) is used for this purpose.
This is also easy to achieve with maven:
<plugin>
<!-- adding second test source directory (just for integration tests) -->
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.9.1</version>
<executions>
<execution>
<id>add-integration-test-source</id>
<phase>generate-test-sources</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>src/test-integration/java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
And then move your integration tests to that directory. It should look like:
src
main
test
test-integration
Integration tests usually needs more memory:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
...
<configuration>
<argLine>-Xmx512m -XX:MaxPermSize=256m</argLine>
</configuration>
</plugin>
This post explains how to skip integration tests, no matter what plugin you are using for these tests.
Basically, what you do is define a profile and put all your integration-tests related xml code inside that profile. Than you activate it when a property -DskipIntegrationTests is missing.
You can do the same for unit tests: write a profile and activate it when -DskipUnitTests is missing.
Then, you could do:
mvn install -DskipIntegrationTests -DskipUnitTests # (runs install without any tests)
mvn test # (runs unit tests)
mvn post-integration-test # (runs all tests)
The maven-failsafe-plugin docs has a section titled "Skipping by Default."
Sadly, the steps that page describes don't work as written. However, a slight change to those steps will make it work:
In the properties section of pom.xml, add this:
<skipITs>true</skipITs>
Then add the skipTests property to the plugin section of maven-failsafe-plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<skipTests>${skipITs}</skipTests>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
So now, an mvn install by default will execute unit tests, but not integration tests.
But an mvn install -DskipITs=false will execute both unit tests and integration tests.
Footnote: Bad documentation played a big part on why Maven was so disliked for such a long time.
mvn test-compile does exactly what you are looking for. You can simply replace mvn install with mvn test-compile and you are done. No need to customise the pom file or anything. The below linked question is similar around #1:
Maven - How to compile tests without running them ?
mvn test-compile should be accepted as the best answer as Maven supports exactly what you want to do natively and without any magic. You would end up with this:
If I run mvn test-compile, I want all tests to compile, but I do not want to execute any.
If I run mvn test, I want all tests to compile, but execute only unit tests.
If I run mvn integration-test, I want to compile and execute all tests.
Don't specify the execution step(s) in the configuration of the failsafe plugin. E.g.
<plugins>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.0.0-M3</version>
</plugin>
</plugins>
Now, you specifically need to call mvn failsafe:integration-test to run the integration tests; they will be skipped in other mvn targets.

maven executing profile independent of phase

I have a profile which I want to execute after install phase is complete for all the modules.
say I have
<modules>
<a>
<b>
<c>
</modules>
Then I have defined a profile whose id is generate-reports.
<profile>
<id>generate-reports</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<id>run-cmd</id>
<!--DO NOT BIND WITH PHASE-->
<phase>install</phase>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>executable-name</executable>
<arguments>
<argument>-o</argument>
<argument>output.txt</argument>
</arguments>
</configuration>
</plugin>
</plugins>
</build>
</profile>
This profile is a report generate profile which will go inside each module and generate report there. but problem is if I want to generate report once the test cases for each reports are run. this profile should not be invoked for each module while installation. Only after complete installation it should be invoked.
In other words I am looking for something like
mvn install generate-reports
or even
'mvn generate-reports' (assuming I already run mvn install individually).
In all I do not want to bind profile with phase and want to run profile independent of phase.
Is there any plugin to accomplish this ?
You can start any goal just by calling the goals name, e.g.:
mvn help:effective-pom
in your case, this should be:
mvn exec:exec
And as described >here< you can also do this:
mvn clean install exec:exec
This should finish a full "install" before invoking your report plugin.

Resources