Featured Post

The great debacle of healthcare.gov

This is the first time in history when the president of the United States of America, or probably for any head of state around the world,...

Friday, March 21, 2008

Software Configuration Management (SCM) evalutation

I've used three different SCM or versions systems so far and those are Visual Source Safe (VSS, Microsoft has now changed the name), Concurrent Versions System (CVS) and Rational Clear Case. In the current project We're using Clear Case in our current project. It is to mention that I primarily am a user of these tools rather administration.

Clear Case

  1. Rebasing development stream with integration stream is a cool feature. I can revert the rebase back to my original stream if I don't feel happy after testing it. This is unlike CVS Update. Yes, the condition is applied: test it before hitting confirm button.
  2. Dynamic view gives me the chance to get the code without copying in my local disk though it is bit slow.
  3. In CC UCM, the changed classes are associated with the defect fix. But this process is really slow. In CVS and Bugzilla, we used to enter the name of fixed classes inside the fix note and that was hard to trace and manage.
  4. CC has a long learning curve. I had spent couple weeks to understand the concept of it when used for the first time.Publish Post
  5. Recommending a baseline is an idea that I liked in CC.
  6. Though the use of multi site has limitations, because of the way it's been designed, but it is helpful in projects which follow onshore - offshore development model.
  7. If your deliver operation follows by an unsuccessful rebase operation, not necessarily the rebase could fail only because of your action but sometime it could happen without giving you any clue of the reason, then the delivery and rebase forms a deadlock. The only solution is to remove the files versions of the last rebase, either using command line or clear case explorer, to continue to deliver from the development stream to integration stream
Resources

http://clearcase.weintraubworld.net/ - I liked the logo of the site especially
http://ask.slashdot.org/article.pl?sid=01/01/03/0319217&tid=128&tid=4 - It has a real stories of real life users
http://www.cg-soft.com/faq/clearcase.html#1.2.12

Thursday, March 20, 2008

Weird exceptions

Weird 1.
While integrating Spring with Struts, I had done a mistake in entering property name in the plug-in tag. Instead of property="contextConfigLocation" I typed "contextConfigurationLocation" and that caused me the below exception while starting the server:

Caused by: java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/action-servlet.xml]

Weird 2.
I had to fix my code after I faced below exceptions on Jan 28, 2008 because I had forgot to enter closing double quote while enclosing the include directive file name.

javax.servlet.ServletException: /WEB-INF/jsp/edit.jsp(2,25) Attribute has no value
at com.ibm.ws.webcontainer.jsp.servlet.JspServlet$JspServletWrapper.service(JspServlet.java:416
)

Wednesday, March 5, 2008

Oracle JDBC driver 9.2.0.1 bug

The following exception throws while batch updating using Hibernate 3.x with JDBC driver 9.2.0.1:

java.lang.NullPointerException
at oracle.jdbc.dbaccess.DBData.clearItem(DBData.java:431)
at oracle.jdbc.dbaccess.DBDataSetImpl.clearItem(DBDataSetImpl.java:3528)
at oracle.jdbc.driver.OraclePreparedStatement.clearParameters(OraclePreparedStatement.java:3401)

