Why system.out.println changes reflects without building jar? - java

I am using maven as a build tool and running some integration-test cases. I logged some statements in my test case using System.out.println() and did a mvn verify and even i didn't clean install/package the jar.The changes were reflecting for logging statements. Did the mvn verify implicitly does a install/package or it doesn't require building the jar. If any one have any idea please share.

The maven goal verify comes after package see: Maven Build Lifecycle so the packaging occurs.

See mvn build lifecycle for order (all above are used) https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html :
validate - validate the project is correct and all necessary information is available
compile - compile the source code of the project
test - test the compiled source code using a suitable unit testing framework. These tests should not require the code be packaged or deployed
package - take the compiled code and package it in its distributable format, such as a JAR.
integration-test - process and deploy the package if necessary into an environment where integration tests can be run
verify - run any checks to verify the package is valid and meets quality criteria
install - install the package into the local repository, for use as a dependency in other projects locally
deploy - done in an integration or release environment, copies the final package to the remote repository for sharing with other developers and projects.

Related

JaCoCo plugin gives different coverage

I'm using the JaCoCo Maven plugin and agent to measure and retrieve the code coverage data of an application which is tested nightly.
This is the schema of the architecture:
My Maven project is configured with the JMeter Maven plugin to execute some API tests during the Maven verify phase.
The Maven command executed by the Jenkins server is the following
mvn verify org.jacoco:jacoco-maven-plugin:0.7.8:dump sonar:sonar -Djacoco.address=TEST_SERVER -Djacoco.destFile=/proj/coverage-reports/jacoco-it.exec -Dsonar.projectKey=sonar_test -Dsonar.projectName=sonar_test -Dsonar.branch=sonar_test -Dsonar.jacoco.itReportPath=/proj/coverage-reports/jacoco-it.exec -Dsonar.java.coveragePlugin=jacoco -Dsonar.language=java
As you can see first the tests are executed through the verify phase, then the jacoco:dump goal retrieves the coverage data from the test server (I configured the server to run the JaCoCo agent) and at last the data is uploaded to my Sonar server.
The "strange" behaviour I'm having is that if I run this command on my computer and then on Jenkins (configuring the Jenkins project accordingly) in the SonarQube page I get different coverage results. Moreover, if I configure the Jenkins project and then I simply COPY it creating a new (but equivalent) Jenkins project, the results are different.
I tried different configurations and cases, but I cannot understand what the problem can be. Am I not considering some JaCoCo constraints (e.g. someting related to the Jenkins project name)?
As said in the question comments, the artifact deployed on the test server and the one compiled during the verify phase on which the report is generated must be exactly the same, so it is not enough that the code is the same.
To solve my problem I had to implement this workflow with Jenkins:
Do a mvn package on the project
Deploy the generated WAR on the remote server using Ansible (we already use Ansible for nightly deploys and other tasks on remote machines)
Run the remote tests without recompiling the wars. To do this I had to add the Maven flag -Dmaven.compiler.useIncrementalCompilation=false (thanks to this and this for the hints) in order to not re-compile the artifacts during the verify phase
Retrieve (dump) the JaCoCo coverage data
So the Maven command described in the question has been split in two commands: the one which creates the package and the one which performs the tests and retrieves the JaCoCo data without recompiling the artifacts.

How to do a deployment pipeline with Maven

We want to accelerate our build pipeline for a multi-module Java web application, which roughly consists of
compile/code analysis
unit tests
integration tests
GUI tests
At the moment each of these build steps starts from scratch, compiling and building again and again, which costs time and means that we do not deploy the actual files to production that have gone through the tests. Is it possible to get Maven to not recompile everything on subsequent steps but instead run the tests against the previously compiled classes?
We are using Maven3 to manage our dependencies and Teamcity as a build server (7 at the moment, planning to upgrade to 8 soon). I have tried to set up a build chain, doing a
mvn clean install
on the first step and then exporting all the */target/ folders to the following builds. Then ideally I would only do a
mvn test
mvn integration-test
Unfortunately I have not been able to persuade Maven to do this properly. Either it compiles the classes again or produces errors.
Has anyone successfully done this kind of setup and has any pointers for me? Is this possible with Maven and is this even the right way to do things?

What is the process with Maven project to compile and test the code?

