Friday, August 28, 2009

Cool memory analysing tool for eclipse

Found a pretty cool tool to analyse heap dump files from within eclipse called Memory Analyzer. You can check for memory allocation and find out about your memory leaks, what processes are taking huge heap memory etc. More info can be found in the following links.

http://www.eclipse.org/mat/
http://ice09.wordpress.com/2009/06/28/eclipse-galileo-mat-and-a-little-spring/

The Perm Gen Exception in JBoss

We sometimes get the PermGen runtime exception thrown from JBoss when running our app. Following in the lines of the exception i stumbled upon two very useful articles explaining the same. This can be found at;

http://www.unixville.com/~moazam/stories/2004/05/17/maxpermsizeAndHowItRelatesToTheOverallHeap.html
http://narencoolgeek.blogspot.com/2007/08/heap-size-and-perm-size.html

As it states Permanent Generation space is different from the Heap space we set using th -Xms commands as Perm Gen space is used to store class objects / method objects generated using reflection. As we use Hibernate this space is definitely growing with time and as the first post above says we should set the -XX:PermSize and -XX:MaxPermSize when running our app servers in order to minimize the risk of these exceptions occurring. You can also set the -XX:+HeapDumpOnOutOfMemoryError option to tell the VM to generate a heap dump if OutOfMemoryError is thrown.


Wednesday, August 26, 2009

Java EE 6 Is Out

Wow some pretty cool features are out with the new Java EE 6 package. Nice post on the same can be found @ http://www.devx.com/Java/Article/42351/0/

Particularly I believe the Asynchronus type method invocation on Session beans is a pretty useful feature as some times we have to use MDBs to replicate the same kind of behaviour even though what we really need is just a non blocking call.

Saturday, August 22, 2009

Singleton not really singleton ??????

The power of Java reflection is amazing. Check the following post on how you can even access Singleton classes and create new objects . Amazing...

http://www.javaworld.com/community/node/892

Tuesday, August 18, 2009

Hibernate And Oracle User Defined Types

I came across a situation recently where i had to use hibernate to read an Oracle defined object type which was used as a column type in the database. A friend of mine shared a useful link which explained how to do this using hibernate 2. But as we were using hibernate 3 I had to do a few adjustments to get it working. Following I share the procedures you need to follow in order to get hibernate 3 working with Oracle objects.
First if you look at the Oracle object it self, it will look like something as given below;


TYPE audit_trail as object

(

UPDATED_BY VARCHAR2(30),

UPDATED_ON DATE,

DML_ACTION VARCHAR2(10)

)


Now to map this to a hibernate object first you need to create a DTO type class to hold the variables defined in the Oracle object. For this example i create a class called AuditTrail which represents the Oracle object.


public class AuditTrail implements Serializable{

private String updatedBy;

private Date updatedOn;

private String dmlAction;

public AuditTrail(){

}

/**

* @param updatedBy the updatedBy to set

*/

public void setUpdatedBy(String updatedBy) {

this.updatedBy = updatedBy;

}

/**

* @return the updatedBy

*/

public String getUpdatedBy() {

return updatedBy;

}

/**

* @param updatedOn the updatedOn to set

*/

public void setUpdatedOn(Date updatedOn) {

this.updatedOn = updatedOn;

}

/**

* @return the updatedOn

*/

public Date getUpdatedOn() {

return updatedOn;

}

/**

* @param dmlAction the dmlAction to set

*/

public void setDmlAction(String dmlAction) {

this.dmlAction = dmlAction;

}

/**

* @return the dmlAction

*/

public String getDmlAction() {

return dmlAction;

}

}


Then moving on you need to tell hibernate how to map the following class to the Oracle user defined type. We do this by implementing the interafce UserType which is provided by Hibernate.


package com.test;

public class AuditTrailUserType implements UserType {

private static final int SQL_TYPE = Types.STRUCT;

private static final String DB_OBJECT_TYPE = "AUDIT_TRAIL";

public int[] sqlTypes() {

return new int[] { SQL_TYPE };

}

public Class returnedClass() {

return AuditTrail.class;

}

public boolean equals(Object o1, Object o2) throws HibernateException {

if (o1 == o2) {

return true;

}

if (o1 == null || o2 == null) {

return false;

}

return true;

}

private boolean equals(final String str1, final String str2) {

return true;

}

private boolean equals(final Date date1, final Date date2) {

if (date1 == date2) {

return true;

}

if (date1 != null && date2 != null) {

return date1.equals(date2);

}

return false;

}

public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner)