I found the solution from a posting in Oracle forum (http://forums.oracle.com/forums/thread.jspa?threadID=190963) and that says:

Oracle seems to have corrected one line in in
oracle.jdbc.dbaccess.DBData, method void clearItem(int i)

version 9.2.0.1:
if(m_items == null && i >= m_items.length) {

version 9.2.0.3:
if(m_items == null || i >= m_items.length) {

----
Another way to avoid this NPE is to avoid using the JDBC2 batch update feature.
For our (hibernate) implementation this corresponds to setting the property 'jdbc.batch_size' to zero.

Date difference dependens on the underlying JVM

If you write a utility method to get the difference between two dates, don't trust your system that it's gonna give you the same result all the time (Don't confused it with the Java slogan 'write once, run anywhere' !). The result you would get is totally dependent on the JVM, on which you are running your code. Follow the below case:

1. Create a date object from the Calendar:

Calendar cal = GregorianCalendar.getInstance();

cal.set(2008, Calendar.JANUARY, 31);
startDate = cal.getTime();

cal.set(2014, Calendar.MARCH, 31);
endDate = cal.getTime();

2. Get the difference in days:

long time1 = startDate.getTime();
long time2 = endDate.getTime();
long inDays = (time2 - time1) / 1000 * 60 * 60 * 24;


3. The result is 2250 days in -
Java(TM) 2 Runtime Environment, Standard Edition (IBM build 1.4.2_12-b03 20061117 (SR6 + 110979) ) and 2251 in Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_04-b05).

The true platform independent solution for the above issue is to add the hour:min:sec
as 23:59:59 while getting the date from the calendar.

cal.set(2014, Calendar.MARCH, 31, 23, 59, 59);

And through that you can write once and run anywhere until any new issue come up.

Note: Though I'm not yet sure but I found some posting that says this happens only if the date falls in some leap year.

Saturday, March 1, 2008

Unit Testing of DAO classes

Data Access Objects (DAO) are important components of any software system. Ideally the DAO classes shouldn't contain any logic other than few Data access logic. In that context, the DAO classes are less error prone while changing code. But there are several reasons, as described below, those forces us to write Unit test for DAO classes.
  1. In practice any code can breaks regardless of complex or simple
  2. Achieve 100% code coverage by unit testing
  3. Testing of data access logic whatsoever is written
Let me share one bitter experience from one of my project that motivated me to write unit testing for DAO classes in my next projects. A senior developer had put a seemingly harmless debugging code in a DAO method at mid night, day before the first working presentation to the Board of Directors, that prints the retrieved record's id from the database. The method was used by a business logic component that generates the next account number in the system and start over if the system has no existing accounts. The code definitely was tested by the developer before he delivered it to the version control but not by any Unit Test code rather manual functional test. He had not covered the scenario with freshly installed database because it takes a lot of hassles that includes execution of both 'remove and create' schema scripts i.e he had to access the database in some way moving away from the IDE. Anyway, the convinced developer left the office at mid night unknowingly injecting a disastrous statement that almost caused the project to be closed in the next day.

Our happy Engineering Manager had clicked the first link of application next day to create an account in the freshly installed system (we intentionally had kept the system fresh to show them how it will start from the very beginning when it would be deployed first) that caused the system to crash, with a NullPointerException trace printed on the browser, in front of the Board members who had come to see the already delayed project's first working presentation. Do I need to detail the situation in the demonstration room after that incident? I don't think so.

To consider unit testing for DAO classes we have to take the implementation technique based on the underlying technology used there. If hard code JDBC is used then Mock can be applied to test the behavior whether the Connection, Statement, ResultSet etc are called and closed properly. But if Hibernate is used to DAO , as O-R mapping for example, then it doesn't make sense to use Mock as the O-R mapper (e.g Hibernate) takes care of those raw objects. In that case, the testing goal would be:
  1. Test the O-R mapping and relationship configurations (e.g hbm.xml files)
  2. Query wrote in the method (e.g using Criteria or HQL)
And the above can't be tested using mock (to achieve the isolation for unit testing) rather use of in-memory database as Test Double (ref. Martin Fowler's article). Lets see a simple implementation of Fake Test Double technique using HSQLDB's in-memory database feature.

The following class provides the Hibernate Session to the test code:

public class HibernateUtil {
private static SessionFactory factory;

public static void setSessionFactory(SessionFactory factory) {
HibernateUtil.factory = factory;
}
}


The following class creates the test schema and also helps initialize and reset the schema:

public class TestSchema {
private static final Configuration config = new Configuration();
static {
config.setProperty("hibernate.dialect", "org.hibernate.dialect.HSQLDialect").
setProperty("hibernate.connection.driver_class", "org.hsqldb.jdbcDriver").
setProperty("hibernate.connection.url", "jdbc:hsqldb:mem:test").
setProperty("hibernate.connection.username", "sa").
setProperty("hibernate.connection.password", "").
setProperty("hibernate.connection.pool_size", "1").
setProperty("hibernate.connection.autocommit", "true").
setProperty("hibernate.cache.provider_class", "org.hibernate.cache.HashtableCacheProvider").
setProperty("hibernate.hbm2ddl.auto", "create-drop").
setProperty("hibernate.show_sql", "true").
addClass(Customer.class).
addClass(Account.class);
}

public static void reset() throws SchemaException {
Session session = HibernateUtil.getSession();
Transaction tx = session.beginTransaction();
try {
session.createQuery("Delete Customer").executeUpdate();
session.createQuery("Delete Account").executeUpdate();
} catch (HibernateException e) {
tx.rollback();
throw new SchemaException(e.getMessage());
}
finally {
tx.commit();
session.close();
}
}

public static void initialize() {
HibernateUtil.setSessionFactory(config.buildSessionFactory());
}

The actual Unite test class:

public class HibernateAccountDaoTest extends TestCase {

CustomerDao custDao;
AccountDao accountDao

public static void main(String[] args) {
junit.swingui.TestRunner.run(HibernateDaoTest.class);
}

public void setUp() {
TestSchema.initialize();
custDao = new HibernateCustomerDao();
custDao.setSession(HibernateUtil.getSession());

accountDao = new HibernateAccountDa0();
accountDao.setSession(HibernateUtil.getSession());
}

public void tearDown() {
try {
TestSchema.reset();
} catch (SchemaException e) {
e.printStackTrace();
}
}

public void testInsertAccount() {
// prepare data set
Customer customer = new Customer(1, "Name", "Address");
Account account = new Account(customer);
accountDao.insertAccount(account);

Account queriedAccount = dao.findAccountById(1);
assertNotNull(account.getBalance()));
}
}



Resources:

http://martinfowler.com/articles/mocksArentStubs.html - Truly speaking, I'd started liking mock object by reading this article
http://www.theserverside.com/tt/articles/article.tss?l=UnitTesting - I just followed this article's way
http://www.javaranch.com/journal/2003/12/UnitTestingDatabaseCode.html - The traditional approach of database code unit testing