How to integrate Ant with Checkstyle and PMD plug-ins in Jenkins - jenkins

I want to integrate Checkstyle and PMD plug-ins in Jenkins for checking quality code automatically.
I followed the instructions from: http://www.treselle.com/blog/static-code-analysis-jenkins/
My build.xml in workspace was appended those codes:
<taskdef name="checkstyle" classpath="WEB-INF/libs/checkstyle-5.6.jar" classname="com.puppycrawl.tools.checkstyle.CheckStyleTask" />
<target name="checkstyle" description="Generates a report of code convention violations.">
<checkstyle config="sun_checks.xml" failOnViolation="false">
<formatter type="xml" tofile="checkstyle_report.xml" />
<fileset dir="WEB-INF/src" includes="**/*.java" />
</checkstyle>
</target>
<taskdef name="pmd" classpath="WEB-INF/libs/pmd.jar" classname="net.sourceforge.pmd.ant.PMDTask" />
<target name="pmd" depends="compress">
<pmd rulesetfiles="java-imports">
<formatter type="xml" toFile="pmd_report.x.ml" />
<fileset dir="WEB-INF/src">
<include name="**/*.java" />
</fileset>
</pmd>
</target>
I also added enough library, but when I builded Jobs, I got a exception:
taskdef class com.puppycrawl.tools.checkstyle.CheckStyleTask cannot be found using the classloader AntClassLoader[]
Why is there such error? And How do I integrate them correctly?
Thanks a lot!

Try later version of check style as checkstyle-8.0-all.jar.
See example

classname="com.puppycrawl.tools.checkstyle.CheckStyleTask" />
taskdef class com.puppycrawl.tools.checkstyle.CheckStyleTask cannot be found
The class is named CheckstyleAntTask.
See https://github.com/checkstyle/checkstyle/blob/master/config/ant-phase-verify.xml on an example on how to use CheckstyleAntTask.
checkstyle-5.6.jar
I recommend upgrading to a newer version. Checkstyle is currently on version 8.

Related

Junit Coverage using Jacoco with ant build

I have run into this specific problem while executing the junit with jacoco:coverage for code coverage. Tried a few things but no luck yet.
I have this junit build script.
<target name="executeJunitMain" depends="createJunitLibs" description="Executes All Junit and prepare report.">
<junit fork="yes" haltonfailure="off" failureProperty="junit.failure" includeantruntime="true" maxmemory="256m">
<classpath refid="compile.class.path" />
<formatter type="xml" />
<jvmarg value="-javaagent:${external.junit.lib.dir}/jmockit.jar"/>
<sysproperty key="jacoco-agent.destfile" file="${coverage.dir}/jacoco.exec"/>
<batchtest fork="yes" todir="${report.dir}" >
<fileset dir="${dest.dir}">
<include name="**/Test*.class" />
<exclude name="**/AllTests.class" />
<exclude name="**/*$*.class"/>
</fileset>
</batchtest>
</junit>
<antcall target="report"/>
</target>
<!-- Execute the coverage report.-->
<target name="report" description="Collect Coverage Report">
<!-- Creates the Junit Report -->
<junitreport todir="${report.dir}">
<fileset dir="${report.dir}">
<include name="TEST-*.xml"/>
</fileset>
<report format="frames" todir="${report.dir}/html"/>
</junitreport>
<!-- Creates the coverage Report.-->
<mkdir dir="${report.dir}/coverage"/>
<jacoco:report>
<executiondata>
<file file="${coverage.dir}/jacoco.exec" />
</executiondata>
<structure name="Code Coverage">
<classfiles>
<zipfileset src="${sources.lib.dir}/${test.jar.name}.jar"/>
</classfiles>
</structure>
<html destdir="${report.dir}/coverage" />
</jacoco:report>
</target>
using this ant script sometimes the junit build is failing. Error as below
BUILD FAILED
C:\Users\user\Codebases\junit.xml:111: The following error occurred while executing this line:
C:\Users\user\Codebases\junit.xml:147: The following error occurred while executing this line:
C:\Users\user\Codebases\junit.xml:164: Unable to read execution data file C:\Users\user\CodeBases\ju
nit\coverage\jacoco.exec
But sometimes it works perfectly. I am not sure when it works and when it does not. Any help will be appreciated.
Thanks
I have found the issue that was causing the jacoco to fail. I had a few instrumented jars imported in the classpath which were not required for the junit execution or coverage. These instrumented jars were causing jacoco session to be incorrect as we also had jmockit integration as Mocking Framework. The below link was very helpful for finding out the issue
eclemma.org/jacoco/trunk/doc/classids.html

Ant task is unable to recognize android private libraries

