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,...

Thursday, November 27, 2008

Be cautuios while using auto boxing and unboxing feature of Java 5

We recently migrated to Java 5 and started using the great auto boxing/unboxing feature of it. I've one method in a class that returns boolean primitive and I required to override it. I was so excited with this boxing feature that I started saving some lines of code by evaluating and returning the Boolean object directly. And when the code I started testing, had started throwing NullPointerException here and there. I got confused for sometime and took a little to understand while what happening there. Becuse the Java 1.4 debugging mindset was looking for a object that was accessed (using dot) but I didn't find any code that can cause that NPE. Then I realized that it is the Boolean object that was getting evaluated to primitives (actually Boolean.booleanValue() was invoked implicitely) and that is causing this NPE.

In prior to Java 5, as of my knowledge, this is first time Java evaluates any object internally and more over that is totally implicit. Once a programmer is used to of this feature he won't have any trouble but first time it is little confusing even though the theory is known to one

Resources:

http://fupeg.blogspot.com/2007/07/auto-unboxing-in-java.html

Friday, November 21, 2008

BASEL II

BASEL II is a regulatory framework introduced as BASEL I has been found not-enough to enforce risk management on financial institutions.

It has three pillers:

Economic Capital
Regulatory Capital
Market information disclosure

It targets to mainly manages the bellow three kinds of risks:

Credit Risk
Market Risk
Operational Risk


Resources:

http://www.riskglossary.com/link/credit_risk.htm

Monday, November 10, 2008

Hibernate: Issue with Char data type

When doing any query, using Criteria object specially, the Char data type doesn't work in the where clause. The query generated by the Hibernate works perfectly fine on the Oracle console and returns rows but Hibernate returns no rows. The reason might be the Char data type fills the remaining capacity with empty space and Oracle is intelligent enough to ignore those extra spaces while doing query match. But Hibernate is not that smart enough. So it doesn't get the exact match even though visually both the values look same.

The workaround is not to keep char(xx) type for the columns that might be used in the query's where clause. This is economic approach as well as it saves storage space. But if the data base can't be touched then the workaround is, create a view on top of the table and in the view, trim the char(xx) column to get rid of all trailing spaces. Or another work around could be pad the trailing spaces while doing the query but I personally don't like this approach.

References:

http://www.javalobby.org/articles/hibernate-query-101/
http://www.hibernate.org/388.html
http://forum.hibernate.org/viewtopic.php?p=2382506

Monday, August 4, 2008

Ant

Create an Ant script to concat multiple text files:

<?xml version="1.0"?>

<project name="concat files" default="build">
<target name="build">
<concat destfile="concatenated.txt" fixlastline="yes">
<path>
<pathelement path="<file_path>\text1.txt" />
<pathelement path="<file_path>\text2.txt" />
</concat>
</target>
</project>

Commands:

ant -buildfile build-file.xml build-target

Thursday, July 3, 2008

Oracle Tips - DML

1. Connecting through sqlplus from console

:> sqlplus user_name/user_password@database_name (fully qualified name as in tns.ora)

2. To connect to another user while already connected to some other user:

sqlplus> conn user_name/user_password@database_name (fully qualified as in tns.ora)

3. To see the currnet schema name that you're connected to:

select sys_context( 'userenv', 'current_schema' ) from dual

4. To see all the table names of the current user:

select table_name from user_tables;

5. To see the constraints of a table:

select table_name, constraint_name, constraint_type from user_constraints;

6. All table and column names of particular schema

select b.table_name, a.column_name from user_tab_columns a, all_tables b where b.owner = 'SCHEMA_NAME'
order by b.table_name

7. Convert row values into columns

Converting row to column is only possible using the below approach when you've predetermined values in the rows.

Approach-1: using case...when...then statement

select column_name1, column_name2,
max((case when column1 = 1
then value_col end)) as "user_defined_name1",
max((case when column1 = 2
then value end)) as "user_defined_name2"
From
Table_name
[group by column_name1, column_name2]


Approach-2: using left outer join:

