Short notes of things that I have learnt or have got my hands dirty with. Short summary sometimes or some analysis in some cases. Blogs on various frameworks, tools and techniques in developing JEE and related applications.
Jan 23, 2013
You're IT: Hibernate Case in Select Clause strange behavior
You're IT: Hibernate Case in Select Clause strange behavior: It seems there is some strange behavior when using the CASE WHEN THEN ELSE END in the select clause. When using It results in java.lang....
Jan 14, 2013
Demystifying “Loading JDBC Driver”
Recently
while interacting with newbies or say IT aspirants when being asked about
simple JDBC questions most of the people were at sea. Question was simple
“While
getting JDBC connection in java application what we do is first we call
Class.forname(“<driver-name”) and then we call DriverManager.getConnection
with appropriate arguments. We do not get any value from Class.forname and
return it to DriverManager so how this works.
Class.forName("driver-name");
DriverManager.getConnection(url, user, password);
|
Most of
the people those who answered simply said it will load JDBC driver. Next
question was “What does that mean”. Long pause and then again “Will load the
driver” J
So now
let’s see what happens when we call Class.forname on JDBC driver for MySQL db.
Class.forName("com.mysql.jdbc.Driver");
|
Following
is code snippet from MySQL driver class.
So when
we call Class.forname(“com.mysql.jdbc.Driver”) static block of this class will
be called
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
}
catch
(java.sql.SQLException E) {
throw new RuntimeException("Can't
register driver!");
}
if (DEBUG) {
Debug.trace("ALL");
}
}
|
Looking
at the code we understand that Class.forname will call registerDriver method of
DriverManager class and will pass instance of Driver class for MySQL to
DriverManager. When DriverManger.registerDriver is called it will check for
null and if it is not null then it will add this driver in list of registered
drivers.
public static synchronized void
registerDriver(java.sql.Driver driver) throws SQLException
{
/* Register the
driver if it has not already been added to our list */
if(driver != null) {
registeredDrivers.addIfAbsent(new DriverInfo(driver));
}
else {
// This is for
compatibility with the original DriverManager
throw new
NullPointerException();
}
println("registerDriver:
"
+ driver);
}
|
When
getConnection(url, user, password) is called it will internally call
getConnection(url, driverinfo, classLoaded) which will iterate through
registered drivers and call connect method on Driver for which which will
create and return connection.
for(DriverInfo aDriver : registeredDrivers)
{
// If the caller
does not have permission to load the driver then skip it.
if(isDriverAllowed(aDriver.driver,
callerCL))
{
try {
println(" trying " +
aDriver.driver.getClass().getName());
Connection
con = aDriver.driver.connect(url, info);
if (con != null) {
// Success!
println("getConnection
returning " + aDriver.driver.getClass().getName());
return (con);
}
} catch (SQLException ex)
{
if (reason == null) {
reason
= ex;
}
}
}
else {
println(" skipping: " +
aDriver.getClass().getName());
}
}
|
So this
is how all happens…Happy coding.. J
Jan 13, 2013
Formatting JUnit Results with Ant
One of the best practice for developing application is Test
Driven Development. Common most tool/api we use in Java for unit testing is JUnit
and for automation we use is Ant. Ant task for JUnit supports four result
format.
- · xml
- · pPlain
- · brief
- · failure
Details
about these formats can be found at JUnit task document. But at times we need
to get unit test results in format other than default format. In my case I
wanted to store these results in csv/xls format to keep track of results that
have passed/failed/thrown error during development. So we created our own
format by implementing org.apache.tools.ant.taskdefs.optional.junit.JUnitResultFormatter.
For implementing this interface we need to have following jars in classpath
·
ant.jar
·
ant-junit.jar
·
junit-x.y.jar (Where x and y are version and
subversion of jar)
So
we create a java project in Eclipse and add these jars in build path and create
following class in java project.
package com.customization.ant.junit.formatter;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.Vector;
import junit.framework.AssertionFailedError;
import junit.framework.Test;
import org.apache.tools.ant.BuildException;
import
org.apache.tools.ant.taskdefs.optional.junit.JUnitResultFormatter;
import org.apache.tools.ant.taskdefs.optional.junit.JUnitTest;
import
org.apache.tools.ant.taskdefs.optional.junit.JUnitVersionHelper;
import com.customization.ant.junit.bean.UnitTestBean;
public class XLSFormatter implements
JUnitResultFormatter{
private enum TestStatus {PASS,FAIL,ERROR};
boolean testsuccess = true;
boolean isError = false;
private OutputStream ostrm;
private
List<UnitTestBean> beanlist = new Vector<UnitTestBean>();
@Override
public void addError(Test
test, Throwable t) {
testsuccess=false;
isError = true;
}
@Override
public void addFailure(Test t,
AssertionFailedError e) {
testsuccess=false;
System.out.println("Adding
failure");
}
@Override
public void endTest(Test test)
{
String
caseName = JUnitVersionHelper.getTestCaseName(test);
UnitTestBean
bean = new UnitTestBean();
bean.setCaseName(caseName);
bean.setSuccessful(testsuccess);
beanlist.add(bean);
}
@Override
public void startTest(Test
test) {
testsuccess = true;
isError = false;
}
@Override
public void
endTestSuite(JUnitTest test) throws BuildException {
StringBuffer
sbuff = new StringBuffer();
sbuff.append("TestCase
Name,Status\n");
for(UnitTestBean bean:beanlist)
{
sbuff.append(bean.getCaseName()).append(",").append(bean.isSuccessful()?TestStatus.PASS:
isError?TestStatus.ERROR:TestStatus.FAIL).append("\n");
}
try
{
ostrm.write(sbuff.toString().getBytes());
ostrm.flush();
ostrm.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void
setOutput(OutputStream ostrm) {
this.ostrm = ostrm;
}
@Override
public void
setSystemError(String arg0) {
isError=true;
}
@Override
public void
setSystemOutput(String arg0) {
}
@Override
public void
startTestSuite(JUnitTest test) throws BuildException {
}
}
|
Let’s
understand the code now. We will define following class level variables to
store status of test cases.
private enum TestStatus {PASS,FAIL,ERROR};
boolean testsuccess = true;
boolean isError = false;
testsuccess will be set
to true if test case is executed successfully. If test case fails then addFailure(Test t,
AssertionFailedError e) will be called and we will set variable testsuccess to false.
Default value of isError will
be set to false and if any Exception/Error occurs while executing test case
then addError(Test
test, Throwable t) will be called and in this method we will set isError to true.
When
we implement org.apache.tools.ant.taskdefs.optional.junit.JUnitResultFormatter
interface we need to implement following methods.
- addError(Test, Throwable): As explained this method will be called when any error occurs while executing test case. We will set isError to true if/when this method is called.
- addFailure(Test, AssertionFailedError): As explained this method will be called when any test case fails. We will set testsuccess to false if/when this method is called.
- endTest(Test): This method will be called at the end of every test. We will use this method to set the value of testcase name and status of this test case (i.e. Pass/Fail/Error) and add it in a Collection (Vector in our case)
- endTestSuite(JUnitTest): This method will be called at the end of Test suite. We will use this method to write result of all tests in csv file.
- setOutput(OutputStream): Output stream as defined in ant task will be passed as an argument. We will store this as handler to local variable to use it later for writing our test results.
- setSystemError(String): This method is not used in our case.
- setSystemOutput(String): We are not using this method either.
- startTest(Test): Not this one too…
- startTestSuite(JUnitTest): Ok…not even this one J
Now
compile this class and export it as a jar. Add this jar in project where we
want to run test cases. In JUnit ant task of build file add following as
formatter. (Following is simplest of options to tell the build file to use this
new class for formatting results)
<formatter classname="com.customization.ant.junit.formatter.XLSFormatter" extension=".csv" />
|
Here we are using a very simple JUnit test case for employee
registration. Where method accepts data in form of a bean and registers
employee. If passed bean is null or values passed in bean are invalid then it
will return false and if bean is valid then employee will be registered and
method will return true. So following will be test class.
package com.sampleapp.service.test;
import org.junit.Test;
import com.sampleapp.service.EmployeeRegistrationService;
import com.sampleapp.vo.EmployeeBean;
import junit.framework.TestCase;
public class EmployeeServiceTest extends TestCase
{
EmployeeBean empBean=null;
EmployeeRegistrationService
svc = new
EmployeeRegistrationService();
@Override
protected void setUp() throws Exception {
System.out.println(getName());
super.setUp();
}
@Test
public void
testForNullEmployee()
{
boolean retval = svc.registerEmployee(null);
assertFalse("Registered
Null employee",retval);
}
@Test
public void
testForValidEmployee()
{
empBean = new EmployeeBean();
boolean retval = svc.registerEmployee(empBean);
assertTrue("Not able to
registered valid employee",retval);
}
}
|
When
we will run this test case following will be output on console
Apache Ant(TM) version 1.8.3 compiled on February 26 2012
Buildfile: E:\softwares\java\workspaces\keyur\Blogs\TestDrivenDevelopment\src\build.xml
parsing buildfile E:\softwares\java\workspaces\keyur\Blogs\TestDrivenDevelopment\src\build.xml
with URI =
file:/E:/softwares/java/workspaces/keyur/Blogs/TestDrivenDevelopment/src/build.xml
Project base dir set to:
E:\softwares\java\workspaces\keyur\Blogs\TestDrivenDevelopment\src
parsing buildfile jar:file:/E:/softwares/java/eclipse-jee-juno-SR1-win32/eclipse/plugins/org.apache.ant_1.8.3.v20120321-1730/lib/ant.jar!/org/apache/tools/ant/antlib.xml
with URI =
jar:file:/E:/softwares/java/eclipse-jee-juno-SR1-win32/eclipse/plugins/org.apache.ant_1.8.3.v20120321-1730/lib/ant.jar!/org/apache/tools/ant/antlib.xml
from a zip file
[echo] Testing
[junit]
[junit]
BUILD SUCCESSFUL
Total time: 287 milliseconds
|
And
following will be the file generated
So
this generated data was stored in following format to track results of each
build.
So happy
coding.
Subscribe to:
Posts (Atom)