Monday, July 14, 2014

Marklogic and Alfresco Integration


What is MarkLogic?

       MarkLogic is a NoSQL database.
       MarkLogic comes in three flavors:

ü  Developer Edition - Free, full-featured version. Included API's extend to all versions of MarkLogic.
ü  Essential Enterprise – Supports replication, backup, high availability, recovery, fine-grained security, location services, and alerting. Semantics and advanced language packs are options.
ü Global Enterprise – It is designed for use for large, globally distributed applications. Semantics, tiered storage, geospatial alerting and advanced language packs are options.

What is Alfresco?

      Alfresco is a friendly team-based collaboration ECM (Enterprise Content Management System).
       Alfresco comes in three flavors:

ü  Community Edition - It has some important limitations in   terms of scalability and availability, since the clustering feature is not available to this edition.
ü  Enterprise Edition – It supports clustering, its design is geared towards users who require a high degree of modularity and scalable performance.
ü  Cloud Edition – It is a SaaS (Software as a service) version of Alfresco.

Why Alfresco?

     Its rich feature set is completely accessible over a REST-based interface and can be extended and enhanced with simple server-side JavaScript (i.e. no compilation required). although Java and Groovy etc. are common choices.
     It allows for management of data of any format (not only document content and images).
     It provides rich collaboration tools such as wiki, forums, issue log etc. and functionality to edit and manage image files.
     It enables easy web designing for people, who are not technical users.
     It provides publishing channels such as Google Docs, YouTube, Flickr, Slide Share, Facebook and LinkedIn out of the box.
     Office documents can be edited within CMS using Google Docs as well as offline using its built-in checkout feature.
     Rich Add-ons from Community i.e. plug-ins/tools can be integrated with Alfresco easily.
     Alfresco is compatible with most commonly used operating systems like Linux, MAC and Windows; it can be fully integrated with an organization's office suites like Microsoft Office or OpenOffice.org.
     Supports workflow with help of Activity and JBPM.
     Supports multiple databases.
      Provide search for the uploaded documents using Lucene API