select column_name1, column_name2,
t1.column1 as 'user-defined-name1',
t2.column1 as 'user-defined-name2'
from
table_name t1,
able_name t2
where
t1.pk = t2.pk
and t1.column1 (+) = 1
and t2.column1 (+) = 2


6. Update column

Apparently it seems harmless of the below update statement -

update table_name t set column_name =
(select column_name from another_table_name a where t.id = a.id and ....)

The problem is, each and every records would be updated even though the subquery returns few matches. The unmatched records in table_name would be updated with null. So there would be unwanted update that might not be expected. Moreover if the table_name has 10 million records, it would take humongous amount of time if you don't care about that null update.

The similar update can be achieved without getting updated with null for the unmatched records in table_name is -

update (select t.column_name, a.column_name from table_name t, another_table_name a
where t.id = a.id and ....) set t.column_name = a.column_name

The precondition is, the t.id and a.id must have unique constraints enabled or they're primary key in the corresponding tables


7. Check out if any object is currently locked out

select object_name, o.object_id from user_objects o, v$locked_object l
where o.object_id = l.object_id

8. Insert special characters like '&'

Set Define Off;
insert statement e.g. insert 'abc&d' into table_name (col1);
Set Define On;

9. See the comments on column

select table_name,column_name,comments from user_col_comments

10. Print the time difference inside a pl/sql

start_time = dbms_utlility.get_time;
// process data
end_time = dbms_utility.get_time;
dbms_output.put_line('time elapsed: ' || (end_time - start_time)/100 || ' secs');

11. SQL*PLUS options:
SQL> set timing on -- shows the elapsed time at the end
SQL>

12. Custom Order:

Use DECODE function in the order by clause instead of the column directly
e.g. Order By DECODE(column_name, 'AA', 1, 'A', 2, 'BB', 3, 'B',4, 'CC', 5, 'C', 6, 'DD', 7, 'D', 8, 'EE',, 'E',10)

13. Connect By:

TBD

14. using 'WITH':

TBD

15. prompt for variable substitution:

Ampersand (&) is used to prompt for the variable substitution. Also ACCEPT can be used to prompt for the customized prompt text e.g.
ACCEPT variable CHAR PROMPT 'Enter Variable: '


HIDE option can be added at the end to not to echo the entered password, for example.

16. Run Unix commands on the SQL prompot

use HOST before the Unix command
e.g.
SQL>HOST ls
SQL>HOST pwd

17. Explain Plan
use SYS.PLAN_TABLE$ in case you don't have privilege to create a plan table

Resources:
https://www1.columbia.edu/sec/acis/dba/oracle/faq-sql.html

http://www.dba-oracle.com/ - has useful queries

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:969054700346631425 - Bulk move

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:273215737113 - Update columns from other table

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:974699100346868838 - should we use db user or application user?

http://www.adp-gmbh.ch/ora/misc/integrity_constraints.html - Oracle's Integrity Constraints

http://jenniferlinca.wordpress.com/ - Blog contains good Oracle stuffs

http://forums.oracle.com/forums/message.jspa?messageID=2348825 - Fun to read

http://www.dba-oracle.com/art_9i_indexing.htm - Performance tuning with index

http://www.orafaq.com/node/855 - Common errors using Outer Join

http://marist89.blogspot.com/ - Wonderful quote from the site - "The trouble with the world is that the stupid are cocksure and the intelligent are full of doubt." --Bertrand Russell. A good database blog

http://www.orafaq.com/forum/t/54714/0/ - Batch delete

http://forums.oracle.com/forums/thread.jspa?threadID=620843 - custom order by

http://www.sqlsnippets.com/en/topic-12186.html - Convert Rows to Columns

http://www.dba-oracle.com/t_converting_rows_columns.htm - Convert Rows to Columns

http://www.orafaq.com/node/855 - Error prone Join

Saturday, June 28, 2008

Capability Maturity Model (CMM) goals - quick reference

The goals to achieve a CMM level is summarized for quick reference:

CMM Level 2 (Repeatable)