I am trying to run findbugs through ant. This is a snippet of a part of my build file:
<taskdef name="findbugs" classname="edu.umd.cs.findbugs.anttask.FindBugsTask" >
<classpath>
<fileset dir="${findbugs.home}/lib" includes="**/*.jar"/>
<pathelement location="${project.target.android.jar}" />
</classpath>
</taskdef>
<path id="build.classpath">
<pathelement location="${project.target.android.jar}" />
<fileset dir="libs">
<include name="*.jar"/>
</fileset>
</path>
<target name="findbugs" >
<findbugs home="${findbugs.home}" output="html" outputFile="findbugs/findbugs.html">
<class location="${out.classes.absolute.dir}" />
<auxClasspath refId="build.classpath"/>
<sourcePath path="${source.absolute.dir}" />
</findbugs>
</target>
This is unable to recognize the android library and gives errors like: cannot find android.os.Bundle,
etc,...
How do I make it recognize android libraries? I have tried including it using , but this doesn't seem to work.
I am not aware of the complete build file, but the main project compilation works fine, and the android lib included there are in this format:
<gettarget
androidJarFileOut="project.target.android.jar"
...
Findbugs works on Java's class file format. Android uses another format called dex. So Findbugs will not work on that.

Jenkins JUnit Test Result Report plugin states that the JUnit xml file is not found?

The exact message received from jenkins is:
No test report files were found. Configuration error?
Build step 'Publish JUnit test result report' changed build result to FAILURE
When configuring the JUnit Test Result Report plugin, on entering the 'Test Report XMLs' path as '/reports/TEST-*.xml', the following error is displayed beneath the path:
'/reports/TEST-*.xml' doesn't match anything: '' exists but not '/reports/TEST-*.xml'
I have tried using the full path as well but that produces the same result. In both cases the paths should have picked up the 'TESTS-TestSuites.xml' file that was present in the /reports directory.
I'm not sure whether this is a problem with the plugin or the XML file being generated. I'm also aware that it could be an issue with the ant build script that I have written to run the JUnit tests and produce the XML result file therefore I have included the contents of this below in case something needs to be changed:
<?xml version="1.0" encoding="utf-8"?>
<project name="jenkins-tests" basedir="." default="linux">
<property name="junit.output.dir" value="output"/>
<property name="src.dir" value="src"/>
<property name="lib.dir" value="libs" />
<property name="bin.dir" value="bin" />
<property name="full-compile" value="true" />
<path id="classpath.base"/>
<path id="classpath.test">
<pathelement location="${bin.dir}" />
<pathelement location="${src.dir}" />
<pathelement location="${lib.dir}" />
<pathelement location="${lib.dir}/junit.jar" />
<path refid="classpath.base" />
</path>
<target name="clean" description="Clean up build artefacts">
<delete dir="${basedir}/${junit.output.dir}" />
</target>
<target name="prepare" depends="clean" description="Prepare for build">
<mkdir dir="${basedir}/${junit.output.dir}" />
<mkdir dir="${junit.output.dir}/reports"/>
</target>
<target name="compile" depends="prepare">
<javac srcdir="${src.dir}" destdir="${bin.dir}" verbose="${full-compile}" includeAntRuntime="false" >
<classpath refid="classpath.test"/>
</javac>
</target>
<target name="test" depends="compile">
<junit printsummary="true" haltonfailure="false">
<formatter type="xml" usefile="true"/>
<classpath refid="classpath.test" />
<batchtest fork="yes" todir="${junit.output.dir}">
<fileset dir="${src.dir}">
<include name="*.java"/>
</fileset>
</batchtest>
</junit>
</target>
<target name="test-reports" depends="test">
<junitreport tofile="TESTS-TestSuites.xml" todir="${junit.output.dir}/reports">
<fileset dir="${junit.output.dir}">
<include name="TEST-*.xml" />
</fileset>
<report format="frames" todir="${junit.output.dir}/reports" />
</junitreport>
</target>
</project>
I've been researching into this problem for a while now and haven't found any solution so I would appreciate any help. Thanks.
Jenkins looks for the path from the workspace root. Ensure that the given path is correct or use wildcards to look in multiple locations. Try using **/reports/TEST-*.xml
Are you sure the reports folder is right under the workspace? Verify manually if the test result files are indeed present in the location given in the path.
For my Android project which has multiple Gradle product flavors I used the following path for Test report XMLs:
**/build/test-results/**/TEST-*.xml

Ant, Sonar - 0% code coverage

