Saturday, November 29, 2008

I pity Zardari

Every time a civilian government takes an oath in Pakistan, Indian establishment takes a sigh of relief in hope things can be normal again. But an assumption of Government being in charge also makes it complacent. Last time with Nawaz Sharif its Army orchestrated Kargil intrusion. This time with Zardari, elements in it's intelligence did the Mumbai massacre. Actually its been pity being head of a civilian government in Pakistan. A head who does not know what goes on under his nose. Mr. Zardari we know its tough but its really sad and pity. I am sure it does not feel good to be in control of only 1/3rd of the country and your own intelligence and Army bosses running a parallel government. Its pity it is. It also shows when you made an U-turn on sending your ISI chief to Delhi to assist after promising it on phone. India I am sure does not know who to blame and talk to? It does not know how many Pakistans it is dealing with. One face of Pakistan appears to be a friend but not in control. Others actively engaged in terrorism with help of under world Dons enjoying state hospitality in Karachi for years. No one could believe that a huge stock of arms and ammunition and trained men were dispatched to Mumbai without involvement of your own intelligence agencies. And if it happened without you knowing it is really really sad and dangerous. We had very high hopes from you but are disheartened to find if you are even in control of your country but still expect you to strengthen the hand of friendship that was extended after your election. Don't make our hope short lived.

Thursday, November 27, 2008

There can't be any reason for terrorism

As humans we are all animals. But we are also blessed with brains capable of making sure that the world does not become a jungle. After what happened in Mumbai I am sure there will be a series of finger pointing to follow. But it only proves that the threat of global terrorism is still serious and refuses to die. Global terrorism is not only directed towards British and American citizens but are also that are planned, funded and coordinated from across the nation's borders. The news has already been coming out that Mumbai attacks were planned and executed with the help of groups based in Pakistan. Also comes a new phenomenon of hijacking a civilian trawler in high seas and then using it to launch an attack, a tactic that challenges security apparatus of any nation. This is a high time for countries to make a decision if they want to be part of a civilized world or choose to being a failed state. Pakistan has a new civilian administration and an onus wrests on them to make this decision. If not a direct involvement of its government but terrorist groups still operating with complete impunity with help of its intelligence agencies is not a sign of trust that two neighbors must have. A world can only be a better place when everyone works together for its better future not by sponsoring mad killings of innocent people.

Sunday, November 23, 2008

Saturday, November 22, 2008

Toplink10g to Eclipselink Migration

No brainer and Toplink team has done a great job to make it very simple and a matter of running a script. Even though the steps are clearly documented on http://wiki.eclipse.org/EclipseLink/UserManual but you may run into some gotchas. Some of the very advanced Toplink mappings use amendment methods and post insert, build events etc. These information are stored in Toplink's classes and descriptors XML files. The migration scripts of Eclipselink does not replace these classes even if the mwp file is successfully opened in the workbench. The solution is very simple.. Replace all classes starting with package name oracle.toplink to org.eclipse.persistence under the classes/ and descriptors/ directory of the Toplink workbench. And following script can be handy as well:

for i in `ls *`
do
sed "s/$1/$2/g" $i > t;
mv t $i;
done

Saturday, November 15, 2008

Timer service in Oracle Coherence

It would be nice to have a Timer Service that runs inside a Coherence Cluster and can execute pre-established Jobs at a certain time of a day, everyday? Such a component can be written as a separate application or configured inside Coherence. Not off-the-shelf available but I have uploaded a simple Quartz based implementation on Miscellaneous Components website. Please read More...

Thursday, November 13, 2008

Managing a collection of data and running Query By Example with Coherence

Problem (1): Coherence NamedCache extends java.util.Map i.e, the data to be managed in the cache must be in a <key>, <value> pair. One of the challenges to manage just a Collection of keys or elements in a cache is to associate these keys with some values. If Values are not given we need to use a Serializable Object that can become it's values (or Nulls). So your collection {a, b, c ..., z} becomes [{a, <o>}, {b, <o>}, ... {z, <o>}] with o being:

public class o implements Serializable { }
Problem (2): Running Queries against the Keys. Coherence supports KeyExtractor that extracts attribute values from cache keys instead of on the Values. The Filter will look like filter = new EqualsFilter(new KeyExtractor("getAge"), value); that matches if the getAge () method of a cache key Object is equal to the value.
Problem (3): Query By Example. This is another challenge. Coherence cache supports Filter mechanism that can be run on existing value for its attributes. Out of the box there is no mechanism that can parse Query By Example. QBE means an Object with partial attribute set is passed to find out all or any cache keys that have same attribute values. Lets introduce a Discoverer class that has following:
protected Filter getFilter(String method, String value) {
Filter filter = null;
if (!(value.equals("*") || value.equals(""))) {
filter = new EqualsFilter(new KeyExtractor(method), value);
} else {
filter = new GreaterEqualsFilter(new KeyExtractor(method), "");
}
return filter;
}
Problem (4): Combining Key searches into one service to support multiple key types. First step is to make sure that each cache stores a specific type of Keys. And if one type of Key is very different from another type of key then create dedicated Discoverer classes that specializes in finding a specific type of Key. Cache configuration could look like:

<caching-scheme-mapping>
<cache-mapping>
<cache-name>Key1
<scheme-name>distributed-scheme
<init-params>
<init-param>
<param-type>string
<param-value>com.some.Key1
</init-param>
</init-params>
</cache-mapping>
<cache-mapping>
<cache-name>Key2
<scheme-name>distributed-scheme
<init-params>
<init-param>
<param-type>string
<param-value>com.some.Key2
</init-param>
</init-params>
</cache-mapping>
</caching-scheme-mapping>