Projects in Level-2 organizations have installed basic software management controls. Realistic project commitments are based on the results observed on projects and on the requirements of the current project. The software managers for a project track software costs, schedules, and functionality; problems in meeting commitments are identified when they arise. Software requirements and the work products developed to satisfy them are baselined, and their integrity is controlled.

Key Process Areas (KPA)

  • Requirement Management
  • Software Project Planning
  • Software Project Tracking and Oversight
  • Software Subcontract Management
  • Software Quality Assurance
  • Software Configuration Management

Goal 1: System requirements that are allocate to software are controlled to establish a baseline for software engineering and management use

Goal 2: Software plans, products, and activities are kept consistent with the system requirements allocated to software

Goal 3: Software estimates are documented for use in planning and tracking the software project

Goal 4: Software project activities and commitments are planned and documented

Goal 5: Affected groups and individuals agree to their commitments related to the software project

Goal 6: Actual results and performances are tracked against the software plans

Goal 7: Corrective actions are taken and managed to closure when actual results and performance deviate significantly from the software plans

Goal 8: Changes to software commitments are agreed to by the affected group and individuals

Goal 9: The prime contractor selects qualified software subcontractors

Goal 10: The prime contractor and the software subcontractor agree to their commitments to each other

Goal 11: The prime contractor and the software subcontractor maintain ongoing communications

Goal 12: The prime contractor tracks the software subcontractor’s actual results and performance against its commitments

Goal 13: Software quality assurance activities are planned

Goal 14: Adherence of software products and activities to the applicable standards, procedures, and requirements is verified objectively

Goal 15: Affected groups and individuals are informed of software quality assurance activities and results

Goal 16: Noncompliance issues that cannot be resolved within the software project are addressed by senior management

Goal 17: Software configuration management activities are planned

Goal 18: Selected software work products are identified, controlled, and available

Goal 19: Changes to identified software work products are controlled

Goal 20: Affected groups and individual are informed of the status and content of software baselines

Saturday, June 7, 2008

JEE software development estimation

Software estimation is one of the key as well as mystifying subject area in software engineering. There is an ongoing debate between two groups whether developing a software is an engineering discipline or a liberal science. The group that claims that software development is a science often put on the proof of it's inaccuracy in estimating a software development, consistently over the period of time.

There are several well known software estimation techniques or models like Line of Code (LOC), Function Point Analysis (FPA), COCOMO and some others. I've studied few of those estimation process but found overly complex to its value proposition or, to some extent, irrelevant to the projects that I was involved so far in my professional career. Most of my prior software development projects are based on J2EE and to develop Financial and CRM solutions. May be those estimation models are useful for many projects but at least I didn't find those very useful or cost effective in my projects. But I'm no way claiming those models or process as not useful.

In my projects I've been using some of the very straight forward and simple techniques to estimate the development effort (not the entire Software Project through) and those estimations were accepted by the project manager with very minor tweaks. The benefits that I get by using my simpler model are:
  • The ball park figure asked by the project manager (PM) can be provided with a 10-15% error margin
  • If PM asks for the base behind your estimation, you've something to defend your number
  • When your project manager pushes you to include additional feature(s) in the middle of development, you can bargain confidently that is backed by your detail estimation
  • People trust documents rather than your verbal explanation (but it may vary person to person and depends on the image in the team)
The driver behind my estimation model is experience and historical data. The factor I use in the model is mostly based on my experience and also supported by the historical data of the project. So it can't be mathematically or statistically proven but has justification. The factors I used in the model are:
  1. Complexity
  2. Familiarity
  3. Comfort level
  4. Implementation's spreading (number of places in the system the feature would've impact)
  5. New feature
  6. Modification of existing feature
  7. Up gradation of existing feature
  8. Change distribution
  9. Implementation items (e.g. Business Logic class, Data Access class, Utility class, Configuration file, Database table, Resource file, User Interface class/files etc.)
  10. Requirement stability (e.g. clarity)
  11. Unit/Integration/Functional test case development
  12. Buffer zone

Using the past experience in the project, I've given a value to each of the factors mentioned above and finally add-up the the numbers to get the time estimated to complete the feature implementation.

Here is an example of estimation calculation using the above estimation technique:

Initially it was little simpler as below:

C: Type of change (New=1/Upgrade=2/Modify=3)
D: Estimated complexity (Low=1/Medium-2/High-3)
E: Level of comfort (1 - Did similar before/2 - Didn't do but know/3 - First time doing)
F: Num of new view file
G: Num of view files to modify
H: Num of New Business methods
I: Num of Bussiness methods to modify
J: Num of new Dao methods
K: Num of Dao methods to modify
L: Num of new tables
M: Num of tables to modify
N: Change is for (e.g. how many products)

Estimation: C/1.5+F*3+G*1+H*3+I*1.5+J*2+K*1.5+L*3+M*1) *N * D/2

But later I found that the estimation that I was getting out of the formula was giving me the value with wide error margin and also didn't cover some fine aspect of estimation items. So I later refined it as below that worked for me almost with no issues for 6 releases (each release time spans 2-3 months of development and implementation) over 1 and half year

J: Type of Change (New=3/Upgrade=2/Modify=2/NoChange=0)
K: Estimated Complexity (Low=1/Medium=2/High=3)
L: Comfort Level (1 - Done similar before/2 - Have conceptual idea/3 - No idea/It can be fraction value)
M: Num of new view file
N: Num of view files to modify
O: Num of New Business methods
P: Num of Bussiness methods to modify
Q: Num of new Dao methods
R: Num of Dao methods to modify
S: Num of new utility methods
T: Num of utility methods to modify
U: Num of configuration files to modify
V: Num of new tables
W: Num of tables to modify
X: Num of places change would happen
Y: No. of Unit Test Cases
Z: Integration Testing? (1/0)
AB: Estimation without testing =(J/2*(M*3+N*1+O5*2+P*1.5+Q*1.5+R*0.75+S*0.5+T*0.25+U*0.1+V*2+W*1)*X*K/3*(L))+Y*1
AC: Estimation with testing (in hr) = =AB*1.5
AD: Estimation with testing (in day) [ceiling] =CEILING(AC/8,1)
AE: Estimation without testing (in day) = =AB/8
AF: Estimation without testing (in day) [ceiling] =CEILING(AE,1)

If a single point estimation needs to be communicated, I use the below famous formula to get a realistic estimation figure:

Estimated Day =(AC+2*(AC+AE)+AE)/6.0

It is certain that the above model would be different for other than Java based web application built for enterprises. In that case the value of factors and criteria would require to be tweaked or twisted

Resources

http://www.stellman-greene.com/aspm/images/ch03.pdf

Monday, May 26, 2008

Why development of Unit Test classes should go in parallel along with development

The question that always strikes me about the unit testing is, why people across the board give less priority on writing unit testing code over functional testing when it comes to software quality. I have been in numerous number of software development project and in most of the cases I found that trend, specially when we needed to do a trade off to hit deadline, the first thing gets under the guillotine was the unit testing. Some cases there are pure ignorance on the importance of the unit testing and in other cases where the importance of the unit testing was acknowledged, the unit testing didn't end up in a good coverage (I consider 80% to 90% as a good coverage) of the production code.

I had seen two types of practices in my projects when it comes to create unit test classes. First practice is to set aside the unit testing during the software development phase and once we've a running application in production, we put some time on code quality and maintainability. This can be defined as "After the fact Unit Testing". The management starts pushing the development team to write unit test classes to get 100% code coverage or at least close to 100%. And the second practice, let's call that as "Unit Testing in Parallel", which is kind of not so popular, is to take unit testing as part of the development from the very beginning and force developers to deliver test classes along with production code. In projects, where the unit testing is deemed as necessary but discarded for the sake of project strict deadline, they tend to follow the first practice mentioned above. I'm not considering the Test Driven Development (TDD) practices in this discussion as I believe that's too extreme and extremely rare in the current software industry.

Let's take a look into the "After the fact Unit Testing" approach. It's never gonna happen that you would be able to get a good coverage of unit test classes and even you get some, the quality of unit test code would be horrible. The reason is that you would write to get the coverage or fulfill the management needs not the developers need. There are other downside that I would discuss soon.