Note: Alfresco use a library called Apache PDBox library (open source java lib) for extracting the texts from PDF and index them.  (http://pdfbox.apache.org/)

Why MarkLogic?

       High-performing XML database.
    Use Google style search engine.
    It's a document-centric NoSQL solution using XML as the content model, meaning you get a very scalable repository that can adapt to content changes effortlessly.
    It unifies structured, semi-structured and unstructured data into a single database from where organizations can store, retrieve, analyze and manipulate these very large data sets.
    With its immediate consistency and a searchable-everything philosophy, there's no need to compromise on your ACID promise.

Union Benefits of MarkLogic and Alfresco:                                  

       Alfresco can be used as an editorial and content production system, so you can create, curate, edit, and workflow and semantically enrich your content and finally publish the documents to MarkLogic.
    Once published to Mark Logic you have the power to perform fast searches using the powerful standards-based XQuery language.
     Versions of documents can be controlled in MarkLogic, Alfresco also supports document versioning but you cannot customize it.
    Using MarkLogic as your publishing target you gain not only a Big Data content store, but a rich and expressive query language where Search and Retrieval are combined.
    As MarkLogic is a document centric content store you don’t need to worry about the type of content and structure of content.

Supported Alfresco versions : 4.x and 5.x
Supported MarkLogic versions : 5.x and above

Steps to integrate Alfresco with MarkLogic>>>>>

1.     Download the alfresco marklogic integration plugin from 
2.     Create the jar file from the plugin maven (for 4.x version)
3.   Create amp using ant (5.0.a community version). 
4.     Add the jar file in /alfresco/WEB-INF/lib.
5.     Copy the config directories given in "/marklogic-integration-alfresco/src/main/config"     
      of plugin to /tomcat/shared/classes/
6.     Restart the Alfresco.
7.     Download the alfresco marklogic integration RESTApi from


7.     Configuring MarkLogic>>

                  I. Create a database named as "alfresco-pub".

                 II. Create a forest named as "alfresco-pub-forest"

                III. Attach the "alfresco-pub-forest" with "alfresco-pub" database.

               IV. Create a role named as "alfresco-publisher" and assign following ‘Execute
 Privileges' to the alfresco-publisher role under 'Execute Privileges’ section.

   A- admin-module-read
   B- admin-module-write
   C- any-collection
   D- xdmp:add-response-header
   E- xdmp:eval
   F- xdmp:document-get
   G- any-uri
   H- xdmp:get-session-field
I-    xdmp:http-delete,xdmp:http-get,xdmp:http-head,xdmp:http-post,
    xdmp:http- put,xdmp:http-options
   
  J- xdmp:invoke

                V. Save the role.

               VI. Assign following permissions to 'alfresco-publisher' role under '
 default permissions' section.

·         Select the role 'alfresco-publisher' and select 'update' from dropdown and save role.
·         Select the role 'alfresco-publisher' and select 'insert' from dropdown and save role.
·         Select the role 'alfresco-publisher' and select 'read' from dropdown and save role.
·         Select the role 'alfresco-publisher' and select 'execute' from dropdown and save role.

          VII. Create a user 'alfrescopub-admin', select the password & assign the 'alfresco-publisher' role to it and save the user.

       Note: You can enable/disable marklogic authentication by setting the value of ml.auth.enabled=true/false in marklogic-integration/alfresco-global.properties .Update the marklogic username and password in "marklogic-integration/alfresco-global.properties" in order to use authentication,

             VIII. Create an HTTP Server on Marklogic server,name it as 'Alfresco-Publishing-HTTP'.

               IX. Select port number as '9000'

                X. Under the root section provide the path of api which you have downloaded.

         For example: 
         If the download location is "d:\alfresco-marklogic-publish-unpublish-webservices"

               XI. Select the modules as 'file-system'.
              XII. Select the database as 'alfresco-pub' created at (step-7.1).
             XIII. Select the authentication 'digest'. If marklogic authentication is enabled in marklogic-integration/alfresco-global.properties. Otherwise Select the authentication 'application-level'.

            XIV. Select the default user 'alfrescopub-admin' created at (step-7.8).
             XV. Add the /url-rewriter.xqy inside the url rewriter section.
            XVI. Click 'OK' to save the changes on HTTP Server.

Your REST services are ready for use::::::
For publish uri should be : http://127.0.0.1:9000/alfrescopub/publish?uri=someuri
For unpublish uri should be : http://127.0.0.1:9000/alfrescopub/unpublish?uri=someuri


 8.  Configure Alfresco, Go to "Admin Console > Channel Publishing > Channel Manager"

          



     9.     Select "MarkLogic" as channel, Alfresco will authorize it.


         10.     Channel added to Alfresco


         11.    Click on "MarkLogic" channel icon to configure channel endpoint.



Provide MarkLogic server hostname e.g. "127.0.0.1" and MarkLogic server port e.g. "9000".

         12.    Click on "Save", Now channel is ready for use.



Test publishing>>>>>

1.  Go to "Project Library" > "Documents" > "Agency File" > "Images"
2.  Select an image,
       



3.  Click on "Publish" link on right hand side .
4.  Select "MarkLogic" as publishing channel, and click "Publish"
      
      







4.  Image published to MarkLogic, You can see the status at the bottom of the page.






You  can also verify the published content via MarkLogic qconsole or via following service



     http://127.0.0.1:9000/alfrescopub/get?id=workspace://SpacesStore/e9528c29-dbbc-49c5-ae63-ae35b67bea33



     Where value of id is the uri of content inside Alfresco, it can be seen in the URL of browser while content is viewed




5.  You can "Unpublish", by clicking on unpublish link right side in the history section,
      and Click "OK". Content will be queued for "Unpublishing"


5.  You can see the unpublish status in the "Publishing History" section.




References: 
https://docs.alfresco.com/4.2/
https://docs.marklogic.com

Leave your comments/suggestions below. Otherwise the next time :)



















    












Monday, June 30, 2014

Can main method be overloaded and overridden in Java?


Can main method be overloaded and overridden in Java?

So, answers are very simple...

Overloading>>>>>>> YES

You can overload the main method. but JVM only understands public static void main(String ar[]) {,....} and looks for the main method as with given signature to start the app.

For example:

public class OverloadingMainTest{
    public static void main(String[] args) {
        System.out.println("main(String[] args)");
    }

      public static void main(String... args) {
System.out.println("String... args >>>> VARARGS");
}

