EMMA coverage tool not displaying line-by-line coverage - java

I am using the EMMA tool for code coverage yet despite my best efforts, EMMA is refusing to see the original .java files and generate coverage on a line-by-line basis.
We are using ANT to build the code and debug is set to true. I know that EMMA is measuring coverage as the .emma files seem to be generating and merging correctly. The reports are able to present high level method coverage with percentages.
But why won't it see the .java files? All I get is:
[source file 'a/b/c/d/e/f/code.java' not found in sourcepath]

Are you setting the sourcepath in your report element?
<report>
<sourcepath>
<pathelement path="${java.src.dir}" />
</sourcepath>
<fileset dir="data">
<include name="*.emma" />
</fileset>
<txt outfile="coverage.txt" />
<html outfile="coverage.html" />
</report>

Could you post the portion of your build.xml that generates the EMMA reports? Sounds like a report sourcepath issue.
report sourcepath should point to your java source.
See sourcepath in the EMMA reference. This can be a path-like structure, so you can include multiple source directories.
As always, with ANT:
execute the smallest possible build.xml with -verbose
-debug for even more information.

I ran into the same issue. But found that while setting the sourcepath we need to set to the only directory level not to the java file location. it is similar to the classpath

does {java.src.dir} need to point to one specific src directory.
This is no one single src directory as I am compiling multiple projects. Each with their own build.xml file.
I believe this is the portion that generates all the coverage reports:
<target name="emma.report" if="use.emma">
<emma enabled="true">
<report sourcepath="${test.reports.dir}">
<!-- collect all EMMA data dumps (metadata and runtime): -->
<infileset dir="${test.data.dir}" includes="*.emma" />
<html outfile="${test.reports.dir}/coverage.html" />
</report>
</emma>
</target>
EDIT: I changed the sourcepath to point directly to one of the src directories. See if that works.

Related

Copy external docs (from xyz-javadoc.jar) into JavaDocs

I want to create a .jar file with Ant, which contains all JavaDocs of my library and its dependencies. I did a lot of searching yesterday afternoon/evening and this morning, but none of the solutions work for me.
My first solution:
<!-- Generate JavaDoc -->
<javadoc sourcepath="${src}" destdir="${doc}" windowtitle="${ant.project.name}">
<classpath path="${lib}/nv-websocket-client-2.9-javadoc.jar"/>
<classpath path="${lib}/gson-2.8.6-javadoc.jar"/>
</javadoc>
My second solution:
<!-- Generate JavaDoc -->
<javadoc sourcepath="${src}" destdir="${doc}">
<classpath>
<fileset dir="${lib}">
<include name="gson-2.8.6-javadoc.jar"/>
<include name="nv-websocket-client-2.9-javadoc.jar"/>
</fileset>
</classpath>
</javadoc>
In both cases, however, only the JavaDoc for my own code is produced. The libraries are completely ignored. In the log of the Ant-Task there are errors, that the classes from the libraries were not found.
I don't know if this is the best aproach, but for me it's easier to use "jar" from command line.
Then all you have to do is indicate where are your files located:
jar uf0 path_to_your_jar\your_jar_file.jar path_to_your_files\*.*
jar uf0 path_to_your_jar\your_jar_file.jar path_to_your_other_files\*.*
If the libraries you want to add are already packed in a jar file, I would extract them first in the root directory, so the path of every file is correct. If you execute the previous commands, you'll have all your files in the "your_jar_file.jar" file.
if you type jar --help from command line you'll see more options. I hope it helps.

Apache ant javah task not working with jdk 10+