I have maven project imported in my eclipse. Now I need to start making changes to it and test it with the integration test (out of App server). Currently, the integration test is run out of server using openEJB container.
My basic question is, what is the regular process to compile, build and test with Maven?
mvn install
Maven -> Update Project.
Run my test from command line
Is it how it is done? I am specifically interested in knowing mvn install commands.
So should I do all three steps before I can test it?
Example: I just wanted to print something and see what is the output. For this I guess I need to do all these steps?
The openEJB container needs classes so it can load them.
There is a wonderful Maven quick-reference sheet at http://maven.apache.org/guides/MavenQuickReferenceCard.pdf
First, you should be aware that unit tests and integration tests are separate and are run from separate plugins and at separate parts of the maven lifecycles. Unit tests are run with surefire and integration tests are run with failsafe.
You want to run integration tests and the failsafe documentation says:
NOTE: when running integration tests, you should invoke maven with the (shorter to type too)
mvn verify
rather than trying to invoke the integration-test phase directly...
This is the best way to run integration tests directly in maven. It will run all the preceding steps necessary (eg: compile) in order to run the integration tests. It won't waste time doing an install because install happens immediately after verify.
But if you're running the tests locally, it may be a better idea to run your integration tests directly in your IDE. That will give you a much faster feedback loop.
If it is Eclipse project the most reasonable thing is to do everything not from command line but from Eclipse. Assuming you have m2e plugin installed, go to your_project->run as->Maven test and run it.
You dont need neither install nor package phase to run Maven tests, package will create a jar which is not needed for tests, install will copy this jar to local repo which is also useless. When Maven run tests it uses compiled classes from target dir and ignores project's jar if even it exists.
Yes, mvn isntall is the most popular option. It compiles, packages and tests your project.

How are "mvn clean package" and "mvn clean install" different?

What exactly are the differences between mvn clean package and mvn clean install? When I run both of these commands, they both seem to do the same thing.
Well, both will clean. That means they'll remove the target folder. The real question is what's the difference between package and install?
package will compile your code and also package it. For example, if your pom says the project is a jar, it will create a jar for you when you package it and put it somewhere in the target directory (by default).
install will compile and package, but it will also put the package in your local repository. This will make it so other projects can refer to it and grab it from your local repository.
Documentation
What clean does (common in both the commands) - removes all files generated by the previous build
Coming to the difference between the commands package and install, you first need to understand the lifecycle of a maven project
These are the default life cycle phases in maven
validate - validate the project is correct and all necessary information is available
compile - compile the source code of the project
test - test the compiled source code using a suitable unit testing framework. These tests should not require the code be packaged or deployed
package - take the compiled code and package it in its distributable format, such as a JAR.
verify - run any checks on results of integration tests to ensure quality criteria are met
install - install the package into the local repository, for use as a dependency in other projects locally
deploy - done in the build environment, copies the final package to the remote repository for sharing with other developers and projects.
How Maven works is, if you run a command for any of the lifecycle phases, it executes each default life cycle phase in order, before executing the command itself.
order of execution
validate >> compile >> test (optional) >> package >> verify >> install >> deploy
So when you run the command mvn package, it runs the commands for all lifecycle phases till package
validate >> compile >> test (optional) >> package
And as for mvn install, it runs the commands for all lifecycle phases till install, which includes package as well
validate >> compile >> test (optional) >> package >> verify >> install
So, effectively what it means is, install commands does everything that package command does and some more (install the package into the local repository, for use as a dependency in other projects locally)
Source: Maven lifecycle reference
package will generate Jar/war as per POM file.
install will install generated jar file to the local repository for other dependencies if any.
install phase comes after package phase
package will add packaged jar or war to your target folder, We can check it when, we empty the target folder (using mvn clean) and then run mvn package.
install will do all the things that package does, additionally it will add packaged jar or war in local repository as well. We can confirm it by checking in your .m2 folder.
Package & install are various phases in maven build lifecycle. package phase will execute all phases prior to that & it will stop with packaging the project as a jar. Similarly install phase will execute all prior phases & finally install the project locally for other dependent projects.
For understanding maven build lifecycle please go through the following link https://ayolajayamaha.blogspot.in/2014/05/difference-between-mvn-clean-install.html
mvn package command will compile source code and also package it as a jar or war as per pom file and put it into the target folder(by default).
mvn install command will compile and package, but it will also put the package in your local repository. So that other projects can refer to it and grab it from your local repository.
mvn install command is mostly used when you wants to compile a project(library) which other projects in your repository are depending on.

How to run unit tests in multi-module maven setup if i put the tests in a separate module?

i have created a multi-module maven project and i am trying to write and execute some tests on specific modules. I am trying to put all test-code into a separate module, but i am wondering if this is the correct way and if so how to i setup the maven build/test cycle so mvn install will use these tests?
According to the Maven Standard Directory Layout test classes belong to the directory src/test/java and required resources to src/test/resources. On the long term it will make your life easier by following the rules, especially when you work on many different projects (where you sometimes can not define alternative structures). In this setup the test cases are automatically invoked by mvn install or mvn test.
You find more informations about the surefire-plugin (responsible for executing the tests) here.

Categories