   public static void main(Integer[] args) {
        System.out.println("main(Integer[] args)");
    }

    public static void main(String arg1) {
        System.out.println("main(String arg1)");
    }

    public static void main(String arg1, String arg2) {
        System.out.println("main(String arg1, String arg2)");
    }
}


Here, i have overloaded the main method with diff. -2 types. but when you run the main method it will print:
          main(String[] args)

So, Again you can overload main method with diff.-2 signatures but it will be a simple     method only ... and it will never execute like actual main method>>

public static void main(String[] args) {
        System.out.println("main(String[] args)");
 }


Overriding>> NO

Overriding of methods can be done for only methods which belongs to an object not class, i mean to say that static methods/static variable etc. are not part of an object. and cant be overridden.

And if you try to do something like given below... you are not overriding it actually. You are hiding it. so when you run the main method of subclass JVM will not be able to load it.


public class Test{
public static void main(String[] args) {
System.out.println("Hello main");
}
}

public class Test1 extends Test{
public static void main(String[] args) {
System.out.println("Hello main test1");
}
}


And yeah if the main method which you have declared is itself not a static method then the overriding concept will be applied.


Friday, June 20, 2014

Data access object unit test using Mokito framework to follow TDD approach

Data access object unit test using Mokito framework to follow TDD approach:

Download MockIto from: 
https://code.google.com/p/mockito/downloads/detail?name=mockito-1.9.5.zip&can=2&q


UserInfoDao .java:

package com.dao;

import java.sql.SQLException;
import com.model.UserModel;

public interface UserInfoDao {
String registerUser(UserModel userInfo) throws SQLException;

}


UserInfoDaoImpl.java:

package com.dao.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import com.dao.UserInfoDao;
import com.model.UserModel;

public class UserInfoDaoImpl implements UserInfoDao {

private Connection connection;

public UserInfoDaoImpl(Connection connection) {
super();
this.connection = connection;

}

@Override
public String registerUser(UserModel userInfo) throws SQLException {
System.out.println("dao_registerUser(..) invoked..");
String queryResp = "Failed";
PreparedStatement preStmt = connection
.prepareStatement("insert into user_info(userName,password,firstName,lastName) values (?,?,?,?)");
preStmt.setString(1, userInfo.getUserName());
preStmt.setString(2, userInfo.getPassword());
preStmt.setString(3, userInfo.getFirstName());
preStmt.setString(4, userInfo.getLastName());

if (preStmt.executeUpdate() > 0) {
queryResp = "Success";
}
return queryResp;
}

public Connection getConnection() {
return connection;
}

public void setConnection(Connection connection) {
this.connection = connection;
}
}


UserModel.java:

package com.model;