We are shifting from jdk 1.8 to jdk13. In our build.xml we have
<target name="generate-native-headers" depends="compile,resolve" description="Java to Native">
<javah class="com.zimbra.znative.IO" outputfile="${build.dir}/IO.h" classpathref="build.class.path"/>
</target>
But java10+ is not supporting javah anymore so I found we can achieve this with javac "nativeheaderdir" here - https://ant.apache.org/manual/Tasks/javac.html#nativeheaderdir
So I tried to convert above javah task to javac as below
<target name="generate-native-headers" depends="compile,resolve" description="Java to Native">
<javac srcdir="src/java/com/zimbra/znative" nativeHeaderDir="${build.dir}" classpathref="build.class.path" includes="src/java/com/zimbra/znative/IO.java" />
</target>
Now the missing javah error gone, but I don't see IO.h file generated in my build directory.
Can anyone help me, how to do this? Your help is really appreciated, thank you.
Note: directory src/java/com/zimbra/znative have around 5-6 .java files. I mentioned an example for 1 file only.
I can't see an obvious way to persuade the javac task to do this. nativeHeaderDir= generates the headers, but won't concatenate as you have found.
A post-javac workaround might look like this - combine the per-class headers into a single file using the Ant <concat> task:
<concat destfile="IO.h">
<header>/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
</header>
<concat destfile="IO.h">
<fileset dir="${build.dir}" includes="*.h" />
<filterchain>
<linecontainsregexp negate="true">
<regexp pattern="(#include .jni.h.)|(DO NOT EDIT THIS FILE - it is machine generated)" />
</linecontainsregexp>
</filterchain>
</concat>
</concat>
The basic idea is simple: find all the header files generated by javac, concatenate them into one header with the name required. Optionally, along the way, strip out the repeated #include and comment lines. The result should look the same as a JDK 8 javah-produced header.
With the below changes, I am able to create header files. But the generated file name is "com_zimbra_znative_IO.h". It should be "IO.h"
<target name="generate-native-headers" depends="compile,resolve" description="Java to Native">
<javac srcdir="src/java/com/zimbra/znative" destdir="${build.dir}" nativeHeaderDir="${build.dir}" classpathref="build.class.path"
includes="IO.java"
excludes="Process.java,ProcessorUsage.java,ResourceUsage.java,Util.java,ProxyInfo.java" />
</target>
Generating header files using javac task from ant should be along with your generated class file. So if the corresponding class file already available and no change in the source file (other words your compiled class modification time is higher than the java source file) then the javac ant task won't do any action on that class file including native header file generation.
You have to perform few check,
Is your srcdir attribute pointing to the right directory which starts your packages. (ex. your class name is com.zimbra.znative.MyClass and the file path is src/java/com/zimbra/znative/MyClass.java then your srcdir should be point to src/java.
Provide destdir where your compiled class files will be generated, otherwise it will generate inside your srcdir.
Normally includes not required if you want to generate all header files which all the class having native method in your srcdir
<target name="generate-native-headers" depends="compile,resolve" description="Java to Native">
<javac srcdir="src/java" nativeHeaderDir="${build.dir}" destdir="${build.classes}"
classpathref="build.class.path" includes="src/java/com/zimbra/znative/IO.java" />
</target>
Before running the ant make sure the IO.class file not exist or the source .java file has recent changes than the existing class file. then see it will generate the class file and header files. Header files should be inside ${build.dir}

Using Ant to build multiple jars

I have multiple Java eclipse projects. Each of them has "jardesc" file for building jar. It's nice - double click -> finish and jar file is made. But when i have to export several jars it's a pain - i have to repeat procedure several times.
Please tell me, can i use Ant script to run several "jardesc" files at once (and get several jars according to each jardesc file)? How to do it?
You could use the jar target to make the jars for you:
<jar destfile='destination.jar' basedir='source\dir\' />
so your build.xml would look a little like this:
<project default="makejars">
<target name="makejars">
<jar destfile="app1.jar" basedir="app1\src\" />
<jar destfile="app2.jar" basedir="app2\src\" />
<jar destfile="app3.jar" basedir="app3\src\" />
</target>
</project>
then just run ant in the same directory as build.xml, and the jars should be made.
Take a look at subant task in ant. You can create ant-file which would call other files to.
<subant target="create_jar1">
<fileset dir="." includes="jar2.xml"/>
</subant>
<subant target="create_jar2">
<fileset dir="." includes="jar1.xml"/>
</subant>
You can use some loops to create ant parameters however there is no way to loop to create multiple jars (even with ant-commons extension), a copy & paste is the only viable solution unless you want to write an ant plugin (which doesn't really take that much 2 hours reading docs + write simple plugin)

How to distribute junit tests to another machine

The build.xml we have today have many targets to compile and run unit tests. The build.xml refers to many property files with relative to itself. All this works fine when build and test is done on same machine.
It is pretty simple to do build get all jars and any test input files to a build_home(another machine). How to run junit on the new location? Should I create small build.xml files to running the tests? (There is no way to create ant build.xml dynamically) Any solutions?
( GridGain is possible solution. Not tried yet. )
Edit: Mode details on why this more complicated: The source code is around 3G, doing clearcase update and build takes considerable time (40 minute) against real test time of junit testing - 60 minutes. We have many machines to run the tests -- loading Clearcase on all systems not possible.
I understand your question as you want to only run the Junit tests on another machine without actually building on it? You can run something on the lines below as build scripts from Cruise control and probably Hudson too
If you're using the task via ant, then follow the same principles as a standard build. You can check out the code to all target machines from source control.
Externalize all root directories to a build.properties. These are properties which have to be set on each machine like so.
#Overall Project Name
project.name=myapp
# Top Level Root directory of the new working project
toplevel.project.dir=D:/proj/eComm
# Root directory of the source code
root.project.dir=D:/proj/eComm/Construction
# JDK home directory
jdk.home=C:/jdk1.5.0_11
build.properties will also have some static properties defined relative to the above. These need not be changed by any user on any local machine.
ear.dist.dir = ${root.project.dir}/target
src.dir = ${root.project.dir}/src
test.src.dir = ${root.project.dir}/test
Ensure your build.xml only refers to any further sub directories via these properties without any hardcoded values in it.
My junit are in a separate file which is imported into the build.xml by
<import file="${root.project.dir.buildscripts.dir}/junit.xml"/>
and some part of junit.xml is shown below
<target name="run.junit" depends="clean.junit, junit.info, prepare.junit"
description="Compiles and runs all JUnit Tests in the 'test' directory and produces a report of all failures">
<junit printsummary="yes" fork="true" haltonfailure="no" showoutput="yes" maxmemory="512m">
<jvmarg line="${junit.jvm.arg}"/>
<classpath>
<fileset dir="${src.dir}">
<include name="**/*.*"/>
</fileset>
<fileset dir="${ear.dist.dir}/build/classes">
<include name="**/*.*"/>
</fileset>
<pathelement path="${test.run.path}"/>
</classpath>
<formatter type="xml"/>
<batchtest fork="true" todir="${ear.dist.dir}/build/junit">
<fileset dir="${test.src.dir}" includes="${test.pattern.include}"/>
</batchtest>
</junit>
</target>
Try Cruise Control. It's a great way to offload your build and unit test to another machine.

Java: How to compile a runnable jar from packages?

My Java application has got a package structure similar to this:
src/com/name/app
src/com/name/app/do
src/com/name/utils/db
How would I go about compiling Java files in these directories in to a runnable jar? I need to package required libraries into the generated JAR (jdbc).
I've always done these things in Eclipse but now I need to supply a couple of people with a way to compile the repository without the use of eclipse and I was thinking of making a makefile or a script that invokes the necessary javac pattern.
Take a look at Ant. It's a relatively simple build tool to understand, and provides everything that meets your requirements. Here's a quick skeleton build.xml to get you started:
<project name="my_app_name" default="jar">
<target name="compile">
<javac srcdir="src" destdir="bin">
<classpath>
<fileset dir="lib">
<include name="**/*.jar" />
</fileset>
</classpath>
</javac>
</target>
<target name="jar">
<jar manifest="manifest_file" destfile="dist/my_app_name.jar">
<fileset dir="bin" />
<fileset dir="lib" />
</jar>
</target>
You need to create a manifest file that will tell the java process which class holds the "main" method. Here is a good place to start learning about manifests.
As an alternate that produces really cluttered Ant build files, you can right click on your Eclipse project and choose "Export...", then choose "General > Ant Buildfiles".
Anyway, that should get you started. You can ask more specific questions as you run into them.
First of all, consider using Ant for such a task.
But since you asked for a manual process, you need to first create a manifest file, like so:
Manifest-Version: 1.0
Created-By: 1.6.0 (Sun Microsystems Inc.)
Class-Path: lib/jdbc.jar lib/otherlib.jar
Main-Class: com.name.app.MainClass
Replace the contents of Class-Path with your libs, and Main-Class with the fully qualified name of your main class.
Then, you need to generate the actual .jar, using the following command:
jar cfm app.jar MANIFEST.MF src/com/name/app/*.class src/com/name/app/do/*.class
Where MANIFEST.MF is the previously mentioned manifest file, and the rest is the folders where your .java classes lie in.
Finally, to run your app, you simply execute: java -jar app.jar.
Consider using Ant to do this. http://ant.apache.org/
I recommend that you use Apache Ant to implement your build scripts.
If implemented correctly, Ant is easy to use and the build scripts can be run on any platform that you can install a JDK on. Indeed, with a little bit of work, you can even set up your project so that users don't even need to download / install Ant. (Hint: add the Ant JAR files and a wrapper script to your project distro)

Categories