Then maintain a local map that stores cache to Object type mapping as:
XmlElement elem = null;
NamedCache nCache = null;
XmlElement cSMap =
CacheFactory.getConfigurableCacheFactory().getConfig().getElement("caching-scheme-mapping");
Iterator mappings = cSMap.getElements("cache-mapping");
String dataType = null;
while (mappings.hasNext()) {
elem = (XmlElement) mappings.next();
nCache = CacheFactory.getCache(elem.getElement("cache-name").getString());
try {
dataType =
elem.getElement("init-params").getElement("init-param").getElement("param-value").getString();

objToMap.put(nCache.getCacheName(), dataType);
mapToObj.put(dataType, nCache);
} catch (Exception exp) {
// -- Log the Exception and skip adding Indexes
log(exp);
}
}
Once mapping is known, create a Discoverer as:
public Collection getKeys(Key filterKey) {
IDiscoverer disc;
try {
disc = (IDiscoverer) keyDiscoverer.get(filterKey);
if (disc == null) {
// -- Even though the cost of Reflection is high but to it takes
// -- a microsecond to initialize an Object. To reduce the
// -- reoccuring cost use a local Map to store the instance
String cName = filterKey.getClass().getName();
String discName =
cName.substring(cName.lastIndexOf(".") + 1) + "Discoverer";
disc =
(IDiscoverer) (this.getClass().getClassLoader().loadClass("com.some." +
discName)).newInstance();
keyDiscoverer.put(filterKey, disc);
}
return disc.getKeys(filterKey);
} catch (Exception exp) {
log(exp);
}
return null;
}
Once the getKeys () is delegated to right Discoverer, the Discoverer object can work on the key's attributes directly. One example being:

public Collection getKeys(Key key)
throws IllegalAccessException, InvocationTargetException {

if (!(key instanceof Key1)) {
return null;
}

String cName = key.getClass().getName();
NamedCache nCache =
CacheFactory.getCache(cName.substring(cName.lastIndexOf (".") + 1));
Key1 pKey = (Key1) key;
Filter filters[] = new Filter[2];
filters[0] = getFilter("getAttribute1", pKey.getAttribute1());
filters[1] = getFilter("getAttribute2", pKey.getAttribute2());
Filter composite = new AllFilter(filters);
return nCache.keySet(composite);
}
As you see the code uses Java Reflection where ever possible but avoids it in re-occurring calls. The Specialized classes like Key1Discoverer on the other hand works on class attributes directly.
This is a simple but quite efficient approach to manage a collection of data and run Templated Queries on it. Coherence cache configuration dictates Object type to be stored in a cache. Discoverer provides a mechanism to have a specialized way of finding keys and manipulate QBE and single service class using Java reflection allows to scale the key types and its discovery to any number of types. Would be glad to see any suggested improvements...

Friday, November 07, 2008

Transfer of Power pattern

This is a little Java trick that came out of the following Problem Statement: How to call a pre-defined method of an invoking class if it is defined in it? Or, invocation through precedence.
If I have three classes Invoker1, Invoker2 and MyUtility and both Invokers call a method of MyUtility, Is it possible for MyUtility to call a method of the Invoker if defined instead of it's own? I call it a transfer of power pattern - An Invoker class dictates what to call not by condition or heirarchy but by definition of its location.

// -- MyUtility.java
public class MyUtility {
private void preInvocation () {
...
}
public void doSomething () {
System.out.println ("I am doing something");
}
}
// -- Invoker1.java
public class Invoker1 {
public void invoke () {
new MyUtility ().doSomething ();
}

public void preInvocation () {
System.out.println ("Invoker1's preInvocation called");
}
}
// -- Invoker2.java
public class Invoker2 {
public void invoke () {
new MyUtility ().doSomething ();
}
}
The way this application works is if preInvocation method is defined in an invoking class, MyUtility should call it instead of it's own. A workflow is defined in a way that does not require a tight integration with an Object hierarchy.

How to do it? Define MyUtility in the following way:

// -- MyUtility.java
public class MyUtility {
private void preInvocation() {
System.out.println("Pre-Invocation of MyUtility");
}
public void doSomething() {
Throwable t = new Throwable();
StackTraceElement[] elements = t.getStackTrace();
String callerClassName = elements[1].getClassName();
Class clz;
try {
clz = Class.forName(callerClassName);
Method method =
clz.getDeclaredMethod("preInvocation", null);
method.invoke(clz.newInstance(), new Object[] { });
} catch (Exception exp) {
// -- Any Exception and call it's own.
preInvocation();
}
}
}
# Run Invoker1 => Invoker1's preInvocation called
# Run Invoker2 => Pre-Invocation of MyUtility
Have fun!

Saturday, November 01, 2008

I endorse McCain, Because...

@11/01/2008: After deep thinking and three days before Nov'4th I have decided to endorse McCain. And the reasons I will reveal after the result ;).

@11/04/2008: And the reason is that whoever I ever voted for has always won, and whoever I endorsed but did not vote has lost. And I do not have voting rights in America. Second, I did not have any goosebumps to endorse McCain. Lets not forget that he is a nice and decent man who gave his entire life to the service of this country. But, Sorry McCain this year we needed change. And a change from a Guy who is ground to earth and seems to think of us The Middle class America. We needed American troops to conclude its services in Iraq and concentrate on Osama Bin-Laden. We needed lower health care cost. And we needed a President of America and of entire free world to be at least a good Orator and able to connect to his audience. We needed someone who can bring back the respect once America enjoyed across the World. And this was an only opportunity to find a Candidate who is equally white as he is black - A nation that a future America represents.
Congratulations Obama and a Salute to McCain.