throws HibernateException, SQLException {

//assert names.length == 1;

final Struct struct = (Struct) resultSet.getObject(names[0]);

if (resultSet.wasNull()) {

return null;

}

final AuditTrail user = new AuditTrail();

user.setUpdatedBy((String) struct.getAttributes()[0]);

user.setUpdatedOn((Date) struct.getAttributes()[1]);

user.setDmlAction((String) struct.getAttributes()[2]);

return user;

}

public void nullSafeSet(PreparedStatement statement, Object value, int index)

throws HibernateException, SQLException {

if (value == null) {

statement.setNull(index, SQL_TYPE, DB_OBJECT_TYPE);

} else {

final AuditTrail user = (AuditTrail) value;

final Object[] values = new Object[] { user.getUpdatedOn(),

convertDate(user.getUpdatedOn()), user.getDmlAction()};

final Connection connection = statement.getConnection();

final STRUCT struct = new STRUCT(StructDescriptor.createDescriptor(DB_OBJECT_TYPE,

connection), connection, values);

statement.setObject(index, struct, SQL_TYPE);

}

}

public java.sql.Date convertDate(Date date) {

return date == null ? null : new java.sql.Date(date.getTime());

}

public Object deepCopy(Object value) throws HibernateException {

if (value == null) {

return null;

}

final AuditTrail user = (AuditTrail) value;

final AuditTrail clone = new AuditTrail();

clone.setUpdatedBy(user.getUpdatedBy());

clone.setUpdatedOn(user.getUpdatedOn());

clone.setDmlAction(user.getDmlAction());

return clone;

}

public boolean isMutable() {

return true;

}

@Override

public Object assemble(Serializable arg0, Object arg1) throws HibernateException {

return null;

}

@Override

public Serializable disassemble(Object arg0) throws HibernateException {

return null;

}

@Override

public int hashCode(Object arg0) throws HibernateException {

return 0;

}

@Override

public Object replace(Object arg0, Object arg1, Object arg2) throws HibernateException {

return null;

}

}


Then you need to define in your entity class how to map this class. You do this by using the columnDefinition tag in the @Column annotation. Following shows how you should map the Oracle user Defined type in your entity class.


@Column(name="AUDIT_TRAIL_DTL",columnDefinition="AUDIT_TRAIL")

@org.hibernate.annotations.Type(type="com.test.AuditTrailUserType")

private AuditTrail auditTrail;


Well thats about it. You can seamlessly integrate Oracle object handling with hibernate by following the few simple steps described above.

Sunday, August 16, 2009

Time for some realistic planning

Ok so we have talked about iterative development, how to implements it then we got on to estimation and this post continues in that path to make it possible for you to provide reasonably realistic estimations and also talks about how to handle the customer when it comes to tight situations.

So you and your team come up with an estimate for the whole project and guess what, the customer thinks its way too long. If you think of it in the customer's perspective what he/she wants is to get that competitive advantage that they perceive the software you are developing will produce in the market before any of their competitors do. We all know what kind of a competitive world we all live in so your customer is no exception. Of course there are few things you can do at this moment.

First of all if you look back on how we made our previous estimation you could see we didnt take into account other overhead such as time spent on installations, updgrades, vacations, sick leaves, paper work etc. These all take considerable amount of time and you need to account for this in to your project estimation. Ok so now you will be asking how the **beep** are we gonna do that. Based on what? Ok chill chill. Variation to the rescue. Variation takes into account all the things that were stated before and counts for that. What is recommended is to have a Variation of 0.7 for a new project team. So how do you calculate the actualy number of days a developer will take to complete work within an iteration with the variation taken into account. Following is the calculation on how to do that;

1(the number of developers) x 20(project iteration size) * 0.7 = 14 days(The actual amount of time to complete the work within one iteration)

Multiply this by the number of iterations required for your first milestone and then you will get a realistic value on how many days are needed to complete the work. So now you have a realistic amount of days which your team feels confident about. Then you go to the customer and negotiate on what to do if this value is greater than the one he/she specified.

What you can do in this instance is lay down your user stories and ask the customer to first of all prioratize them according as they deem appropriate from high to low. You can give them a variation of values to base them such as 10-50 where 10 being the highest priority and 50 being the lowest.