In the "Unit Testing in Parallel" approach: This should be the ideal approach when you start a project development. There is one downside, unit test takes extra effort on top of production code that the project management team or customer don't want to effort it initially until they start getting high number of defects production when a simple change in requirement is accepted by the project at the end of the game.

I would advocate for the second approach and explain why this is much much superior to any other approach with the way out of all short falls of this approach.

When a developer starts developing a method, he definitely has few test cases in his mind to validate his implementation. The test case can be either developed in mind before the implementation of the method has started or some time at the end of the development to check if the developed method works as expected. Lets consider the development of the below production code development:

public double convertCurrency(double foreignCurrencyAmt, double exRate) {

return baseAmt / exRate;

}

When the above method is being developed, the developer tests the code by passing sample data and validate against expected return value. Most of the time this testing is done verbally in case it straight forward like the above logic but the complex logic is tested by running the application or by some other means.

Suppose the developer validates his logic by passing foreignCurrencyAmt as 700 and exRate as 70 and expecting the converted currency amount as 10. Either he would test it inside his mind or by running the application with above mentioned data set. So, we can divide the development into two parts - logic development and logic validation. Hypothetically we can distribute 70% time to logic development and 30% time to logic validation of the entire development time of production code.

In first approach where unit testing is done after the development is finished, when the developer would do the development of unit test cases, he would have to spend at least same amount of time (i.e. 30% time) to reconstruct the validation logic. Practically this time would be more because he would need to recall the production code logic again (unless the code is very simple like the earlier example code). My point is here, this 30% time to construct the validation logic (input data set and expected return values) would be duplicated both in the development of production code and development of unit test code. And this effort duplication can be avoided if the production code and unit test code are developed in parallel (pseudo parallel is the most appropriate phrase). There are some overhead of writing formal unit testing code that takes, for example, X amount of time, that we can't avoid and would definitely impact the project time line. I don't want to stress more on the advantages of spending this overhead time in this blog as there is no debate on this. I just want to end my discussion here with this statement that we're able to save the development time (the hypothetical 30% time that is duplicated to construct validation logic) if we develop unit testing code in parallel with production code.

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

Friday, February 29, 2008

WebSphere Application Server

Websphere Application Server 5.1: Test Environment Setup

1. In Configure tab
  • Enable administration console
2. In Environment tab
  • Open Java VM Settings section add any system properties you want in your application like logger class or environment information (dev, sys or prod etc.)
3. In Variables tab
  • Open Node Settings
    • set the ORACLE_JDBC_DRIVER_PATH to jdbc driver jar location
4. In Security tab
  • Open JAAS Authentication
    • Add an alias: user-auth;
      • Username : <db-user>
      • Password : <password>
5. In DataSource tab
  • Open Server Settings section
    • In JDBC Provider List set
      • Oracle JDBC provider: Oracle Thin Driver;
      • Implementation Class: OracleConnecctionPoolDataSource
  • Define DataSource after choosing the just created Provider
    • Class path = {ORACLE_JDBC_DRIVER_PATH}/<jdbc-driver>.jar
    • Data source
      • 1st Screen
        • Oracle Thin Driver
      • 2nd Screen
        • Name: jdbc/MyDataSource
        • JNDI Name: jdbc/MyDataSource
        • Component Managed Auth Alias: user-auth
        • Container managed auth alias: user-auth
      • 3rd Screen
        • Port number: <oracle-port> note: default port is 1521
        • URL:jdbc:oracle:thin:@<db-host-name>:<port>:<schema-name>
6. Completed

Useful commands:

Check out the version of installed WAS in Solaris:

$[WAS Installed location]/bin/versionInfo.sh

Thursday, February 28, 2008

A Comparative analysis of Unit Testing in isolation