public class UserModel {
private String userName;
private String password;
private String firstName;
private String lastName;
private int id;

public String getUserName() {
return userName;
}

public void setUserName(String userName) {
this.userName = userName;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

@Override
public String toString() {
return "UserModel [userName=" + userName + ", password=" + password
+ ", firstName=" + firstName + ", lastName=" + lastName
+ ", id=" + id + "]";
}

}


UserInfoService.java:

package com.service;

import com.model.UserModel;

public interface UserInfoService {
String registerUser(UserModel userInfo) throws Exception;
}

UserInfoServiceImpl.java:

package com.service.impl;

import com.dao.UserInfoDao;
import com.model.UserModel;
import com.service.UserInfoService;

public class UserInfoServiceImpl implements UserInfoService {

private UserInfoDao userInfoDao;

public UserInfoServiceImpl(UserInfoDao userInfoDao) {
super();
this.userInfoDao = userInfoDao;
}

@Override
public String registerUser(UserModel userInfo) throws Exception {
System.out.println("service_registerUser(..) invoked..");
return getUserInfoDao().registerUser(userInfo);
}

public UserInfoDao getUserInfoDao() {
return userInfoDao;
}

public void setUserInfoDao(UserInfoDao userInfoDao) {
this.userInfoDao = userInfoDao;
}
}

DaoClient:

package com.client;

import java.sql.Connection;

import com.dao.UserInfoDao;
import com.dao.impl.UserInfoDaoImpl;
import com.model.UserModel;
import com.service.UserInfoService;
import com.service.impl.UserInfoServiceImpl;
import com.util.DBMockUtils;

public class DaoClient {
public static void main(String[] args) throws Exception {
UserModel userInfo = new UserModel();
userInfo.setFirstName("Abhinav");
userInfo.setLastName("Mishra");
userInfo.setPassword("admin");
userInfo.setUserName("admin");
Connection conn = DBMockUtils.getConnection("com.mysql.jdbc.Driver",
"jdbc:mysql://localhost:3306/users", "root", "root");
UserInfoDao dao= new UserInfoDaoImpl(conn);

UserInfoService userServ=new UserInfoServiceImpl(dao);

System.out.println(userServ.registerUser(userInfo));
}
}


UserServiceTest : JUnit Test case.

package com.service.test;

import junit.framework.TestCase;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;

import com.dao.UserInfoDao;
import com.model.UserModel;
import com.service.UserInfoService;
import com.service.impl.UserInfoServiceImpl;

public class UserServiceTest extends TestCase {

private UserInfoService userInfoService;
private UserModel userInfo;

@Mock
private UserInfoDao userInfoDao;

@BeforeClass
public static void oneTimeSetUp() {
// one-time initialization code
System.out.println("@BeforeClass - oneTimeSetUp");
}

@AfterClass
public static void oneTimeTearDown() {
// one-time cleanup code
System.out.println("@AfterClass - oneTimeTearDown");
}

@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
userInfoService = new UserInfoServiceImpl(userInfoDao);
userInfo = new UserModel();
userInfo.setFirstName("Abhinav");
userInfo.setLastName("Mishra");
userInfo.setPassword("admin");
userInfo.setUserName("admin");

System.out.println("@Before - setUp");
}

@After
public void tearDown() {
System.out.println("@After - tearDown");
}

@Test
public void testUserInfoSuccess() throws Exception{
System.out.println("@Test testUserInfoSuccess()...");

Mockito.when(userInfoDao.registerUser(userInfo)).thenReturn("Success");

final String status = userInfoService.registerUser(userInfo);
System.out.println("Expected Result: " + status);

// Verify state
assertEquals("Success", status);

// Verify that method invoked actually or not
Mockito.verify(userInfoDao).registerUser(userInfo);

// verify the object with no. of times invocation
Mockito.verify(userInfoDao, Mockito.timeout(1)).registerUser(userInfo);
}

@Test
public void testUserInfoFailure() throws Exception {
System.out.println("@Test testUserInfoFailure()...");

Mockito.when(userInfoDao.registerUser(userInfo)).thenReturn("Failed");

final String status = userInfoService.registerUser(userInfo);
System.out.println("Expected Result: " + status);

// Verify state
assertEquals("Failed", status);

// Verify that method invoked actually or not
Mockito.verify(userInfoDao).registerUser(userInfo);

// verify the object with no. of times invocation
Mockito.verify(userInfoDao, Mockito.timeout(1)).registerUser(userInfo);

}
}


Output:


@Before - setUp

@Test testUserInfoSuccess()...

service_registerUser(..) invoked..

Expected Result: Success

@After - tearDown

@Before - setUp

@Test testUserInfoFailure()...

service_registerUser(..) invoked..

Expected Result: Failed

@After - tearDown





Testing servlets using JUNIT and MockIto

Testing Servlets using JUNIT and Mockito:


Mockito framework:



I have used version 1.10.19 of mockito-all for this post.

<!-- https://mvnrepository.com/artifact/org.mockito/mockito-all -->
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-all</artifactId>
    <version>1.10.19</version>
    <scope>test</scope>
</dependency>

Limitations:

1- Final,anonymous and primitive types can not be mocked.
2- Methods with return type "void"called from within doPost or doGet methods can not be mocked.

Servlet:

package com.github.abhinavmishra14.demo.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * The Class Login.
 */
public class Login extends HttpServlet {
	
	/** The Constant serialVersionUID. */
	private static final long serialVersionUID = 38044879686270933L;