After this is done you get this priority list and try to assign it to your iterations and see if you can get it everything in for the time specified. Something to note here is to assign the user stories according to the highest priority to the lowest. And one more thing is while doing this you should focus on only keeping your baseline functionality intact. Baseline functionality are the smallest amount of features that are needed to give a working solution to the customer.

With this amount still if the estimation is higher than what the customer expects then you have to sacrifise some of the user stories and push them back on to the next mile stone. And sadly you will have to notify the customer of the reality of the situation. One thing to note is to specify to the customer on what basis you came into this estimation. Then they will in most cases understand where your coming from. But thing to note is to always be upfront and honest to your customers because customer loyality once lost can never even be regained as i see it. What you have to specify to the customer is that the other features are not scrapped out completely, its just that they will only be available for the next milestone. If the customer still wants all that functionality then the only possible way to do that is by extending the number of iterations in your project which will eventually bring up the project deadline. But it is always the case where the customer will agree on scrapping some of the fuctionality until the next milestone.

In the end you have a realistically possible project due date that you feel confident about. And after all its better to under promise and over deliever and the vise versa. Hence you should be truthful about your estimation rather than building the project plan according to what the customer wants it to be which would only pave you a nice big path to failure :) .......


Well happy estimating and keep your projects in line.... In line of success ;)

Tuesday, August 11, 2009

The Dreadful Estimates

Well the title of this post it self is self explanatory aint it ;) ... We all know how hard it is to estimate something in our own lives. Moms will always ask how long will it take to clean your room, wife will ask how long will it take for you to get home, if you ask your dad for something he will ask how much does it cost.. So as the pattern goes on you can see all of us live in a world revolving around estimates. The same comes into play when estimates need to be made when an IT project is taken into consideration. Ofcourse all of us know how much of a dreaded task estimations can be mostly due to the fact of uncertainity that is filled with making some or most of the estimates. Aim of this post is to help all you poor souls and to take you out of your misery of doing estimates and doing them right:D ..

First of all what needs to be done is basically jot down all the user requirements and break them up into user storys which refelect all the functionality which needs to be provided by the software we are doing to build. A user story can be just a short 3-4 line description of what the functionality is all about with a title preceding. For example a typically user story will look like the following;

Title - Log-in users to the system
Description - Provide authentication capabilities to users loggin in to the system via a login menu.

That of course is one simple user story but you get what im trying to imply here yea ;) ... Ok so moving on, the next thing to do is to get together with your team with all the user storys you have come up with after many initial discussions with the customers and to decide an appropriate estimate for each user story you have defined.

One fun way of doing this would be by putting the user story on the table, explaining to your team what is exactly required by the user story and ask each one to provide an estimate of how long it will take to finish that specif story. Then you look at the spread of values taking everything into consideration. You then ask each developer based on what assumptions each of them came up with the estimates. What you do then is clarify each assumption with the customer that your team has come up which even you cant provide an accurate answer. Note that this is a pretty important step because if you go ahead with many assumptions to the coding stage that runs a high risk factor of the resulting software not being what the customer really wanted. Hence it is always advisable to talk to the customer up front with any assumptions you have and to get it clarified at that point of time so as to minimise the risk factor.

But of course at times even the customer would not know the correct answer to an assumption in which case what you should be doing is noting it down so that you have a track of any risk factors associated with each user story.

Then after going through the cycle of estimation and assumption clarification you ask your team to make another estimate now that most of the assumptions are resolved. Then you take the spread of estimated values which in this case would not be as much dispersed as before and take an average value from those values and come to an agreement with your team members of that value. Ofcourse one thing to note is this time should include not only the coding time but also the design, testing, integration, documentation(if needed) and deployment time.

If for some reason the estimated number of days for a user story is more than or equal to 15 days that usually means still there is something wrong somewhere. So what do you do in this situations? Well you got two options;

  1. Break down the user story into smaller functionalities, thereby spreading the number of days among the sub functionalities.
  2. There still might be unanswered assumptions that might fact for this estimate hence it is time to go back to the customer again and to further clarify those assumptions which would eventually lead you to re estimate the number of days.
Hence any of the following two ways can be used. After that what you do is add up all the estimated values you have come up with for all the user storys which would then make it possible for you to give the customer an estimated for the whole project which you feel confident about because you and your team have nailed down almost all of the assumptions and are pretty confident with the estimate.

So you come up with the estimate for the whole project. What if the customer says that the number you came up with is too much???? Yikes, didnt think of that now did ya? Well that my friend is a topic of its own. So stay tuned for the next post to see what you can do to overcome/handle such situations.