What I understand about Unit Testing can be expressed using this simple statement "Unit testing is all about the testing in isolation". And that makes the Unit Testing unique from the other form of testing like Integration Testing, Functional Testing or System Testing. I don't see any debate about the goal of Unit testing but when it comes to implementation of the testing and how to isolates the System Under Test (I followed Martin Fowlers naming conventions here) there are lots of differences in opinion and implementation technics. Lets start to talk about this by showing the components of a unit test-

  1. Unit test class, usually written in JUnit framework
  2. System Under Test (SUT), the targeted class that I'm gonna unit test and
  3. Collaborators classes, SUT interacts with those classes to accomplish it's goal

To implement the Unit testing in isolation, today I'll consider three popular approaches and will try to show the comparative advantages and disadvantages from a developer point of view. Those three popular approaches to achieve the isolation are:

  1. Point cut approach
  2. Stub approach
  3. Mock approach

Point cut approach uses the Aspect Oriented Programming (AOP) technique to implement the isolation. The principal behind this is, point cut the collaborator method calls from SUT and eventually return the expected outcome from the method. Usually an Advice class is written that point-cuts the method calls. The advantages of this approach are:

  • The SUT is unaware about the point cut and can be configured externally.
  • No mock or stub objects need to be written. etc.

The disadvantages are:

  • The test data (expected outcome) are stored not in the test class itself.
  • Becomes complicated when the point-cut advice needs to provide different response for different test cases.
  • The developer needs to be aware of multiple classes and files incase use xml as configuration for point-cut
  • Not possible to verify the behavior of the calls

Stub approach stub out the collaborator by injecting the Stubbed collaborators and hence isolate the SUT from having the real collaborators method calls to be invoked. The advantages of this approach are:

  • It isolates the SUT from each collaborators replacing with Stub versions hence makes it easy to understand and maintain
  • Don't bother about how the method has been implemented i.e. overlooks the implementation detail and looks for the outcome (it is known as state verification)

The disadvantages are:

  • It doesn't perform the behavior verifications

Mock approach is more like Stub approach and uses mock objects to isolate the SUT from the collaborators by injecting the Mock collaborator objects. The hallmark difference of Mock approach from the stub approach is that the Mock approach considers the behavior test as well. So the mock approach has all the benefits of Stub approach has and has also the ability to perform the behavior verifications though some people see this one as demerits.

Now see a simple testing implementation in Mock approach using a popular Mock Testing Framework, EasyMock.


public class SampleServiceTest extends TestCase {
private SampleDao daoMock;
private MockControl daoControl;

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

public void setUp() {
daoControl = MockControl.createControl(SampleDao.class);
daoControl.setDefaultMatcher(MockControl.EQUALS_MATCHER);
daoMock = (SampleDao)daoControl.getMock();
}

public void testDeleteSampleData() {
SampleDataId dataId = new SampleDataId(1);
SampleData data = new SampleData(dataId);
SampleDataAudit audit = new SampleDataAudit(sampleData);

daoMock.findData(dataId);
daoControl.setReturnValue(data);
daoMock.evict(data);
daoControl.setVoidCallable();
daoMock.deleteSampleData(dataId);
daoControl.setVoidCallable();
daoMock.insertSampleDataAudit(audit);
daoControl.setVoidCallable();
daoControl.replay();

SampleService csi = new SampleService();
csi.setSampleDao(daoMock);
csi.deleteSampleData(dataId);
daoControl.verify();
}
}


Monday, February 4, 2008

In Java: That I used to get confused

Inheritance

Overriding Access Modifier:
In overriding, the access modifier can allow more. i.e. If the access modifier is declared as protected in the parent, the child can only change it to public.

Hiding member method:
In case of class methods, if the child class declares the same class method with the same signature (that is the combination of method name, parameter number) then it is considered as the child hides the parent's method. In that scenario, the method actually invoked depends on from where the class method is being called.
Cat cat = new Cat();
Animal animal = cat;
The Animal.classMethod() will invoke the Parent's (Animal) and the Cat.classMethod() will invoke the Child's (Cat) implementation.
This is somewhat opposite in case of instance method overriding; the method gets invoked depends on the instance of the class.

Hiding member variable:
If the child uses any member variable of the name same as in parent class, even if the types are different, the field variable is considered to be hidden by the child. In this case super keyword needs to be used to access the parent 's member variable. This is known as field hiding.