	/**
	 * Instantiates a new login.
	 */
	public Login() {
		super();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.GenericServlet#init(javax.servlet.ServletConfig)
	 */
	@Override
	public void init(ServletConfig config) throws ServletException// called once servlet loads
	{
		System.out.println("Login Init called...");
		try {
			super.init(config);
		} catch (ServletException e) {
			e.printStackTrace();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.GenericServlet#destroy()
	 */
	@Override
	public void destroy()// called just before servlet unload
	{
		System.out.println("Login Destroyed...");
		super.destroy();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest,
	 * javax.servlet.http.HttpServletResponse)
	 */
	@Override
	public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		System.out.println("Login doPost...");
		String name = req.getParameter("user");
		String pwd = req.getParameter("password");
		String rememberMe = req.getParameter("rememberMe");
		System.out.println("User: " + name + " | password: " + pwd);
		if (name.equals("abhinav") && pwd.equals("passw0rd")) {
			HttpSession session = req.getSession();
			session.setAttribute("user", name);
			Cookie ck1 = new Cookie("user", name);
			Cookie ck2 = new Cookie("pwd", pwd);
			res.addCookie(ck1);
			res.addCookie(ck2);
			if (rememberMe != null && rememberMe != "") {
				Cookie ck3 = new Cookie("rememberMe", rememberMe);
				res.addCookie(ck3);
			}
		}

		PrintWriter out = res.getWriter();
		out.write("Login successfull...");
		// Dispatching request
		RequestDispatcher rd = req.getRequestDispatcher("/HelloWorld.do");
		rd.forward(req, res);
	}
}



TestCase:

package com.github.abhinavmishra14.demo.servlet.test;

import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.io.PrintWriter;
import java.io.StringWriter;

import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import junit.framework.TestCase;

import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import com.github.abhinavmishra14.demo.servlet.Login;

public class LoginServletTest extends TestCase {

	@Mock
	HttpServletRequest request;
	@Mock
	HttpServletResponse response;
	@Mock
	HttpSession session;

	@Mock
	RequestDispatcher rd;

	@Before
	protected void setUp() throws Exception {
		MockitoAnnotations.initMocks(this);
	}

	@Test
	public void test() throws Exception {
		when(request.getParameter("user")).thenReturn("abhinav");
		when(request.getParameter("password")).thenReturn("passw0rd");
		when(request.getParameter("rememberMe")).thenReturn("Y");
		when(request.getSession()).thenReturn(session);
		when(request.getRequestDispatcher("/HelloWorld.do")).thenReturn(rd);

		StringWriter sw = new StringWriter();
		PrintWriter pw = new PrintWriter(sw);

		when(response.getWriter()).thenReturn(pw);

		new Login().doPost(request, response);

		// Verify the session attribute value
		verify(session).setAttribute("user", "abhinav");

		verify(rd).forward(request, response);

		String result = sw.getBuffer().toString().trim();

		System.out.println("Result: " + result);

		assertEquals("Login successfull...", result);
	}
}


Output:

Login doPost...
User: abhinav | password: passw0rd
Result: Login successfull...



Tuesday, June 17, 2014

Implement Java Code Coverage and Junit test cases using Ant

Automating Java Code Coverage and JUnit:

Following jar files are required JUnit:

hamcrest-core-1.3.jar
junit-4.7.jar

Following jar files are required Java Code coverage:

jacocoant.jar


Build Properties:

src.dir=src
test.dir=test
project.name=TestApp
build.dir=appbuild
test.reports=test-reports
coverage.report=coverage-reports

Ant Targets:

<project name="TestApp" default="echo-properties" basedir="." xmlns:jacoco="antlib:org.jacoco.ant">

<property file="build.properties" />

<!--Creating the required directories for test cases-->
<target name="test-init" description="Creates the required directories for test case reports">
<echo>******Cleaning the ${test.reports}******</echo>
<delete dir="${test.reports}" />
<echo>******Creating the required directories for test reports******</echo>
<mkdir dir="${test.reports}" />
</target>
<target name="execute-junit" depends="compile,test-init">
<junit fork="true" printsummary="on" haltonfailure="yes" description="Junit test cases TestApp">
<classpath refid="classpath"/>
<classpath>
       <pathelement location="${build.dir}/WEB-INF/classes"/> 
       <pathelement location="${build.dir}/WEB-INF/test"/> 
       <pathelement location="${build.dir}/WEB-INF/config"/> 
</classpath>

<!--Save test result in xml format-->
    <formatter type="xml"/>
 
<!--Single test case->
     <!--<test name="com.AuthenticationServiceTest"
                                 haltonfailure="no" outfile="unittest_result"/>-->

<!--Batch test run-->
<batchtest fork="yes" todir="${test.reports}">
       <fileset dir="${build.dir}/WEB-INF/test">
        <include name="**/*TestSuite.class"/>
        <exclude name="**/*Test.class"/>
        <exclude name="**/AllTests.class"/>
       </fileset>
</batchtest>
 </junit>
  <antcall target="execute-junit-report"/>
</target>
<!--Report of the Junit Test cases -->
<target name="execute-junit-report">
        <junitreport todir="${test.reports}">
            <fileset dir="${test.reports}" includes="TEST-*.xml"/>
            <report todir="${test.reports}"/>
        </junitreport>
</target>
<!--Creating the required directories for coverage-->
<target name="test-coverage" description="Creates the required directories for coverage">
<echo>******Cleaning the ${coverage.report}******</echo>
<delete dir="${coverage.report}" />
<echo>******Creating the required directories for test reports******</echo>
<mkdir dir="${coverage.report}" />
</target>
<!-- Code Coverage Configurations -->
<taskdef uri="antlib:org.jacoco.ant" resource="org/jacoco/ant/antlib.xml">
<classpath path="${lib.dir}/jacocoant.jar"/>
</taskdef>
<target name="execute-code-coverage" depends="compile,test-coverage,test-init">
   <jacoco:coverage>
<junit fork="true" printsummary="on" haltonfailure="yes" description="Junit test cases TestApp">
<classpath refid="classpath"/>
<classpath>
       <pathelement location="${build.dir}/WEB-INF/classes"/> 
       <pathelement location="${build.dir}/WEB-INF/test"/> 
       <pathelement location="${build.dir}/WEB-INF/config"/> 
</classpath>

    <!--Save test result in xml format-->
    <formatter type="xml"/>
<!--Batch test run-->
<batchtest fork="yes" todir="${test.reports}">
       <fileset dir="${build.dir}/WEB-INF/test">
        <include name="**/*TestSuite.class"/>
        <exclude name="**/*Test.class"/>
        <exclude name="**/AllTests.class"/>
       </fileset>
</batchtest>
</junit>
</jacoco:coverage>
</target>
<target name="code-coverage" depends="execute-code-coverage">
<jacoco:report>
   <executiondata>
       <file file="jacoco.exec"/>
   </executiondata>
   <structure name="TestApp Code Coverage">
       <classfiles>
           <fileset dir="${build.dir}/WEB-INF/classes"/>
       </classfiles>
       <sourcefiles encoding="UTF-8">
           <fileset dir="${src.dir}"/>
       </sourcefiles>
   </structure>
   <html destdir="${coverage.report}"/>
<csv destfile="${coverage.report}/coverage-report.csv"/>
<xml destfile="${coverage.report}/coverage-report.xml"/>
</jacoco:report>
</target>

</project>




Implement FindBugs using ANT

What is FindBugs?

FindBugs is an open source program used to find bugs in Java code.It uses static analysis to identify hundreds of different potential types of errors in Java programs.

Potential errors are classified in four ranks: (i) scariest, (ii) scary, (iii) troubling and (iv) of concern.

This is a hint to the developer about their possible impact or severity. 

It is very similar to PMD, FindBugs operates on Java bytecode, rather than source code. Whereas PMD works on source code.

It can find major issues with code such as Possible NullpointerException, Security flwas, Performance issues etc. and many more. 


So, Let's do it >>>>>>>>>>>>>>>>>>>>>>>>>>>>>

Following are required jar files:

FindBugs Version 3.0.0:

 annotations.jar
ant.jar
asm-debug-all-5.0.2.jar
bcel-6.0-SNAPSHOT.jar
commons-lang-2.6.jar
dom4j-1.6.1.jar
findbugs-ant.jar
findbugs.jar
jaxen-1.1.6.jar
jcip-annotations.jar
jdepend-2.9.jar
jFormatString.jar
jsr305.jar
yjp-controller-api-redist.jar

Documentation:


I am demonstrating
Ant Targets:

<!-- FindBugs Configurations -->
<!-- Put all jar files given above to classpath, in my case all the jar files are in the 
               D:\JavaTools\Findbugs\findbugs-3.0.0\lib -->

<path id="findbugs.classpath">
<fileset dir="D:\JavaTools\Findbugs\findbugs-3.0.0\lib">
<include name="*.jar" />
</fileset>
</path>

<!--Creating the required directories for findbugs--> <target name="findbugs-init" description="Creates the required directories for findbugs."> <echo>******Cleaning the ${basedir}/findbugs-reports******</echo> <delete dir="${basedir}/findbugs-reports" /> <echo>******Creating the required directories for findbugs******</echo> <mkdir dir="${basedir}/findbugs-reports" /> </target>

<target name="findbugs" depends="findbugs-init,compile" description="Run code analysis over code to check for problems.">
       <!-- Fail this target if FindBugs is not installed. -->
<echo>*****Performing FindBugs analysis on ${project.name}*****</echo>
       <taskdef name="findbugs"
                classname="edu.umd.cs.findbugs.anttask.FindBugsTask"
        classpathref="findbugs.classpath" />

          <!-- Run FindBugs.for HTML output-->
<findbugs classpathref="findbugs.classpath"
      output="html"
             outputFile="${basedir}/findbugs-reports/findbugs.html"
     stylesheet="${basedir}/findbugs/fancy-hist.xsl">

<!-- fancy-hist.xsl stylesheet can be found in findbugs.jar file, 
       There are other stylesheets available and can be used based on the needs -->

<!-- An optional nested element which specifies a source directory path containing source files used to  compile the Java code being analyzed.By specifying a source path, any generated XML bug output will have complete source information, which allows later viewing in the GUI. -->

          <sourcePath path="${src.dir}" />

 <!-- auxclasspath is an optional nested element which specifies a classpath (Jar files or        directories) containing classes used by the analyzed library or application, but which you don't want to analyze.It is specified the same way as Ant's classpath element for the Java task.-->

<auxclasspath refid="classpath"/>

<!-- A optional nested element specifying which classes to analyze.The class element must specify a location attribute which names the archive file (jar, zip, etc.), directory, or class file to be analyzed. Multiple class elements may be specified as children of a  single findbugs element. In addition to or instead of specifying a class element, the FindBugs task can contain one or more fileset element(s) that specify files to be analyzed. For example, you might use a fileset to specify that all of the jar files in a directory should be analyzed. -->

<class location="${build.dir}/WEB-INF/classes" />

        </findbugs>

 <!-- Run FindBugs.for XML output -->
<findbugs classpathref="findbugs.classpath"
     output="xml"
             outputFile="${basedir}/findbugs-reports/findbugs.xml">

<!-- An optional nested element which specifies a source directory path containing source files used to  compile the Java code being analyzed.By specifying a source path, any generated XML bug output will have complete source information, which allows later viewing in the GUI. -->

          <sourcePath path="${src.dir}" />

 <!-- auxclasspath is an optional nested element which specifies a classpath (Jar files or        directories) containing classes used by the analyzed library or application, but which you don't want to analyze.It is specified the same way as Ant's classpath element for the Java task.-->

<auxclasspath refid="classpath"/>

<!-- A optional nested element specifying which classes to analyze.The class element must specify a location attribute which names the archive file (jar, zip, etc.), directory, or class file to be analyzed. Multiple class elements may be specified as children of a  single findbugs element. In addition to or instead of specifying a class element, the FindBugs task can contain one or more fileset element(s) that specify files to be analyzed. For example, you might use a fileset to specify that all of the jar files in a directory should be analyzed. -->

<class location="${build.dir}/WEB-INF/classes" />

  </findbugs>
<echo>*****FindBugs analysis report saved into ${basedir}/findbugs-                    reports/findbugs.xml*****</echo>

</target>


  <!-- Compile the source code -->
<target name="compile" depends="init">
<echo>******Compile the source files******</echo>
<javac debug="on" srcdir="${src.dir}" destdir="${build.dir}/WEB-INF/classes"
includes="**/*">
<classpath refid="classpath" />
</javac>
<!-- Compile the test cases -->
<javac debug="on" srcdir="${test.dir}" destdir="${build.dir}/WEB-INF/test"
includes="**/*">
<classpath refid="classpath" />
</javac>

</target>