In My project, if I write pom like this:
...
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.9</version>
<executions>
<execution>
<id>post-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
...
it will not generate report in my project after i run mvn install.
but i change it to
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.9</version>
<executions>
<execution>
<id>pre-test</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>post-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
it worked!!
I want to know what was the different?
I read the offical document here: http://www.jacoco.org/jacoco/trunk/doc/prepare-agent-mojo.html
the goal prepare-agent is just for set property for jvm agent, not start jvm agent, why it is necessary?
Well the link shared by you over prepare:agent already reads much of it:
Prepares a property pointing to the JaCoCo runtime agent that can be
passed as a VM argument to the application under test.
So if the goal is not bound to the plugin execution, then the default behavior for the property would be either argLine or tycho.testArgLine for packaging type eclipse-test-plugin.
In your case, if we assume its argLine, and your project defines the VM arguments for test execution, you need to make sure that they include this property.
One of the ways to do this in case of maven-surefire-plugin - is to
use syntax for late property evaluation:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>#{argLine} -your -extra -arguments</argLine>
</configuration>
</plugin>
The detailed Java Agent doc, can help you understand deeper how Jacoco uses its own agent to provide a mechanism that allows in-memory pre-processing of all class files during class loading independent of the application framework.
Related
http://www.eclemma.org/jacoco/trunk/doc/prepare-agent-mojo.html
I am like really not familiar with maven at all. And the project that I am working on requires it....
I am trying to customize this Jacoco tool in maven. Especially the "include" parameter for prepare-agent goal. I am testing a big project with about 4000 classes in many different packages. But the only coverage information that I need is only from 5-10 classes.
Any idea how I can specify something like this? Basically specify "include" while running test. Or do I have to specify it in the POM file?
"mvn jacoco:prepare-agent -Dinclude = "weka.associations.Apriori" test"
yes you can specify in the pom.xml file
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.4.201502262128</version>
<configuration>
<excludes>
<exclude>**/*_.*</exclude>
</excludes>
</configuration>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</configuration>
</plugin
where exclude tag will include your exclusion list , the classes which you want yo exclude to get code coverage, right now , it will not exclude anything
Kindly use the new version of jacoco as it is old one which i have specified
We have a Maven multi module project consisting of a parent (HelloWorld) and different children (HelloWorldServices and HelloWorldPresentation) and use Jenkins to build.
The error after running the successful test is
[INFO] --- jacoco-maven-plugin:0.7.6.201602180812:report (default-cli) # HelloWorldServices ---
[INFO] Skipping JaCoCo execution due to missing execution data file:/var/lib/jenkins/workspace/HelloWorld/HelloWorldServices/target/jacoco.exec
The lines before it says
[INFO] --- jacoco-maven-plugin:0.7.6.201602180812:prepare-agent (default-cli) # HelloWorldServices ---
[INFO] argLine set to -javaagent:/var/lib/jenkins/.m2/repository/org/jacoco/org.jacoco.agent/0.7.6.201602180812/org.jacoco.agent-0.7.6.201602180812-runtime.jar=destfile=/var/lib/jenkins/workspace/HelloWorld/HelloWorldServices/target/jacoco.exec
This is how I defined the parent pom JaCoCo plugin:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.6.201602180812</version>
<configuration>
<destfile>${project.artifactId}/target/jacoco.exec</destfile>
<datafile>${project.artifactId}/target/jacoco.exec</datafile>
</configuration>
<executions>
<execution>
<id>jacoco-initialize</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>jacoco-site</id>
<phase>package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
In no pom did I explicitly mention surefire. I also tried what you find everywhere to put the argLine in the configuration but all with the same result. The JaCoCo .exec file has never been created, no matter what I do. As for the goals, I use
mvn clean install jacoco:prepare-agent jacoco:report
Since when I omit the jacoco goals, it doesn't even display the INFO message.
You should not invoke the agent after the install phase but before, so instead of invoking:
mvn clean install jacoco:prepare-agent jacoco:report
You should invoke
mvn clean jacoco:prepare-agent install jacoco:report
The main reason is: the agent will not participate to the build lifecycle, the test phase will already be executed as part of the install phase, then Maven will execute the agent as per command line invocation, but it will be too late.
You should probably also change the plugin configuration above to:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.6.201602180812</version>
<executions>
<execution>
<id>jacoco-initialize</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>jacoco-site</id>
<phase>package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
Note: I removed the configuration section, because it was actually pointing to default values. Moreover, XML elements are case sensitives here, so your datafile element was simply ignored, it should have been dataFile instead. The same applies to destFile.
The prepare-agent goal is already using ${project.build.directory}/jacoco.exec as default destFile value, the same applied to the dataFile value for the report goal. The main reason for this change would be a more flexible and standard build, not relying on artifactId as project name (the default, but still not mandatory) and using the more generic ${project.build.directory} property instead to point directly at target.
Final note: make sure to configure the Jacoco Plugin executions within the build/plugins section and not build/pluginManagement/plugins section. The pluginManagement section is meant for governance and common harmonization of versions or configurations, but it will be ignored if the corresponding plugin would not be declared under build/plugins.
As per official Maven POM reference
pluginManagement: is an element that is seen along side plugins. Plugin Management contains plugin elements in much the same way, except that rather than configuring plugin information for this particular project build, it is intended to configure project builds that inherit from this one. However, this only configures plugins that are actually referenced within the plugins element in the children. The children have every right to override pluginManagement definitions.
(note: bold is mine)
JaCoCo reports get created from the execution data file.
If this file is not present then JaCoCo report goal skips the report creation.
So it is compulsory to create the execution data file.
Reasons due to which execution data file will not get created are the following
- Tests are not present.
- All tests are ignored.
- Surefire plugin is missing.
- JaCoCo's prepare-agent goal is not executed, which sets argLine which is needed to configure to surefire.
- Surefire plugin is not configured with JaCoCo's agent.
I think that "destfile" and "datafile" are case sensitive so try to replace them with "destFile" and "dataFile", maybe it'll work :)
I just dealt with this issue today and found out that this happening when I set the argLine parameter in Surefire plugin (which I needed to do for running JavaFx-related tests) which replaces the default even after you have prepare-agent in your jacoco-maven-plugin goals.
So basically, the solution is to add the original argLine and append your additional arg lines using #{argLine} as noted here:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
<configuration>
<argLine>#{argLine} --enable-native-access ALL-UNNAMED --add-modules jdk.incubator.foreign</argLine>
</configuration>
</plugin>
It mentioned in that post to assign the jacoco agent argline variable ${surefire.argLine} but i think those steps are not necessary (at least not in my case).
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.5</version>
<configuration>
<target>
<propertyfile file="lombok.config">
<entry key="config.stopBubbling" value="true" />
<entry key="lombok.addLombokGeneratedAnnotation" value="true" />
</propertyfile>
</target>
<excludes>
<exclude>**/domain/**</exclude>
<exclude>**/enumeration/**</exclude>
<exclude>**/exception/**</exclude>
</excludes>
</configuration>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<!-- attached to Maven test phase -->
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
<!-- Add this checking -->
<execution>
<id>jacoco-check</id>
<goals>
<goal>check</goal>
</goals>
<configuration>
<rules>
<rule>
<element>PACKAGE</element>
<limits>
<limit>
<counter>INSTRUCTION</counter>
<value>COVEREDRATIO</value>
<minimum>65%</minimum>
</limit>
</limits>
</rule>
</rules>
</configuration>
</execution>
</executions>
</plugin>
I share with you my response may be someone else work for him
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.5</version>
<!-- <configuration>
<excludes>
<exclude>package you want exclude</exclude>
</excludes>
</configuration>-->
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<!-- attached to Maven test phase -->
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
<!-- <execution>
<id>jacoco-check</id>
<goals>
<goal>check</goal>
</goals>
<configuration>
<rules>
<rule>
<element>PACKAGE</element>
<limits>
<limit>
<counter>LINE</counter>
<value>COVEREDRATIO</value>
<minimum>0.9</minimum>
</limit>
</limits>
</rule>
</rules>
</configuration>
</execution>-->
</executions>
</plugin>
I would like to execute a plugin goal from command line but perform multiple executions of the plugin. To this end my POM looks like this:
<plugin>
<groupId>xxx.yyy</groupId>
<artifactId>zzz</artifactId>
<version>1.1.6</version>
<executions>
<execution>
<id>default-cli-1</id>
<goals>
<goal>mygoal</goal>
</goals>
<configuration>
.... config1 ....
</configuration>
</execution>
<execution>
<id>default-cli-2</id>
<goals>
<goal>mygoal</goal>
</goals>
<configuration>
.... config2 ....
</configuration>
</execution>
</executions>
</plugin>
What I would like to do is something like:
mvn xxx.yyy.zzz:mygoal
and that would then execute the two executions. But I cannot figure out how.
I'm aware that I cannot use an <id> when executing from the command line. That is what the default-cli is for. However the <id> must be unique within <executions> which means I can only put the default-cli on one execution.
Maven version 3.0.5.
You can execute a goal (and its execution) from command line starting from Maven 3.3.1 on and this new feature, via the #executionId additional option.
Concerning Maven and execution ids generation, you can also check this SO question.
Before Maven 3.3.1 you could instead bind the two executions to a phase which would normally not harm (like validate) and have something like the following:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>execution-1</id>
<phase>validate</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>something1</classifier>
</configuration>
</execution>
<execution>
<id>execution-2</id>
<phase>validate</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>something2</classifier>
</configuration>
</execution>
</executions>
</plugin>
Then executing:
mvn validate
You will effectively execute the two executions of the same goal of the same plugin, as part of an harmless phase.
If you don't want to have them as part of this phase by default (understandable), then you can move them to a profile and activate it as part of the execution:
mvn validate -PpluginGoalExecution
For completeness, the profile would look like:
<profile>
<id>pluginExecution</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>execution1</id>
<phase>validate</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>something1</classifier>
</configuration>
</execution>
<execution>
<id>execution2</id>
<phase>validate</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>something2</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
And it goes without saying: the id of the profile should in this case be quite self explanatory about which plugin and which goal it would actually execute (that is, the purpose of the profile, as usual).
Update
Just cosmetic, but you could also add to the profiled build above the element:
<defaultGoal>validate</defaultGoal>
So that you would only need to run the following Maven command (only profile activation):
mvn -PpluginGoalExecution
And it would then automatically execute the validate phase and the configured plugin executions. Not a big change (as I said, cosmetic), but maybe closer to a plugin goal execution rather than a Maven phase invocation (again, just appearance).
I'm working on a project in which I've got an antlr4 grammar in main code, and I'd like to add a "mini-grammar" for some tests. I'd like the generated .java files for that mini-grammar to only be available to test code. Can the antlr4-maven-plugin support this?
After some experimentation, I settled on this less-than-ideal setup:
both my main-targeted and test-targeted grammars are in src/main/resources (I realize this isn't the standard place; I set sourceDirectory to account for this)
the antrun plugin copies ${project.build.directory}/generated-sources/antlr4/**/MyTestGrammar*.java to ${project.build.directory}/generated-test-resources/antlr4
the build-helper-maven-plugin plugin adds ${project.build.directory}/generated-test-resources/antlr4 as a test source dir
This requires three plugin configurations, and that I explicitly specify which of the generated grammars are meant for tests and which are meant for main code. Is there a better way?
Save your test grammar in a subfolder of ${baseDir}/src/test/antlr4.
Then you can try and put something like this inside the build-plugins element of your POM:
<plugin>
<groupId>org.antlr</groupId>
<artifactId>antlr4-maven-plugin</artifactId>
<version>${antlr4.plugin.version}</version>
<configuration>
<arguments>
<argument>-visitor</argument>
</arguments>
</configuration>
<executions>
<execution>
<id>antlr-4</id>
<goals>
<goal>antlr4</goal>
</goals>
</execution>
<execution>
<id>antlr-test</id>
<configuration>
<sourceDirectory>${baseDir}/src/test/antlr4</sourceDirectory>
<outputDirectory>${baseDir}/target/generated-test-sources-antlr/antlr4</outputDirectory>
</configuration>
<phase>generate-test-sources</phase>
<goals>
<goal>antlr4</goal>
</goals>
</execution>
</executions>
</plugin>
and then add the generate sources while compiling the test classes:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>add-test-sources</id>
<phase>generate-test-sources</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>${baseDir}/target/generated-test-sources-antlr/antlr4</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
You may want to adjust directories and packages names according to your needs
I want to run the maven compiler plugin in a different phase and with different sourceDirectories and destinationDirectories such that code from directories other than src/main/java and src/test/java can be used.
I thought the solution would look something like the below, where the phase I was linking it to was pre-integration-test. However the properties for testSourceDirectory and testOutputDirectory don't seem to be specified in this way as they are in the section of the POM.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>compile mytests</id>
<goals>
<goal>testCompile</goal>
</goals>
<phase>pre-integration-test</phase>
<configuration>
<testSourceDirectory>${basedir}/src/inttest/java</testSourceDirectory>
<testOutputDirectory>${basedir}/target/inttest-classes</testOutputDirectory>
</configuration>
</execution>
</executions>
</plugin>
Is there a way to get this plug-in to compile different directories in different phases without affecting its default operation?
The source directories are set outside the compiler-plugin inside the <build> element, so this won't work.
You can use the build-helper-maven-plugin's add-source and add-test-source to specify additional source directories for your integration tests, but this will not remove the existing source dirs.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.3</version>
<executions>
<execution>
<id>add-it-source</id>
<phase>pre-integration-test</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${basedir}/src/inttest/java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
If you bind the add-test-source goal to run just before the testCompile goal, your integration tests will be included. Note you want them to be output to target/test-classes so the surefire plugin will find them.
To handle removal of the standard test sources, I wrote a small plugin to modify the model to remove existing testSource locations before adding the ones for integration tests.
After more research it is apparent this is not actually possible in Maven 2 in the way I want, a hack of some form is necessary to introduce integration tests. While you can add additional directories (as suggested by Rich Seller) there is no plugin to remove the other sources or to compile a directory separately from the main compilation.
The best solution I have found for adding integration tests is to first use the build helper plugin to add the directory inttest directory to be compiled as tests.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>add-test-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>src/inttest/java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
Now in order to get the integration tests to execute on the integration-test phase you need to use excludes and includes to manipulate when they get run as below. This allow any custom parameters you might want (in my case an agent being added via argline).
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<excludes>
<exclude>**/itest/**</exclude>
</excludes>
</configuration>
<executions>
<execution>
<id>inttests</id>
<goals>
<goal>test</goal>
</goals>
<phase>integration-test</phase>
<configuration>
<excludes><exclude>none</exclude></excludes>
<includes>
<include>**/itest/**/*Test.java</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>