I have problem with ant sonar task. This task end with success but don't run unit tests and don't show code coverage.
Test task
<target name="test" depends=".....">
<path id="classpath">
<fileset dir="test/lib" includes="**/*.jar"/>
<fileset dir="lib" includes="**/*.jar"/>
<pathelement location="......."/>
</path>
<mkdir dir="build/tests"/>
<javac srcdir="test/src" destdir="build/tests" includes="**/*.java" debug="${debug}" deprecation="${deprecation}" optimize="${optimize}" nowarn="${nowarn}" fork="true">
<classpath refid="classpath"/>
</javac>
<copy todir="build/tests">
<fileset dir="test/src" excludes="**/*.java"/>
</copy>
<jacoco:coverage destfile="target/jacoco.exec" xmlns:jacoco="antlib:org.jacoco.ant">
<junit printsummary="yes" fork="true" haltonfailure="false" showoutput="true" failureproperty="test.failed">
<formatter type="xml"/>
<classpath refid="classpath"/>
<classpath>
<pathelement location="build/tests"/>
</classpath>
<test name="com........MainTestSuite" todir="build"/>
</junit>
</jacoco:coverage>
<fail message="Test failure detected, check test results." if="test.failed"/>
</target>
and sonar task:
<target name="sonar" depends="build">
<property name="sonar.tests" value="test" />
<property name="sonar.libraries" value="" />
<property name="sonar.surefire.reportsPath" value="sonarWorkDir" />
<!-- The following properties are required to use JaCoCo: -->
<!-- 1. Tells Sonar to run the unit tests -->
<property name="sonar.dynamicAnalysis" value="true" />
<!-- 2. Tells Sonar which "tests" targets to run -->
<property name="sonar.jacoco.antTargets" value="test" />
<!-- 3. Tells Sonar to use JaCoCo as the code coverage engine -->
<property name="sonar.core.codeCoveragePlugin" value="jacoco" />
<!-- Execute Sonar -->
<sonar:sonar key="${JOB_NAME}" version="${VERSION}" xmlns:sonar="antlib:org.sonar.ant">
<sources>
<path location="...../src" />
</sources>
<binaries>
<path location="build/....." />
</binaries>
</sonar:sonar>
</target>
until sonar task runs i got a warning 10:00:20.290 WARN o.s.p.j.JaCoCoPlugin - Coverage information was not collected. Perhaps you forget to include debug information into compiled classes?
I would advise you to:
use the latest version of the Sonar Ant Task (from what I can see in your script, you're using the old syntax)
take a look at our sample Ant projects to find out where your issue is. Most probably, the following example is what you're looking for: https://github.com/SonarSource/sonar-examples/tree/master/projects/code-coverage/ut/ant/ut-ant-jacoco-runTests
Kind of a late response, but I just recently ran into this issue and couldn't find a simple solution on the internet. Instead, to solve it I simply took the advice of the stack trace. Coverage information was not collected. Perhaps you forget to include debug information into compiled classes?
And then went back to my ant file and made sure the source files (not test) were being compiled in debug mode. Apparently the jacoco plugin needs that extra info like line numbers in order to calculate the code coverage. Once you change your ant file you should finally see a code coverage percentage in sonar.
<javac srcdir="${source.dir}" target="1.6" source="1.6" destdir="${build.classes.dir}" debug="on">
...
</javac>
Also, make sure you include the following sonar properties :
sonar.binaries=build/classes
sonar.tests=junit/tests
sonar.dynamicAnalysis=reuseReports
sonar.junit.reportsPath=build/test-reports
sonar.java.coveragePlugin=jacoco
sonar.jacoco.reportPath=build/test-reports/jacoco.exec
So you probably want to remove sonar.antTargets and change sonar.dynamicAnalysis's value to reuseReports

How to remove specific Cobertura warning?

When i am running my ANT build script, Cobertura is complaining with the following warning. With that, i am wondering what it means really and how can i turn it off.
[cobertura-instrument] WARN visitEnd, No line number information found for class com.x.y.z.A. Perhaps you need to compile with debug=true?
ANT sample below:
<target name="instrument" depends="init,compile" >
<delete file="cobertura.ser" />
<delete dir="${instrumented}" />
<cobertura-instrument todir="${instrumented}">
<ignore regex="org.apache.log4j.*" />
<fileset dir="${build}" >
<include name="**/*.class" />
<exclude name="**/Test*.class" />
</fileset>
</cobertura-instrument>
</target>
Please advise.
Setting debuglevel appears to not work for anonymous inner classes (Cobertura 1.9.4.1)?
[cobertura-instrument] WARN visitEnd, No line number information found for class com.test.MyClass$1. Perhaps you need to compile with debug=true?
As suggested here in the cobertura mailing-list, perhaps you can try adding the debug options and see if that helps.
<javac debug="true" debuglevel="vars,lines,source">

Resources