Search This Blog

Loading...

Monday, November 2, 2009

Mahabharata- a tribute to my favorite archers

Mahabharata is one of the two great Indian Epics with the Ramayana being the other. I remember when in school and my history teacher asked "Name the two world famous Epics" and I jumped to state "The Ramayana and the Mahabharata". She corrected me by stating the the two world famous epics are the Illiad and the Odyssey. Never the less, I think of the Mahabharata as a definite leader when it comes to Epics. I could go on describing the Mahabharata but that would be more than one blog :-).

The author of the Mahabharata epic was Veda Vyasa. Due to its voluminous and complex nature, it was impossible for any mortal to be able to scribe the epic. For this reason, the Vyasa approached Lord Ganesha to assist with the same. Lord Ganesha, although agreed to do the same, had a condition that the entire epic must be dictated to him without a pause from the Vyasa and if the Vyasa did pause, then the epic would not be completed. The Vyasa in turn put forth a condition that Lord Ganesha would only write down a verse after understanding the meaning of it. This condition allowed the Vyasa some breathing room during the recitation.

The Mahabharata involves a classic battle between cousins on the fields of Kurukshetra. A standard good versus evil scenario. On once side, there were the Pandavas , and on the other, the Kauravas. The Pandavas, can be considered the good and righteous guys of the epic while the Kauravas represented the exact opposite.

I still remember the time growing up in India when a televised serial on the Mahabharata would play every Sunday afternoon. The entire city would almost come to a standstill with everyone glued on the set. This was a SOAP opera, Action flick, romance, sex, polygamy all combined into one. Aah what memories :-)

Anyway, in the Mahabharata, there were multiple valorous warriors, each skilled in different arts of combat. There were supreme archers such as Bheeshma, Drona, Karna, Arjuna and Ekalavya. The popular vote regarding the best archer of the time would lean toward Arjuna, the son of Kunti and Indra (The Indian Zeus). My primary focus is on the archers in this blog. Each of them have an Achilles heel that they cannot hide.

Bheeshma: Bheeshma was a student of Parashurama. Bheeshma was granted a boon from his father on when he could die. Here was a man, who was a grand uncle to the warring cousins, the Pandavas and Kauravas. He loved them both, but forced by duty, was forced to fight on the side of the Kauravas. A major warrior considering his age when he fought in the Kurukshetra A restrained and troubled man, he did not use his total abilities when fighting the Pandavas as they were his kith and kin after all. It is probable that Bheeshma was not the best archer of the land. However, vanquishing him would have been impossible by anyone as he just cannot die unless he choose to.

Death of Bheeshma:
During the Kurukshetra battle Bheeshma was unstoppable, he was terror incarnate as he slaughtered the Pandava forces. Bheesma's Achilles heel was that he also was cursed that his death would be finally at the hands of a Eunuch. That Eunuch was Shikandi. Bheeshma had a policy wherein he would never fire his weapons on a woman and Shikandi bordered on the same. Although, Shikandi could never fire the weapons to kill the grand sire, Arjuna firing from behind Shikandi using Shikandi as a shield could easily hurt Bheeshma. And that is exactly what happened in the Kurukshetra war where Arjuna firing from behind Shikandi downed the grand sire with a bevy of arrows.

In conclusion, if the grand sire had no weakness as mentioned above, the Pandava army would have been vanquished. There is one point to mention that Arjuna had sent the Grand sire packing during the battle when Arjuna was masquerading as a eunuch., i.e., the battle for Virata's kingdom. However, could that victory have been Arjuna's if the sire had chosen to fire on the Eunuch? During the Kurukshetra war, Bheesma would at many a time torment Arjuna with his fine tuned arrows. Arjuna would hesitate to fire on his grand uncle and that irked Lord Krishna (Arjuna's charioteer) who although had sworn to not fight in the Kuruskshetra war decided to attack Bheeshma himself. It is only after Arjuna swore to kill the grand sire did Krishna's wrath get appeased. A classic picture I found of the same with Krishna attacking the Grand Sire with a chariot wheel with Arjuna restraining him:

Archery Skills : 8
Character: 10
Achilles Heel: Unwilling to fight a woman in any form. Excessively duty bound.

Drona: Drona, the Acharya, the teacher, the one who taught both the cousins, the Pandavas and Kauravas, the art of warfare. Here was a man, again forced by duty to fight on the side of the Kauravas in the Kurukshetra war. This man was also a student of the great Parashurama. He had a favourite pupil in Arjuna. Drona was a complex individual, a man who had been insulted by a friend regarding his poverty and then gone on to own kingdoms and humble the man who had insulted him. Drona's lowest moment is probably when he asked Ekalavya to sacrifice his thumb. Drona served as the second commander of the Kaurava army after the fall of Bheeshma.
Again, like Bheeshma, Drona did not want to participate in the Kurukshetra battle but was duty bound to do the same.

Death of Drona:
Drona loved his son who also participated in the war. During the war, he like Bheeshma was routing the Pandavas. Arjuna had qualms about fighting his teacher and would often prefer to avoid the encounter. The same left Drona in his element to devastate the Pandava army. It is said that Drona used celestial weapons on foot soldiers, clearly inglorious. The only time that one could catch Drona of his guard was if he heard news of his son's death. The Pandavas gave Drona the false news regarding his sons death leading Drona to lay down his arms. When unarmed, he was beheaded. A rather inglorious end to a great teacher.

Archery Skills: 9
Character
: 6
Achilles Heel: Loved his son, no special gifts apart from his archery.

Karna: One of the most complex and torn personalities of the Mahabharata. Karna was the son of Kunti and Surya, the son god. At childbirth, he was cast away by his mother and raised by folks considered lowly at the time, charioteers. The eldest brother of the Pandavas who even after knowing of his origins was forced to fight on the side of the Kauravas due to obligations from the favours he had obtained from the Kauravas. Considered by many, as the main nemesis of Arjuna. This was a man who was known for his generosity while still being a very ferocious archer who at every step of his life was reminded of his apparently lowly origin and denied his rightful place among the royals. Karna was born with the Kavacha and Kundala, a divine body armour and earrings respectively which made him invulnerable to any weapon. One important fact about Karna's life that needs mentioning is that he obtained the skills of archery by deceiving his master, the great Parashurama. When Parashuma figured out Karna's treachery, he cursed him saying that his acquired skills would desert him when he needed them the most!


Death of Karna:
Before the start of the Kurukshetra war, Karna's mother Kunti had requested him to spare the life of her sons, i.e., Karna's younger brothers. Karna however promised to spare them all, except Arjuna whom he swore to fight till death. In addition, prior to the starting of the war, Karna parted with his impenetrable armour to a scheming Indra (Arjuna's father) and in turn got an all powerful weapon, the Shakti. Although stripped of his Kavacha and Kundala, Karna, the third commander of the Kaurava army after the fall Drona routed all the Pandava brothers in battle barring Arjuna and Bheema. During the Kurukshetra war, Krishna clouded Karna's mind whenever he met Arjuna so that he forgot about the Shakti weapon and never fired the same at Arjuna. Karna in an attempt to prevent a crisis, fired the same at a son of Bheema and killed him. The weapon could be used only once sadly. When Karna confronted Arjuna finally in the battlefield, they were evenly matched, however, Karna's chariot wheel got stuck in the mud and to accentuate the problem, he forgot his entire archery skill due to the curse by his teacher Parashurama. On this opportune moment, at the prompting of Krishna, Arjuna fired an arrow that ended the life of Karna.
Archery Skills : 9
Character: 8
Achilles Heel: Over generous individual. It is his generosity that finally costed him his life.

Arjuna: The third son of Kunti born by the grace of the kings of gods, Indra and considered by many as the most supreme archer of all time. He was considered equal with the gods with his mastery of the bow. This was a man along with Krishna had helped Agni in consuming the Khandava forest, not even his father could stop the event from occurring. As a reward, Agni gave Arjuna the divine bow, Gandeeva , and an inexhaustible quiver of arrows. Arjuna, had by severe penance won over the favour of gods and in turn the secrets of many a celestial weapon (think nukes here folks). He was granted the Pashupata missile by none other than Shiva himself. The most favourite student of Drona, Arjuna was responsible for the deaths of Bheeshma, Drona and Karna in the Kurukshetra war. Arjuna had Lord Krishna as his charioteer during the Kurukshetra war. Krishna had wowed not to take up arms during the war but he definitely provided strategic guidance to the Pandavas and worked miracles as Arjuna's charioteer providing him invaluable guidance about each and every adversary. Along with Bheema, his brother, Arjuna's contributions in the Kurukshetra war was the reason for the Pandava's victory. One of the most expected images is of Arjuna and Krishna blowing their conch proclaiming victory:


Archery Skills: 10
Character: 8
Achilles Heel: He believed himself to be the Archer of the time. High arrogance that he could vanquish the Kauravas very easily. He however had considerable hesitation when fighting his teacher or relatives. Without Krishna as his charioteer, I believe the Mahabharata would have reached a different outcome.
Death: Old age

Ekalavya: Ekalavya was a forest dwelling individual who looked upon Drona as his teacher and practiced his archery without the personal tutelage of Drona. He practiced his art by consulting a stone sculpture of Drona. Ekalavya was a master of the art, even shocking his own master when the met face to face. Drona had made a wow that Arjuna would be remembered in history as the greatest archer of his time, but upon seeing the skill of Ekalavya, he felt that his wow might go unfulfilled. For this reason, he asked Ekalavya to provide him with his index finger as the price for being his student (even though her did not train him in person). The devout student that Ekalavya was, without a thought cut of his index finger and gave it to his teacher as fees for what he had learnt. Without the use of the index finger, Ekalavya was half the archer he could have been. A warrior who could have been the greatest if only he had never met his teacher!


Archery Skills: 10
Character
: 10
Achilles Heel: Equivalent of piracy. Gained knowledge without paying for it. Over honest in admitting to the same :-).
Death: Unknown and unsung.

Apart from the above, there were others who can be considered as "Also Rans". The names of these other warriors are Ashwathamma (Son of Drona) and Abhimanyu (Son of Arjuna), Kripacharya (brother in law of Drona).

History names Arjuna as the survivor of the Kurukshetra war and touts him as the greatest archer of the saga. However, whether he really was the greatest archer of the times is not beyond debate IMHO. Bheeshma had tutelage from the great Parashurama and had the option of choosing his time of death. Defeating Bheeshma in a fair fight would have been impossible. I however do not think that Bheeshma was as skilled as Arjuna as an archer. He might have been a greater warrior though. Drona, well I am not convinced that Drona was a better archer than Arjuna and neither do I think he was a better warrior. I however do think he was a calculating teacher at best. Ekalavya, now, this individual would have probably been the greatest archer of all time, if only he had the use of his thumb. The very fact that Drona demanded such a sacrifice from Ekalavya only exemplifies the fact of how he feared the skills of Ekalavya would make Arjuna look mediocre. Karna, although great, I do not believe that he was better than Arjuna in archery. There are numerous occurrences in the Mahabharata where Arjuna has performed while Karna could not, and I mean in archery folks :-)))). Karna would however have been unstoppable in the Kurukshetra war if he did have at his disposal the Kavacha and Kundalas.

Do I have a face off here? I think the characters of the Mahabharata are very complex and interesting. I wish one day Hollywood decides to make an epic Movie on the same. If they can do the movie Troy, then the story of the Mahabharata should be 10 times better :-) The Mahabharata is filled with so many moral stories as well. It is said, that reading the Mahabharata cleanses ones souls of their sins. If true, in my case, I might have multiple reads ahead and multiple sleepless nights in Salt Lake City ;-)

Finally, much respect to my favourite Lord Krishna, the coolest god one can find, forever your admirer. Scrub, scrub scrub...the soul cleansing begins :-)

Saturday, October 31, 2009

Ubuntu Karmic and Windows 7

Did two upgrades this weekend. Upgraded a laptop from Vista to Windows 7 and a desktop from Ubuntu Jaunty to Karmic, both 64 bit. Pleased with both upgrades so far. Vista was one of MS biggest lows as far as their OS version goes, Windows 7 seems more peppier in general so far.

I have been very pleased with Ubuntu ever since I installed the same. Have previously been a user of Mandriva, Fedora and Suse. Found mandriva comprehensive in its software offering but not very stable. I feel that Suse may be great to compete with Redhat on the server market but is no where as user friendly as Ubuntu. What I like about Ubuntu is that its pretty solid, convenient and just so easy to use. It detects the need for propriety drivers and installs in a breeze. Have dual monitor support without any xorg.conf tweaking. Printer, web cam all worked out of the box. Have it now running Skype as well without a problem.

After installing Ubuntu, I followed the following BLOG on a TODO list that really helped.
Anyway, got rid of the standard 1948 created Gnome menu in favour of AWN and now my desktop rocks.

A note for those installing eclipse 64 bit. One will find that clicking on some buttons does not work and one has use the keyboard actions to activate the buttons. The way around this problem is to set the following "export GDK_NATIVE_WINDOWS=true" prior to launching eclipse.

On the Windows 7 front, I prefer using Chrome over firefox or IE as its so much more faster on many sites that I frequent. The upgrade from Dell from Vista to Win 7 was pretty simple. Cannot watch youtube on 64 bit IE yet due to 64 flash plugin not available (no so on my Ubuntu though :-)) Don't get me wrong, I don't have anything against Win 7 (except $$$) but when compared with what FREE brings, I find it difficult to justify the extra $$$. I however do need to a Win machine due to the fact that there is no software for the iphone of any value on Linux and that there are sites that I go to such as CWTV to watch videos requiring Win or Mac. Another seller for the Win 7 is my few PC games that I have. BTW, I did not buy Win 7, its a free upgrade option.

The Mrs also is happy with Ubuntu...and as long as she is happy, I am as well :-)

Friday, October 16, 2009

Exceptions in RESTful HTTP with Restlet and JAXB

REST, or rather, RESTful HTTP and how exceptions can be handled therein is what this posting is about.

For those of us who have worked with SOAP and faults, we are familiar with how exceptions are handled. SOAP Stacks upon encountering an exception will throw a SOAP fault which is then marshalled into an exception on the consumer end of the service. SOAP faults in a way provide a protocol over standard HTTP.

When working with REST we have the concept of Resources and their Representations. An exception in a RESTful architecture is really a tuple of an HTTP Status Code and a Representation that describes the same.

The HTTP Status code in themselves are quite indicative, delving a bit into the same:
  • 1XX Series - Informational - Request received and continuing processing
  • 2XX Success - Action received, understood and accepted
  • 3XX Redirection - Further action required to complete the request
  • 4XX Client Error - Request is badly formatter or the server cannot process the request
  • 5XX Server Error - Server failure on a a potentially valid request
When working with architectures that have Java on both ends of a Service, shying away from Exception handling is IMHO a self imposed handicap. In a RESTful system, one would typically have an expected representation of a resource and in the event of exceptions, have them represented as alternate results along with the appropriate error codes. The JAX-RS specification has the concept of a WebServiceException.

What I am trying to do in this BLOG is a demonstrate how exception handling can be accomplished with a framework like Restlet. I am not demonstrating a specification by any means or a wrapper protocol. For the sake of this demonstration, I will be using Restlet and JAXB. In particular, the example will rely on the XmlAdapters of JAXB extensively coupled with the Java Reflection API and Annotations. The XmlAdapters serve to translate to and from Exceptions to JAXB Representions

The scope of this example is as follows:

a. Exceptions supported are of a particular type and its subclasses only:
Exceptions are restricted to WebServiceException and its sub classes. In addition, the WebServiceException is a RuntimeException. No checked exceptions. Any exceptions thrown by a Restlet Resource that are not an instance of WebServiceException will be converted to the same prior to being marshalled. Any WebServiceException marshalled, must have a JAXB Object associated with it.


@XmlJavaTypeAdapter(WebServiceExceptionAdapter.class)
public class WebServiceException extends RuntimeException {
// Http Status code
private int status;
}


// This class extends WebServiceException but has the same body as
// WebServiceException. For this reason, there is no special XmlAdapter required.
public class OrderException extends WebServiceException {
..
}

b. XML as the media type for Transferring Exceptions:
XML is the sole media type supported for exceptions in this example. Note that it is quite trivial to change the same to accommodate additional media types like JSON etc if required. Every Exception's representation is wrapped around with a WebServiceExceptionWrapperDto. The same is to allow for sub typing. Note that the targetException will be marshalled by an appropriate XmlAdapter at Runtime.

@XmlType(name = "ExceptionWrapper", propOrder = { "targetException" })
@XmlRootElement
public class WebServiceExceptionWrapperDto<E extends WebServiceException> {
@XmlElement(name = "targetException", required = true)
public E targetException;
}

c. Rich Exceptions:
Exceptions that can be richer, i.e., more than just message, cause and stack. For example validation messages, codes, inner objects etc. A simple example of the same is shown below where the OrderValidationException contains a description and a custom validation error code. The same could easily have been a complex object if required:


@XmlJavaTypeAdapter(OrderValidationExceptionAdapter.class)
public class OrderValidationException extends WebServiceException {
// A code representing the error
private int validationCode;

// A description indicating the cause of the validation error
private String validationMessage;
...
}


// Note that the OrderValidationException Adapter is behaving like a Template method pattern
// Base marshalling to an exception is handled by the parent class with the child only providing
// specific additions. The methods marshall() and unmarshall() are implemented in the parent class
// and will populate the base properties of the Exception and representation accordingly
public class OrderValidationExceptionAdapter extends
AbstractExceptionXmlAdapter<OrderValidationExceptionDto,OrderValidationException> {

@Override
public OrderValidationException toException(OrderValidationException created,
OrderValidationExceptionDto dto) throws Exception {

created.setValidationCode(dto.validationCode);
created.setValidationMessage(dto.validationMessage);
return created;
}

@Override
public OrderValidationExceptionDto toRepresentation(OrderValidationExceptionDto created,
OrderValidationException t) throws Exception {

created.validationCode = t.getValidationCode();
created.validationMessage = t.getValidationMessage();
return created;
}

d. Control over which parts of an Exception are marshalled:
Provide server stack, cause and message to client. At the same time, ability to prevent certain exceptions from transmitting stack. One might or might not want to marshall server stack in certain cases. The same will be accomplished via an annotation that resides on an Exception thrown. Note that the same can be enhanced for further control. In the example shown below, throwing of the BarException will not result in the marshalling of the stack or cause:

/**
* Foo Exception when thrown should not include server stack and any cause
*/
@ExceptionMarshallingParams(includeStack=false, marshallCause=false)
public class BarException extends WebServiceException {
}


e. Simple mechanism to throw exceptions on the Client:
Clients are aware of the Exceptions that can be expected from a Service and can expect them to be thrown appropriately. For example:

public OrderDto createOrder(OrderDto order) throws OrderValidationException, OrderException {
JaxbRepresentation<OrderDto> orderRep = new JaxbRepresentation<OrderDto>(order);
Response response = client.post(baseUri + ORDERS_RESOURCE_URI, orderRep);
if (response.getStatus().isSuccess()) {
orderRep = new JaxbRepresentation<OrderDto>(response.getEntity(), OrderDto.class);
try {
return orderRep.getObject();
}
catch (IOException e) {
throw new OrderException(e.getMessage(), e, response.getStatus());
}
}

// Not a Response we expected..throw one of the following exceptions expected instead
throw ExceptionUtil
.getWebServiceException(response.getEntity(), OrderValidationException.class, OrderException.class);
}


public class ExceptionUtil {
...
public static WebServiceException getWebServiceException(Representation xmlRep,
Class... expectedExceptions) {
StringBuilder packages = new StringBuilder(20);
packages.append(WebServiceException.class.getPackage().getName());

for (Class clazz : expectedExceptions) {
String ctxPath = getContextPath(clazz);
packages.append(":").append(ctxPath);
}

JaxbRepresentation<WebServiceExceptionWrapperDto<WebServiceException>> wsRep
= new JaxbRepresentation<WebServiceExceptionWrapperDto<WebServiceException>>(
xmlRep, packages.toString());
try {
return wsRep.getObject().targetException;
}
catch (IOException e) {
throw new RuntimeException("Error unmarshalling exception", e);
}
}
...
}

Note that it would have been nice if we could specify the exceptions that a method could throw using generics. That feature however is restricted to a single exception type and thus accommodating checked exceptions are hard.

f. Resource Classes throw Exceptions on failed code states:
Resource classes will be able to throw any type of WebServiceException and have it marshalled to the client. The Resource classes must however ensure they populate the Exception with the appropriate Http Status Code. For example, an OrderResource on create might throw an OrderNotValidException or an OrderException when a POST operation is invoked on it. At the same time, a GET on the OrderResource might throw a OrderNotFoundException.

public class OrderResource extends ServerResource {
@Post("xml")
public OrderDto createOrder(OrderDto dto) {
try {
dto = persistOrder(dto);
setStatus(Status.SUCCESS_CREATED);
return dto;
} catch (OrderValidationException ove) {
ove.setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
throw ove;
}
catch (OrderException e) {
getResponse().setStatus(Status.SERVER_ERROR_INTERNAL);
throw e;
}
}
@Get("xml")
public OrderDto getOrder() {
....
Order order = null;
try {
order = orderService.getOrder(orderId);
}
catch (OrderNotFoundException nfe) {
nfe.setStatus(Status.CLIENT_ERROR_NOT_FOUND);
throw nfe;
}
return (OrderDto) beanMapper.map(order, OrderDto.class);
}
....
}


public class HealthResource extends ServerResource {
private static int counter = 0;
@Get
public String isHealthy() {
// Simply to prove a point....
switch (counter) {
case 0:
counter++;
// Throw a WebServiceException
throw new WebServiceException("System is unhealthy", Status.CLIENT_ERROR_UNAUTHORIZED);

case 1:
counter++;
// throw a RuntimeExeception..this will be transparently marshalled
throw new RuntimeException("Some unexpected exception thrown as a Runtime");
}

getResponse().setStatus(Status.SUCCESS_OK);
return "OK YEAH!";
}
}

g. Marshalling of exceptions occurs via a Restlet Status Service:

A custom extension of the Restlet Status Service is responsible for marshalling all thrown Exceptions. The same is shown below:

public class JaxbExceptionStatusService extends StatusService {
....
public Status getStatus(Throwable throwable, Request request, Response response) {
Throwable cause = throwable.getCause();
WebServiceException exception;
String contextPath = ExceptionUtil.BASE_EXCEPTION_PACKAGE;

if (cause == null || !(cause instanceof WebServiceException)) {
// If not a WebService Exception then throw a WebService Exception
exception = new WebServiceException(..., Status.SERVER_ERROR_INTERNAL);
} else {
exception = (WebServiceException) cause;
String clazzContext = ExceptionUtil.getContextPath(cause.getClass());

if (!contextPath.equals(cause.getClass().getPackage().getName())
&& !clazzContext.equals(contextPath)) {
contextPath = contextPath + ":" + clazzContext;
}

if (exception.getStatus() == 0) {
exception.setStatus(Status.SERVER_ERROR_INTERNAL);
}
}

// Create the Exception Wrapper
WebServiceExceptionWrapperDto<WebServiceException> exceptionWrapper = new WebServiceExceptionWrapperDto<WebServiceException>();
exceptionWrapper.targetException = exception;

JaxbRepresentation<WebServiceExceptionWrapperDto<?>> rep = new JaxbRepresentation<WebServiceExceptionWrapperDto<?>>(
exceptionWrapper);

rep.setContextPath(contextPath);
response.setEntity(rep);
return Status.valueOf(exception.getStatus());
}
}

I have included herewith a Maven example that will demonstrate the client, service and exception management in use. The maven module titled "exceptionnmodule" contains the exception handling code. The integration will demonstrate different exceptions that are thrown by the server and re-thrown by the client code. In particular, you can see the the following abilities of the framework:

a. Ability to throw a simple RuntimeException from the Service and see it marshalled/unmarshalled as WebServiceException
b. Ability to throw an instance of WebServiceException
c. Ability to throw an exception that is a subtype of WebServiceException but without any addition body. For example, the OrderException.
d. Ability to throw a sub type of the WebServiceException that has additional body elements. For example, OrderValidationException.

One can witness the server stack, cause, HTTP Status, specific exception types. Simply run a "mvn install" from the top level project.

Although the example uses Restlet 2.0, the framework has no dependencies on the same. There might be many areas for improvement in the concept and I would like to hear about them if a reader of this blog has ideas. Also, in this example, I have used code from a posting by Ian Robertson on Artima regarding Reflecting Generics.

Finally, I don't know how this BLOG will format. I am trying something new, I hope it woiks!

Download the Code HERE!

Wednesday, August 26, 2009

Restlet 2.0 example using Spring, Maven, Annotations and a Custom Converter

Its been some time since I posted regarding REST. Restlet 2.0 is on its way, I figured its time I updated the example I had created some time ago to a Restlet 2.0 milestone release. If you are continuing to read this BLOG, I would recommend a read of the Restlet 1.1 BLOG I mentioned prior to reading this one.

So whats new with Restlet 2.0? A read of the Resource API refactoring page is recommended.

One of the major features that I liked about JAX-RS over the core Restlet API while working with the former is that it is annotation driven versus class driven. Automatic content negotiation and the calling of the appropriate method in your Server Resource class for different Content-Types is really best left to the container. A method intended to serve content should not have if/else blocks for different content, something one would need to do in Restlet 1.1. Restlet 2.0 seems to take the same into consideration by providing the "best of both worlds"

There were major changes that occurred on Restlet version 1.2 that the team at Restlet decided to change the release to a 2.0. Further details of the change can be obtained at http://blog.noelios.com/2009/05/27/restlet-2-0-m3-released/

Restlet 2.0 has a major change in the way Resources are viewed. In particular a split into a ClientResource and a ServerResource. Details of the same can be viewed on the Restlet Resource API refactoring WIKI page. In addition, there has been a refactoring of certain core classes to different packages. I also noticed that the Restlet API and Restlet engine are shipped as a single jar org.restlet.jar. I could not find the com.neolios packages any more. Finally, there is a jse and j2ee edition of Restlet available.

So, eager to try out the Restlet 2.0 annotations, I reworked my example to use Restlet 2.0 while simplifying the Spring integration present.

Compared to my previous example, I have reduced my Spring applicationContext.xml to be more thinner by using a more annotated approach.



<context:component-scan base-package="com.welflex">
</context:component-scan>

<!-- Spring Application. Note there are no mapping of resources here -->
<bean id="application" class="org.restlet.Application">
<property name="name" value="orderApplication"></property>
<property name="root" ref="root" />
<!-- Added to handle Exceptions centrally -->
<property name="statusService" ref="applicationStatusService"/>
</bean>

<bean id="root" name="router" class="com.welflex.order.rest.SpringBeanRouter"/>
<bean id="beanMapper"
class="net.sf.dozer.util.mapping.DozerBeanMapper">
<property name="mappingFiles">
<list>
<value>dozerBeanMapping.xml</value>
</list>
</property>
</bean>



The OrdersResource has changed to:



@Component(value = "/orders")
@Scope(value = BeanDefinition.SCOPE_PROTOTYPE)
public class OrdersResource extends ServerResource {
......
@Post
public JaxbRepresentation<OrderDTO> createOrder(Representation rep) {
...
return new JaxbRepresentation<OrderDTO>(MediaType.APPLICATION_XML, dto);
}

}



Note that the OrderResource class now extends ServerResource unlike in my previous example which extended the Resource class. Also note that the mapping of the resources to paths are defined in the OrderResource class itself unlike in the xml file in my previous example. The POST method, called createOrder() accepts and returns XML. The return type is a JaxbRepresentation. If we desired, we could have another method in the code that accepts JSON content and returns JSON content that is titled createJSONRepresentation(). Depending on the content type requested, the appropriate method would be called. This is much better than having an if/else block in an acceptRepresentation(Variant v) method.

Take a look at the Products Resource, that returns a JSON representation when a GET method is invoked. Note that this method will only return JSON content.



@Component(value = "/products")

@Scope(value = BeanDefinition.SCOPE_PROTOTYPE)
public class ProductsResource extends ServerResource {

......
@Get
public JsonRepresentation getProducts() {
.....
return new JsonRepresentation(jsonString);

}
}



Pretty nice, I would say. To spoil the party, one of the things I liked about the JAXRS implementations was that I could annotate a Resource with the media type it supported and if it were a JAXB object it would automatically marshall the XML, if it were JSON, it would automatically marshal the same as well.

The same can be accomplished in Restlet by using a Converter Service that converts a java object to and from a media type. There are plans for adding JAXB converters amongst others in 2.0 M5. In short, by using a Converter Service, I would like the createOrder() method to have the following signature, i.e., method returns a JAXB Object, however the container knows how to marshal that into XML back to the caller:



@Post("xml":"xml")
public OrderDTO createOrder(OrderDTO inOrder) {

return outOrderDTO;
}



So what about the ClientResource class? How does that work? Well with Restlet 2.0, one can continue to use the Restlet Client class or use the ClientResource class. The ClientResource is not thread safe. An example of how the ClientResource can be used is shown below in the OrderClientImpl class:



public class OrderClientImpl implements OrderClient {

private static final String ORDERS_RESOURCE_URI = "/orders";
private final String baseUri;

public OrderClientImpl(String baseUri) {
this.baseUri = baseUri;

}

public OrderDTO createOrder(OrderDTO order) throws IOException {

ClientResource ordersResource = new ClientResource(baseUri + ORDERS_RESOURCE_URI);

try {
return ordersResource.post(order, OrderDTO.class);

}
catch (ResourceException e) {
throw new IOException(e);

}
}

public void updateOrder(OrderDTO order) throws OrderException {

JaxbRepresentation<OrderDTO> orderCmd = new JaxbRepresentation<OrderDTO>(
MediaType.APPLICATION_XML, order);

ClientResource ordersResource = new ClientResource(baseUri + ORDERS_RESOURCE_URI + "/"

+ String.valueOf(order.getOrderId()));
try {

ordersResource.put(orderCmd);
}
catch (ResourceException e) {

throw new OrderException("Order Update Failed", e);
}
}

public OrderDTO getOrder(Long orderId) throws OrderNotFoundException, IOException {

....
}

public void deleteOrder(Long orderId) throws OrderException {

....
}
}



I quite like the use of ClientResource versus the Restlet Client as I feel its more RESTful, i.e., talking to a Resource using HTTP verbs. However, again we witness the JAXB representation creeping in as we saw with the service due to the lack of a converter.

I decided to create my own Converter for JAXB to see if I can get it to work and simplify the code base. One of the things I wanted to add just for my pleasure is a way to propagate server stack traces to the client. This is NOT what one would typically include in a representation of a resource as one would not want clients getting details of the working of a server, however, as this is my playground, anything goes ;-). After some tinkering, the following is my Jaxb Converter, it assumes that all JAXB root level objects have the annotation @XmlRootElement:



public class CustomXmlConverter extends XmlConverter {

......
@Override
public List<Class<?>> getObjectClasses(Variant source) {

List<Class<?>> result = super.getObjectClasses(source);

result = addObjectClass(result, JaxbRepresentation.class);
result = addObjectClass(result, Object.class);

return result;
}

@Override
public List<VariantInfo> getVariants(Class<?> source) {

List<VariantInfo> result = super.getVariants(source);

if (source.getAnnotation(XmlRootElement.class) != null

|| source.isAssignableFrom(JaxbRepresentation.class)) {
result = addVariant(result, VARIANT_APPLICATION_ALL_XML);

result = addVariant(result, VARIANT_APPLICATION_XML);
result = addVariant(result, VARIANT_TEXT_XML);

}

return result;
}
@SuppressWarnings("unchecked")

@Override
public <T> T toObject(Representation source, Class<T> target, UniformResource resource) throws IOException {
.....
if (target.getAnnotation(XmlRootElement.class) != null) {
return new JaxbRepresentation<T>(source, target).getObject();

}

throw new IllegalStateException("Should not have got here");
}

@Override
public Representation toRepresentation(Object source, Variant target, UniformResource resource) throws IOException {

Representation result = null;
if (source.getClass().getAnnotation(XmlRootElement.class) != null) {

result = new JaxbRepresentation<Object>(source);
}

else {
result = super.toRepresentation(source, target, resource);

}

return result;
}
.....
}




Great, so we have a Converter, how do we make Restlet use this converter for XML. In my common maven module (shared between client and web), I define a file in META-INF/services/org.restlet.engine.converter.ConverterHelper, and in that file, I have a single entry defining my custom converter. Now when the client and service code use the common library, they will use the Custom Converter I have defined for JAXB.
Thus, to illustrate the change, my new resources for Orders and Order are shown below:



@Component(value = "/orders")

@Scope(value = BeanDefinition.SCOPE_PROTOTYPE)
public class OrdersResource extends ServerResource {
.....
@Post("xml")

public OrderDTO createOrder(OrderDTO dto) {
....
return createdOrderDto;

}
...
}

@Component(value = "/orders/{id}")

@Scope(value = BeanDefinition.SCOPE_PROTOTYPE)
public class OrderResource extends ServerResource {

@Put(value = "xml")
public void updateOrder(OrderDTO orderDTO) {

try {
String id = (String) getRequest().getAttributes().get("id");

orderDTO.setOrderId(Long.parseLong(id));
persistOrder(orderDTO);

}
catch (RuntimeException e) {
getResponse().setStatus(Status.CLIENT_ERROR_BAD_REQUEST);

throw new OrderException("Failed to update an order", e);
}
}
.....
}



We are no longer returning Representations in the above code. Quite similar to JAXRS, wouldn't you say ;-)? On the Client end, the OrderClientImpl no longer deals with Representations but only OrderDTOs as shown below:



public class OrderClientImpl implements OrderClient {

....

public OrderDTO createOrder(OrderDTO order) throws OrderException {

ClientResource ordersResource = new ClientResource(baseUri + ORDERS_RESOURCE_URI);


try {
return ordersResource.post(order, OrderDTO.class);

}
catch (ResourceException e) {
throw new OrderException("Error Creating an Order", e);

}
}

public void updateOrder(OrderDTO order) throws OrderException {

ClientResource ordersResource = new ClientResource(baseUri + ORDERS_RESOURCE_URI + "/"

+ String.valueOf(order.getOrderId()));
try {

ordersResource.put(order);
}
catch (ResourceException e) {

throw new OrderException("Order Update Failed", e);
}
}
}




I like the simplicity of the above and cannot wait to see the release of Restlet 2.0 that has the additional converters built in.

For those interested, I have a maven project example available for download. The project provided uses the custom JAXB converter. To execute the project, one would need to use JDK1.6.X and maven 2.0.9 or higher. To view an integration test in action execute, "mvn install" from the root level of the project. The result should be something like:



-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.welflex.order.IntegrationTest
log4j:WARN No appenders could be found for logger (com.welflex.client.ProductClientImpl).
log4j:WARN Please initialize the log4j system properly.
Aug 28, 2009 8:59:55 PM org.restlet.engine.http.StreamClientHelper start
INFO: Starting the HTTP client
20:59:55 DEBUG - com.welflex.order.rest.ProductsResource.getProducts(44) | Getting Products in JSON Format
Number of Available Products:3
Product Id:663123
Product Id:9912123
Storing the order...
Aug 28, 2009 8:59:55 PM org.restlet.engine.http.StreamClientHelper start
INFO: Starting the HTTP client
20:59:56 DEBUG - com.welflex.order.rest.OrdersResource.createOrder(45) | Call to post an order:..........
Updating the order...
Order successfully
Retrieving the order...
Deleting the order..
20:59:56 DEBUG - com.welflex.order.rest.OrderResource.getOrder(86) | Requested order with id:5499731937442305515
20:59:56 DEBUG - com.welflex.order.rest.ApplicationStatusService.getStatus(21) | In Order Status Service :class org.restlet.resource.ResourceException
Expected Order to not be found. Look at the server stack we got back
com.welflex.exception.OrderNotFoundException: Error obtaining Order
at com.welflex.client.OrderClientImpl.getOrder(OrderClientImpl.java:60)
at com.welflex.order.IntegrationTest.testLifeCycle(IntegrationTest.java:131)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59)




More on Restlet 2.0 once its released. For now, maybe I should probably look toward cleaning up the JaxbConverter and submitting it to Restlet or better still head in the search of kindred spirits, if you know what I mean ;-)

Sunday, August 16, 2009

Bollywood calling...I'm hanging up

Recently we got an invite to a party by some friends of ours. The theme of the party was Bollywood stars. To add to the same, a mandate of the party was that every participant do a small skit based of the star they represent.

I have not been on the stage since my school days where the last play I participated in was a silent one about Dr.Seuss. All mime, no dialogues.

The wife and I were just not sure who we wanted to represent. Whenever the topic came about, I would divert the conversation as I didn't want to think about it.

A day before D-Day, I am on YouTube desperately trying to get ideas. I see a song by my #1 hero of Bollywood, someone who's movies I grew up on, Mr.Amitabh Bachchan and his all time classic role of Anthony Gonsalves in the movie Amar, Akbar, Anthony. After the movie, his character of Anthony Bhai achieved cult status in India. Now, the most famous image of Anthony Bhai is where he is dressed as a priest. Getting the same costume done would have been hard. However, there is another song of his that is a classic, "My name is Anthony Gonsalves" where the main character of the movie, Anthony Gonsalves, is attempting to woo the heroine of the movie, Jenny, in an easter party.



Now the above song looked difficult but yet feasible, i.e., something the two of us can perform together. A coat, a hat, a gown, flower, umbrella, monocle...the prop search commences.

We needed a coat with a tail. As I only had a black coat, the idea was to get some cardboard and attach it. During a visit to Walmart, we could not find any black cardboard. Improvising, we bought a yard of black cloth and attached the same to one of my old suits. The other props were easy (no monocles available though, decided on a pair of glasses). The hard part is doing the act. Hardly any time to practice or remember the lines. Its not easy to remember, "You see the whole country of the system is......"

We practiced an abridged version of the song a couple of times and then left it to chance.

D-Day arrives, as we enter the party, we are surrounded with Bollywood stars, Bhiku Matre, Raj Kapoor, SRK , Sanjay Dutt, Salman Khan, Deepika Padukone, Rekha,..nice! The party is on, the hosts have taken considerable effort in making the party great. Now, due to certain spirits in the vicinity, my mind got clouded as the party moved forward resulting in me forgetting some of the lines. I watch the other stars perform and they perform admirably. Can't let Jenny down..got to remember, got to remember..go away you spirits..:-)

Time to do the gig and we did something pretty close to what we had planned.



This was the first time my wife and I have done any skit together. We loved the party and managed to not totally embarrass ourselves in the process, at least so we believe :-) Finally, sorry Parveen, your Anthony might be cooler, but my Jenny is the best :-)

Tuesday, August 11, 2009

Documentating Software, my 2c

Documentation....Aaargh..why in heavens name would anyone waste time on it? The following few words are a window into my experiences and thoughts on documentation in IT organizations.

Sadly, most organizations cannot or will not afford, the luxury of an additional resource who is dedicated to just the task of documentation, i,e., a technical writer. So as developers and architects where does that leave us ? I have heard statements such as:
  • "Your code should be clear enough such that documenting the same is redundant"
  • "Documentation is not much value unless its kept up to date, bad or expired documentation is worse than no documentation"
  • "It is more important that the code has enough test coverage. The tests if good, document the code use"
  • "We do not have the time, it is lowest on our priority list. We got bigger fish to fry."
Don't get me wrong, I am not in total disagreement regarding the above. Neither am I a subject matter expert on documentation. I am someone who often finds myself in the middle of this.

What I find myself questioning is:
  • If the code is so self documenting or clear, and if you find people keep asking the same question over an over, is it really so self documenting ?
  • If one created documentation, clearly it was considered important. If important, then it would need to updated with the same love when created.
  • And please, there is always time...:-)
I have often entered an enterprise only to find that there is no Enterprise level documentation, stale or current. On the other hand, I have walked into an Enterprise only to be handed a thick set of pages to wade over to acclimatize myself. Neither worked for me, what I was seeking as an entrant was to see the enterprise from the 2000 feet level and then drill down as appropriate.

I am a very visual person, many a time a figure to me means more than a 1000 words. If there is a diagram that describes the stack the company uses, the applications, the services, even if partially wrong, immediately gives me a description of the architecture and/or project. That is a big win as far as acclimatising me to the environment.

When different folk ask the same question to me many times over, to me, that is another clearly indication of a lack of documentation. If a topic is constantly questioned, it deserves a place IMHO for documentation such that the next time the question arises, I point the person posing the question to the documentation instead of the repeated sermon that only I hold the copyrights to. DRY (Don't repeat yourself) does not apply to code alone...

Documentation is often created with great detail and appears as a big win, however if it starts becoming stale, then it loses its value and significance and becomes more of a "White Elephant". A conversation I had with someone in the past:

Someone: "Can you help me with this?"
Me: "Sure, did you check the documentation on the same?"
Someone: "Yeah but that is so outdated, so I don't bother looking at it any more"

The above conversation totally supports the argument that bad or documentation that are stale are definite deterrents to readers.

The following represent a few directions regarding documentation that I will try to adhere to:
  1. Enterprise or Project Documentation or "The BIG Picture documentation": From an Enterprise architect perspective, providing a high level description/diagram of the entire enterprise and how it all fits or works together can be valuable. The documentation does not have to drill into the microscopic details but instead provide a more a high level view that helps an entrant understand how all the parts of an enterprise fit together. From the perspective of a team lead/lead developer, it would be beneficial if documentation were provided regarding the boundaries and dependencies of a particular project. There is no need for details of a database schema, however there is need to indicate that the application talks to a particular schema on a particular database . These documents might even be able to help detect problems in the architecture, as now, you are looking at "The Big Picture" From previous experience, I also feel that documenting "Big" decisions that affect a project can have great value. With time, we tend to forget the reasons for choosing a direction. A place to consult back as to "Why?" can prove valuable.
  2. Stack Documentation: A diagram and/or description indicating the various technology stack in play. For example, "JBoss - App Server, Spring Framework, HP UX - 10.2 deployment OS, ..". This might be encompassed within the scope of point no.1. Again, stacks are rarely changed, and if they are, they probabaly require immediate attention.
  3. Repeated Query Documentation: If any question posed to a developer or architect is being asked more than once, regardless of its longevity deserves due diligence in the documentation space. In lawyer terms, it would classify as "Asked and answered" :-). If you enjoy the interaction and enjoy repeating the same answer, well then more power to you , please disregard the documentation angle.
  4. Redundant Documentation : Code that contains redundant or unnecessary documentation (i.e., code is self explanatory) serves no purpose. I violate this sometimes and need to stop. For example, getters and setter of a POJO (Plain Ole Java object) rarely requires documenting if the method name is clear. Institute naming standards that are enforced. Don't bother with class or schema diagrams, any developer worth his salt will be able to easily find free tools to reverse engineer classes or database schema's and be able to get the most current versions of the same.
  5. Documenting Complex Code: Code that is unavoidably complex, deserve either strong documentation or better still refactoring.
  6. Job security as it applies to documentation: Job security is not improved by keeping the details in your head. People are smart and folks that tend to do that will not last in a smart organization. Organizations lacking strong leaders, well get strong and smart leaders :-)
  7. When to document and how much ? : Things that are in constant flux are hard to document, wait for stabilization. However, do follow up after stabilization occurs. Make sure your code works first, then comes the documentation. If you have good documentation but code that is broken, thats not a win. In the same vein, I would go further to say, Unit Tests and Integration Tests are more valuable than documentation. Place yourself in the position of a person who will utilize the documentation, make the content detailed enough for your intended audience. For example, in an enterprise level document, do not bother listing individual Web Services or Database Schemas, it is enough to state that Web Services communicate with databases and or other Web Services. The detail in the documentation should also be only that much that you can afford to keep current moving forward. Finally piggy backing on this point, broken windows or no windows from the top can send a bad message. What I mean is, "If an architect or lead themselves do not document, then it becomes a hard sell to a developer that they need to document"
  8. Detail and Artistry of Documentation: Reiterating, "Make it right before making it pretty". A straw diagram caught on a white board via a cell phone camera during the design, if posted on a WIKI is often as effective as a colorful work of art. High ceremony documentation is almost too much and often unnecessary. Concise and to the point documentation works in most cases. People are smart, they often like a start. Its like being provided a map into Yellowstone regarding the sights to see. One does not require information on the concentration of sulfur at each site, just where the sites are located, we'll figure out the sulfur content at each site :-)
  9. Tools for documentation: Use a tool that works for collaborative authoring such as a WIKI. Almost any software development project IMO deserves a WIKI or equivalent presence. Media WIKI and such are free to use, so a smart person would avail such tools. Use technology where applicable.
  10. Collaborative Documentation: Documentation on IT projects should not belong to a single owner but be considered a collaborative effort. In other words, every member of the team should feel that they can add or correct toward the documentation. If a person comes asking a question and you give an answer, if you ask the person to document the same as you feels its valuable and is missing, you might be surprised as to how gladly they are willing to contribute. On the same note when you find documentation that is outdated and more importantly wrong, deprecate the documentation at the very top if you do not have the time to make it current.
  11. How to get started, documentation: As an entrant into a new IT environment, one often needs to get set up and be ready to get productive. A road map documentation that provides a user of "What, Why, Where, Who" can be quite useful.
  12. Selling documentation to the business: Getting business to account for time slots for code testing itself can be a daunting task in some organizations, getting a time slot in the project budget for documentation can be harder sale. However, as a lead or person making an estimate of a project, it is important to bake in the same. Documentation is money, however you need to sell the same and its value to the business. Lack of critical documentation is something that can come back to haunt you. "Protect your skin and those of your kinsmen" :-)
I am sure I have only touch the tip of what needs documentation. I cannot claim the title of a "Documentation nazi" and/or authority, neither am I claiming a "One set of rules fits all". People have probably written books on the same.....Easy to preach, hard to do, but hey, trying is not so hard, is it, and that is motive, trying ;-)...

Friday, June 26, 2009

Farewell Michael Jackson

There has been a spate of news flooding the media after the sudden demise of arguably the musical sensation of the century. There are people who still cannot get over his sudden demise, people who are sick of the continued media coverage and those who are indifferent. This BLOG is a few words from me to express my feelings on the passing of a man whose music I loved growing up and still do.

Going back in time, one day during my schooling years, a friend of mine had this audio cassette that he said I must hear as the songs from it were just super. I heard "Wanna be starting something" and I was of gyrating to the beats. Not the most famous song of M.J, and I cannot claim I understood the lyrics, but I liked it. Especially, I had my own version of "Mama-se, mama-sa, ma-ma-coo-sa" that I would be dancing to ;-)

Then I heard Beat It and Billie Jean. Hearing the vocals and guitaring on the former (Eddie Van Halen on the guitar), hearing the introduction on the latter had me hooked! I must admit that the first time I heard him, I was of the impression that the singer was a female.

Then started the research into who this artiste was. Steps back in time hearing "Off the wall" and others got me more interested in M.J. Following suite was trying to get videos of him performing, something not easily available in India at the time. I watched the moon walk that he performed for the Motown anniversary. Recollecting the time, I remember all my friends trying their very best to do this moon walk. What a dance step. This person was more than just a singer that I liked, he was a dancer that I could never hope to be. I had found an artist who was a complete entertainer. Before you knew it, my brother and I had most of the Jackson songs in our collection, even if it meant begging my parents to buy a tape for one song considering we already had the rest in our collection. Thanks dad and mom for humoring us.

At the time, in India one could either purchase L.P records or Tapes. Music quality from the tapes were not the best, however, even with the quality available I remember my brother and I enjoying the music and trying very hard to decipher the lyrics. No internet available at that time :-)

Time flew, the next album we eagerly awaited and got was "Bad". M.J had changed his face considerably by now, the songs were different compared to "Thriller". It took me time for the songs to grow on me, his looks although strange were not much of a deterrent for me, that was his personal life so to say. M.J still rocked!

Continued to watch sporadic news that trickled in about M.J, him sleeping in an Oxygen Chamber, "Bubbles" the chimp, more surgeries etc etc....To be honest, again these oddities as reported by the media did not affect me in a way to reduce my admiration of the man.

Time flew on, then came the "Pedophile" accusations and scandals. At this point, it was more than eccentric indulgences of a man who has more money than what he knew to do with. I really did not know what to believe. As a fan, I hoped that my childhood idol would be exonerated. As an evaluator, I was of the opinion, a man is innocent till proven guilty. Cut it anyway, the fact that he was a great artist could not be blemished by the results of the court cases. If you choose to, blame it on the legal system or the compromising accusers, there was no conviction. As a bystander, I can only accept the result. Guilty or otherwise, I primary held the parents of the children who claimed abuse responsible for allowing such a situation to present itself in the first place. Did they really need to let their children sleep over in a strangers home??? Come on!

After all these incidents, one would hear of a one off concert where M.J would be in news and then silence ensuing for months, sometimes years on end. Financial problems, and the "Martin Bashir" interview are what I followed. M.J's appeal and record selling ability had dwindled, I however still like the song "Rock my world" though.

Years pass, I hear that he is about to perform again in 2009; a curtains concert and that tickets are sold out like hot cakes. Happy for the man. Also hear that he is in the process of making a new album. Happy to hear the news and hoping he will be back with an album to match the genius of "Thriller".

In my office, I hear, M.J has been hospitalized. Do not give much interest to the news as I do not feel it was serious. This is M.J we are talking about, a great dancer, a physically fit person, at least that was the impression imprinted in my brain growing up. Soon after a colleague of mine says that some sites are reporting M.J is dead. I refuse to believe saying its not been announced on "CNN", its not been announced on "BBC". Denial at work here...

Soon after, my trusted news sites report that M.J has in fact passed away. Saddened now. This just felt chronologically wrong, out of order. How could M.J pass on when others that I had placed ahead of him in the passing order have not? Shocked and saddened at the loss...still not ready to believe the obvious. News that he died in a car accident, News that he was murdered were all acceptable outcomes for my sensibility, but sudden death by heart failure ???

Reach home and am hooked on CNN watching the events unfold. M.J's demise reminded me of my own mortality in a way...the random factor had wreaked havoc for me. Watching CNN get into news about his weirdness was not what I expected. I had hoped that a person such as M.J would be more remembered for his music and creative genius. Felt disappointed that the media were focusing more on the negativity involved in his life.

In the end, there are people who hate him, have convicted him in their minds as a pedophile and there are people who believe he was innocent and then there are majority who simply respected the man for his immense talent. I am part of the latter faction and I will miss the possible creative and artistic contributions he would have provided were he alive. The world has lost a great artiste.

Everyone will remember M.J in their own way. Like one person said, one will remember where one was on the day M.J passed away, I for one definitely will. The man has done considerable work for charity and causes. Maybe more than many of will ever be able to do. Remember the man for what he did good. I admit that he was a strange bird....however please try to remember him for his abilities and contributions as an entertainer/singer.

From my end, every time the song "Billie Jean" or "Beat It" starts on my Boxster, I will have a smile on my face and be in an upbeat mood...it takes me back to my childhood, it reminds me of the good times my brother and I had as kids...thanks M.J...I will miss your singing..Eddie Van Halen or Slash on the guitar..the pedal is hitting the floor....

Tuesday, June 23, 2009

Scaling in the JMS World...in particular Topics

Scalability and Availability in JMS. For the former, as load on the messaging system increases, one would want to be able to service the increased messages without performance degradation. For the latter, one should ensure the reduction if not elimination of single point of failures, i.e., ensuring system is available for use.

Most JMS Providers have some sort of mechanism for addressing the above. This BLOG is however only going to concentrate on Oracle WebLogic.

WebLogic has an interesting way in which JMS Destinations (Queues and Topics) are scaled via Distributed or Virtual Destinations. A Virtual Destination can be considered a sort of router/load balancer that distributes messages it receives over to actual or physical destinations. Each physical destination would reside in separate WebLogic instances on potentially separate hardware. See figure below where a virtual destination "test_queue" has physical members test_queue_1, test_queue_2 and test_queue_3 on separate WebLogic instances:



As an example of Virtual Queues in action, in the conceptual figure shown below, Producers send messages to the Virtual Queue which then directs the message to one of the physical destinations



P : Producers
VQ: Virtual Queue
PQ-X: Physical Queue, where X is the number of the Queue
C: Consumer
M: Message

In the case of a Virtual Topic, messages sent to the Virtual Topic are sprayed on to each and every physical member as shown in the figure below where VT and PT-X represent Virutal and Physical topics respectively:


Scaling Queues:
From the figure shown regarding Queues, it is pretty simple to follow how the system scales and that it will continue to service new messages and consume them should one of the servers in the messaging cluster fails. A message will be consumed at most by one of many consumers successfully. Adding Consumers to the end of the physical members allow the architecture to process messages rapidly, i.e., Competing Consumer Design Pattern.

Now, what if one of the servers having physical members went down, for example VQ-1 went down? From the perspective of availability, messages are still flowing and getting consumed from the other available member, i.e., VQ-2. What about the messages that were in the physical member whose server went down? One has multiple options. The first and most straight forward is to restart the server and re-connect the consumers to drain the queue. WebLogic allows for auto-service migration in the event of failure. This is another feature that can assist in recovering from failure. Queues readily tend to present themselves for scaling. One note on the same, if message ordering is put into play, all bets are off :-)..more on the same on a subsequent blog.

Scaling Topics:
Topics unlike Queues present an interesting challenge. In the case of a topic, a message is delivered to all listeners of the topic and each listener is typically different than its peer in how it handles the message. For example a message posted to an order topic, might have a consumer that processes the order while another one looks at inventory calculations:


Clearly we cannot have two consumers that process the same order and it is redundant to have duplicate consumers perform the same inventory calculations.

Messaging systems have the concept of a Durable Subscriber, i.e., a Message listener who registers with the topic such that they are delivered messages sent to the topic even when the listener is not connected. Message providers store the message on behalf of the durable subscriber and forward the same when the subscriber comes back on line.

In WebLogic one cannot connect to a durable subscriber using a distributed (virtual) destination JNDI. One has to explicitly register with a physical member. This is one gripe that I have with the WebLogic solution. Adding to the problem, should one connect to one physical member and if that member goes down, attempting to establish the durable subscription on other available members are treated like totally new subscriptions. In consolation, if the server goes down that contains durable subscriptions, then messages will be stored on other physical members of the virtual topic on behalf of the durable subscribers, and when the server is restored, messages get forwarded to the durable subscribers when they comes back on line as shown below:


Now, as each subscriber of the topic has a unique agenda from the other subscribers, the fact that it is the sole entity that services the message, the same represents a single point of failure and a proves a scalability inhibitor as it cannot concurrently process multiple messages.

So how can one scale a topic so that a message on a given type of subscriber can be rapidly processed? One direction is have the consumer of a Topic post the message onto a Queue which can then be processed by competing consumers. One way this can be achieved is to have a Message Driven Bean withing the container whose sole purpose is to transfer the message from the topic to a queue for those consumers that need to scale. An example of the same is shown below:


In the above shown example, as one consumer of the topic needs processing to rapidly occur of messages received, an MDB (registered as a durable subscriber of the topic) is used to transfer every message onto a Queue which is then consumed by competing consumers. As other consumers, DC-1 and DC-2 are not in need of scaling, they remain durable single subscribers.

The above solution works to scale the durable subscriber of a topic. However, in WebLogic when using distributed topics the durable MDB still represents a single point of failure.

A question to ask at this point is, "Do you really need a topic for the use case at hand?" Topics are great IMO when the subscribers tend to be dynamic in nature or do not need to be durable, an example of the former is a stock quote topic and an example of the latter is a event listener that requires notification of an event.

When the number of subscribers are a known or finite in amount, the use of a queue coupled with the MDB can easily achieve a scalable solution as shown below where the MDB transfers messages on the in-queue to subsequent out-queues where competing consumers can scale and consume the messages:



Transfer MDB:
It is pretty trivial to create the Transfer MDB. One would typically like to re-use the Transfer MDB Java Code with only configuration changes for different applications. The same can easily achieved via separate projects where target destination can be provided via @Resource. A simple transfer MDB is shown below:



@MessageDriven
@TransactionAttribute(TransactionAttributeType.REQUIRED)

public class MessageRouterMdb implements MessageListener {

/**
* Map this jms connection factory to the actual one in the weblogic-ejb-jar.xml deployment
* descriptor of the ejb project. The Connection factory to be used will be the one that is
* specific to this mdb.
*/

@Resource(name = "jms/connectionFactory")

private ConnectionFactory connectionFactory;

/**
* Injected in Message Driven Context
*/

@Resource
private MessageDrivenContext mdc;

/**
* Define a comma separated list of destinations JNDI names in the ejb-jar.xml via an environment
* entry.
*/

@Resource
private String targetDestinations;

// Initialized
private List<Destination> targetJmsDestinations;

private MessageProducer messageProducer;

private Connection connection;

private Session session;

@PostConstruct
public void init() {
try {

InitialContext ctx = new InitialContext();
connection = connectionFactory.createConnection();

session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

messageProducer = session.createProducer(null);
String[] targetDestArray = StringUtils.split(targetDestinations, ",");

targetJmsDestinations = new ArrayList<Destination>();

for (String targetDest : targetDestArray) {

targetJmsDestinations.add((Destination) ctx.lookup(targetDest));

}

connection.start();
}
catch (Exception e) {
throw new RuntimeException("Error Initializing Message Router Mdb", e);

}
}

public void onMessage(Message message) {

try {
// Loop through target destinations and send message to each destination
for (Destination dest : targetJmsDestinations) {

messageProducer.send(dest, message);
}
}

catch (Exception e) {
mdc.setRollbackOnly();

}
}

@PreDestroy
public void cleanup() {

// Close open jms resources here...
}
}




The CODE for the above MDB and an example Maven Project that uses WebLogic is available for download HERE. Note that the code is not specific to WebLogic and can really be used in any container, for example JBoss.

Conclusion:

Scaling topics via an MDB and target queues just felt like an obvious pattern to me. WebLogic, like many JMS Providers has the concept of a Message Bridge. Initial investigation led me to believe that a message bridge more serves the purpose of transferring a message from one provider to to another rather than serving to scale a Topic and distributed messages to multiple destinations.

There may be cases as mentioned where the number of subscribers are not known. In such a case, a topic might work and it becomes the responsibility of the subscribers to scale on their end, for example multi-threading upon receiving the message.

What really would be nice if the JMS specification had the concept of "Durable Competing Consumers" where a Durable subscriber could register multiple instances of itself such that a message to a topic would be delivered to at most it or one of its clones :-). I believe there are some Messaging providers who permit such a pattern via customization that extend the JMS specifications.

Before bidding adieu, this has been one of my most figurative blogs, all Ye artists, look at the diagrams with a forgiving eye, "I am a programmer not an artist!" :-)

Friday, May 22, 2009

Ending the drought...

Its been a month since I posted anything on my BLOG, cannot let May end with a drought. It has been rather a trying month for me, the reasons I am saving for a later melodramatic post ;-)...

Right now I am very happy. At the company I currently work at, we released out a JMS architecture with minimal hiccups. It was very gratifying to witness the entire team involved work and mesh so well in order to make the architecture work. Everyone from Architects, Developers, System Administrators, Testers worked so well together. I must state that my level of confidence in the team and players involved was so much that I did not even have to be there during the go live in person. Put it in a word, my current organization is so much about "WE" and not "ME". That is a motto that works IMHO. Guess my current organization is very talented in its selection process of the people they want on board.

I truly enjoyed working with all the folks on the various facets involving the deployment of the architecture, frameworks, deployment, projects etc. We suffered a few hiccups after the deploy as well but the messaging solution itself was 100% solid. In fact in my own retarded way, I appreciated the fact that the failures occurred as they served to demonstrate that the failure path in fact worked ;-)

Personally, I have experienced considerable growth in the areas of JMS Messaging. However, every once so often I again am humbled by what I don't know or did not anticipate.

The project as a whole was like our baby that finally saw the light..and danced on...I hope it keeps dancing :-))))))))))) Even if does not, I believe we have a team strong enough to put it on crutches to make it so...

I can't wait for further adoption of the architecture...so thrilled, had a blast...

More BLOG's coming up soon, the little GREY cells were on vacation (not dead, just vacationing), you should see something from them soon....

Friday, April 24, 2009

Browsing Weblogic JMS Distrubuted Queues

On of the interesting features of Weblogic is that when javax.jms.QueueBrowsers are created, they are pinned to a particular physical member of a distributed destination. What that means is that a QueueBrowser created for a distributed destination will only be able to browse messages on the member it gets pinned to and not the whole queue.

One can try to create X number of queue browsers based of the number of servers in the provider URL, for example, "t3://localhost:8002, localhost:8003", and hope that no two queue browsers will pin to the same destination, i.e., at the mercy of Weblogic round robin if possible. Even if we do manage to do that, one still needs to iterate over X separate enumerations in order to manage the message. Consider an integration test where one sends a message to a distributed destination and would have to create X queue browsers to determine whether or not the message is present.

What would be really nice is if the Weblogic runtime gave us a QueueBrowser that provided an enumeration of enumerations of the physical members of a distributed queue. That however is not present. So, I decided to create a simple example that would help me with the same. At the same time, I am interested in understanding the JMX capabilities of Weblogic.

The example will create a QueueBrowser and obtain an enumeration from each of the physical members of the distributed destination and provide back an enumeration of the respective enumerations. In the case of uniformly created distributed destinations, the JNDI name of the physical members will be of the format JMSServerName@JNDIName. If one knows the JMSServerName thats great. However, one should not have to rely on the same as JMSServers might be added/removed. It would be nice if the distributed member JNDI names could be located on the fly by using Weblogic's JMX capabilities and thats what I intend to do. Note that the enumerations obtained in Weblogic are snapshots of the current state of the queue and are not dynamic, i.e., new messages added being dynamically reflected in the enumeration. Finally, I am providing a java.util.Enumeration for the JMS messages instead of an java.util.Iterator as Enumeration does not have a "remove" method and I hate putting an "UnsupportedOperationException" in the Iterator and also I would like to be true to the JMS API.

So first obtaining the JNDI name of physical members of a distributed queue. Weblogic JMX is a tree for objects. Once we obtain the ServerRuntimeMBean information, we can obtain information about the JMSRuntimeMBeans and then the different JMSServers and finally the JNDI names of the JMS Servers as shown below:



public class WeblogicMBeanHelper {
private final MBeanServerConnection connection;

private final JMXConnector connector;

private final ObjectName service;

public WeblogicMBeanHelper(String url, String userName, String password) {

try {
service = new ObjectName(
"com.bea:Name=DomainRuntimeService,Type=weblogic.management.mbeanservers.domainruntime.DomainRuntimeServiceMBean");

}
catch (MalformedObjectNameException e) {
throw new AssertionError(e.getMessage());

}
......
......
JMXServiceURL serviceURL;

try {
serviceURL = new JMXServiceURL("t3", hostName, Integer.valueOf(port), jndiroot + mserver);

Hashtable<String, String> h = new Hashtable<String, String>();

h.put(Context.SECURITY_PRINCIPAL, userName);
h.put(Context.SECURITY_CREDENTIALS, password);

h.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES, "weblogic.management.remote");
connector = JMXConnectorFactory.connect(serviceURL, h);

connection = connector.getMBeanServerConnection();
}
catch (Exception e) {

throw new RuntimeException(e);
}
}

public Iterable<String> getDistributedMemberJndiNames(String distributedDestJndiName) {
Iterable<String> serverNames = getJmsServerNames();

Set<String> distributedDestNames = new TreeSet<String>();

for (String serverName : serverNames) {
distributedDestNames.add(serverName + "@" + distributedDestJndiName);

}

return distributedDestNames;
}

public Iterable<String> getJmsServerNames() {

.....
}

public Iterable<ObjectName> getJMSServers() {

....
}

public Iterable<ObjectName> getJMSRuntimes() {

....
}

public List<ObjectName> getServerRuntimeMBeans() {

try {
return Arrays.asList((ObjectName[]) connection.getAttribute(service, "ServerRuntimes"));

}
catch (Exception e) {
throw new RuntimeException("Error obtaining Server Runtime Information", e);

}
}

public void close() {

// Close the connector
....
}
}





public class WeblogicMBeanHelper {
private final MBeanServerConnection connection;

private final JMXConnector connector;

private final ObjectName service;

public WeblogicMBeanHelper(String url, String userName, String password) {

try {
service = new ObjectName(
"com.bea:Name=DomainRuntimeService,Type=weblogic.management.mbeanservers.domainruntime.DomainRuntimeServiceMBean");

}
catch (MalformedObjectNameException e) {
throw new AssertionError(e.getMessage());

}
......
......
JMXServiceURL serviceURL;

try {
serviceURL = new JMXServiceURL("t3", hostName, Integer.valueOf(port), jndiroot + mserver);

Hashtable<String, String> h = new Hashtable<String, String>();

h.put(Context.SECURITY_PRINCIPAL, userName);
h.put(Context.SECURITY_CREDENTIALS, password);

h.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES, "weblogic.management.remote");
connector = JMXConnectorFactory.connect(serviceURL, h);

connection = connector.getMBeanServerConnection();
}
catch (Exception e) {

throw new RuntimeException(e);
}
}

public Iterable<String> getDistributedMemberJndiNames(String distributedDestJndiName) {
Iterable<String> serverNames = getJmsServerNames();

Set<String> distributedDestNames = new TreeSet<String>();

for (String serverName : serverNames) {
distributedDestNames.add(serverName + "@" + distributedDestJndiName);

}

return distributedDestNames;
}

public Iterable<String> getJmsServerNames() {

.....
}

public Iterable<ObjectName> getJMSServers() {

....
}

public Iterable<ObjectName> getJMSRuntimes() {

....
}

public List<ObjectName> getServerRuntimeMBeans() {

try {
return Arrays.asList((ObjectName[]) connection.getAttribute(service, "ServerRuntimes"));

}
catch (Exception e) {
throw new RuntimeException("Error obtaining Server Runtime Information", e);

}
}

public void close() {

// Close the connector
....
}
}




Now that we have a way of obtaining the distributed members, the following represents the QueueBrowser that enumerates over the different members and consolidating the same into a single enumeration. I have a second enumeration that provides information regarding the JMServer that hosts the given message:



public class DistribuedQueueBrowser {
...
private final Iterable<String> queueNames;

public DistribuedQueueBrowser(String adminUrl, String providerUrl,
String distributedDestinationName, String userName, String password) throws Exception {

ctx = getInitialContext(providerUrl, userName, password);
WeblogicMBeanHelper helper = null;

try {
helper = new WeblogicMBeanHelper(adminUrl, userName, password);

queueNames = helper.getDistributedMemberJndiNames(distributedDestinationName);
}
finally {

if (helper != null) {
helper.close();

}
}

// Set up connection/session..
....
}

private InitialContext getInitialContext(String providerUrl, String userName, String password) throws Exception {

....
}

// Retrun an Enumeration of Messages only
public Enumeration<Message> getEnumeration() throws JMSException, NamingException {

return new JmsMessageEnumeration(getMessageEnumeratorMap());
}

@SuppressWarnings("unchecked") private Map<String, Enumeration<Message>> getMessageEnumeratorMap() throws JMSException,
NamingException {

Map<String, Enumeration<Message>> serverMessageMap = new HashMap<String, Enumeration<Message>>();

for (String queueName : queueNames) {
String serverDq[] = StringUtils.split(queueName, "@");

Queue queue = (Queue) ctx.lookup(queueName);

javax.jms.QueueBrowser qb = session.createBrowser(queue);

serverMessageMap.put(serverDq[0], qb.getEnumeration());

}

return serverMessageMap;
}

// Return an enumeration of ServerLocatedMessage that contains the
// the jms server that houses the message

public Enumeration<ServerLocatedMessage> getServerLocatedEnumeration() throws JMSException,
NamingException {

return new ServerLocatedMessageEnumeration(getMessageEnumeratorMap());
}

public static class ServerLocatedMessage {
private final Message message;

private final String jmsServerName;

public ServerLocatedMessage(String jmsServerName, Message message) {

this.message = message;
this.jmsServerName = jmsServerName;

}
...
}

private static abstract class AbstractMessageEnumeration<T> implements Enumeration<T> {

Map.Entry<String, Enumeration<Message>> current;
private Enumeration<Message> currMessageEnumer;

private final Iterator<Map.Entry<String, Enumeration<Message>>> iterator;

public AbstractMessageEnumeration(Map<String, Enumeration<Message>> map) {

iterator = map.entrySet().iterator();
current = iterator.hasNext()

? iterator.next()
: null;
currMessageEnumer = current != null

? current.getValue()
: new Enumeration<Message>() {

public boolean hasMoreElements() {
return false;

}

public Message nextElement() {
throw new NoSuchElementException();

}
};
}

Enumeration<Message> getEnumeration() {

if (current == null || currMessageEnumer.hasMoreElements()) {

return currMessageEnumer;
}

while (iterator.hasNext()) {

current = iterator.next();
currMessageEnumer = current.getValue();

if (currMessageEnumer.hasMoreElements()) {
return currMessageEnumer;

}
}

return currMessageEnumer;
}

public boolean hasMoreElements() {
return getEnumeration().hasMoreElements();

}
}

// Wraps the JMS Message within a ServerLocatedMessage object
// which contains the server name along with the message
private static class ServerLocatedMessageEnumeration extends

AbstractMessageEnumeration<ServerLocatedMessage> {

public ServerLocatedMessageEnumeration(Map<String, Enumeration<Message>> map) {

super(map);
}

public ServerLocatedMessage nextElement() {

Message message = getEnumeration().nextElement();
return new ServerLocatedMessage(current.getKey(), message);

}
}

private static class JmsMessageEnumeration extends AbstractMessageEnumeration<Message> {

public JmsMessageEnumeration(Map<String, Enumeration<Message>> map) {
super(map);

}

public Message nextElement() {
return getEnumeration().nextElement();

}
}

public void close() {

......
}
}



Using this QueueBrowser is rather straight forward and can be done via:



// Note that the first argument is the admin url and the second is the
// managed server url.
DistribuedQueueBrowser qb = new DistribuedQueueBrowser("t3://localhost:7001",
"t3://localhost:8001",
"test_queue", "weblogic", "weblogic");

Enumeration<Message> i = qb.getEnumeration();
while (i.hasMoreElements()) {

Message m = i.nextElement();
System.out.println("Message:" + m);

}

Enumeration<ServerLocatedMessage> sli = qb.getServerLocatedEnumeration();

while (sli.hasMoreElements()) {
ServerLocatedMessage m = sli.nextElement();

System.out.println(m);
}
}



The code for the same is available HERE. The zip file contains only the JAVA files. One would need to compile the same with weblogic's client jar's and then use them. Let me know if you have problems running the code or if you have any tips regarding the code.
Later...

Saturday, April 18, 2009

Aspect J Maven and Logging

At my earlier job, I had looked at Aspect Oriented programming with Spring. I used the same for transactions. I wanted to use it for Logging method enter/exits as well but abandoned the same as one would need to use Spring's native AspectJ weaving. I was not ready to take that on at the time. Another option was to use AspectJ compile-time weaving, again, not something I had the time for and simply settled on Transactional support with Spring Aspects.

So what am I upto? I wanted to play with AspectJ and how compile time weaving on maven project would help me eliminate the logging.

Enter and exit of methods are quite useful, especially when debugging. Another use case of debugging would be to trace the method arguments passed to a method. In addition, performance of profiling method executions has its benefits. In an earlier blog post I had investigated the use of Java Instrumentation to assist with profiling.

So I start by creating a logging Aspect. If the logging level is set as DEBUG, it will LOG entry and exit of a method. If the level is set as TRACE, then the time for method execution is also logged along with the method arguments to the method. The following represents the Aspect:



import org.aspectj.lang.*;
import org.apache.log4j.*;

public aspect LoggingAspect {

Logger LOG = Logger.getLogger("trace");

// Execute on all methods except this Logging Aspect

pointcut traceMethods()
: execution(* *.*(..)) && !within(LoggingAspect);

// Around each method do the following
Object around() : traceMethods() {

Signature sig = thisJoinPointStaticPart.getSignature();

String baseEnterMessage = "Enter [" + sig.getDeclaringType().getName() + "." + sig.getName() + "] ";


if (LOG.isTraceEnabled()) {
Object[] args = thisJoinPoint.getArgs();


if (args.length > 0) {
StringBuilder argsBuilder = new StringBuilder(20);

argsBuilder.append(baseEnterMessage).append(" Args :");

for (int i = 0; i < args.length; i++) {

argsBuilder.append("{Index [" + i + "], Value [" + args[i] + "]}");

if (i != args.length - 1) {

argsBuilder.append(",");
}
}
argsBuilder.append("}");


LOG.trace(argsBuilder.toString());
}
else {

LOG.trace(baseEnterMessage);
}
}
else if (LOG.isDebugEnabled()) {

// Print base debug without arguments
LOG.debug(baseEnterMessage);
}

long start = System.currentTimeMillis();


try {
Object result = proceed();
return result;

} finally {
String baseMessage = "Exiting [" + sig.getDeclaringType().getName() + "." + sig.getName() + "].";


if (LOG.isTraceEnabled()) {
// If trace is enabled, print the time for execution.
long end = System.currentTimeMillis();

LOG.trace(baseMessage + "Completed in:" + (end - start) + " millis");

} else if (LOG.isDebugEnabled()) {
LOG.debug(baseMessage);

}
}
}



Another nice use of Aspects is to be able to enforce compile time standard checks. Maybe Find Bugs has a way to already do this. Not sure. Anyway, say for example, we want to detect when there are System.out.println() calls in the code or maybe the code in question is using some Class/Framework that we do not approve of, with Aspects and compile time checking there is a nice way out. I quite liked reading the blog by Jacob Matute on the compile time enforcement of standards. What I envision is the inclusion of a simple jar in project that can/will enforce the standards one desires. I think this might be preferable over depending on IDE based configuration of plugins.

What about method invocations where checks are performed? For example in many methods we repeat code that checks if an argument is null and throws some exception? What if one could declare an annotation on the method and an aspect check for the annotation to handle the same for you? The code becomes cleaner IMO. I think Java 7 will have this feature. Till then one can create an @NotNull annotation on a parameter and have aspects handle the exception throwing part for you across your entire code base. Andy Clement's blog discusses the same very nicely.

As I used maven for all my projects, there is a plugin from codehaus, for integrating AspectJ into maven.

For the sake of demonstration, I have a simple, fictional and potentially farcical objects that would undergo the tests of the Aspects:



public class Order {
private final Long id;

private final String userName;
private final Random random = new Random();


public Order(Long id, String userName) {
this.id = id;

this.userName = userName;
}

public String getUserName() { return userName; }


public int getTotalCost(int range) {
System.out.println("Calculating Cost...");

try {
Thread.sleep(2000L);
} catch (InterruptedException e) {}

return getRandom(range);
}

private int getRandom(int range) { return random.nextInt(range);}

}



An even trivial use of the Order object which is not even a unit test is shown below:



@Test
public void testOrderModel() {

Order order = new Order(23L, "Foo");

System.out.println("Order UserName:" + order.getUserName());

System.out.println("Order Total cost:" + order.getTotalCost(113));

System.out.println(Util.concatName("Sanjay", "Acharya"));

}



When I run "mvn install", I notice the following depending on the logging level I have setup in my log4j.properties, i.e., DEBUG or TRACE:



-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.welflex.model.ModelTest
Enter [com.welflex.model.Order.getUserName]
Exiting [com.welflex.model.Order.getUserName].Completed in:0 millis
Order UserName:Foo
Enter [com.welflex.model.Order.getTotalCost] Args :{Index [0], Value [113]}}
Calculating Cost...
Enter [com.welflex.model.Order.getRandom] Args :{Index [0], Value [113]}}
Exiting [com.welflex.model.Order.getRandom].Completed in:0 millis
Exiting [com.welflex.model.Order.getTotalCost].Completed in:2000 millis
Order Total cost:40
Enter [com.welflex.model.Util.concatName] Args :{Index [0], Value [Sanjay]},{Index [1], Value [Acharya]}}
Exiting [com.welflex.model.Util.concatName].Completed in:1000 millis
SanjayAcharya
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 3.12 sec



Parting Thoughts:
I think Aspects are rather powerful. There is plugin support for Aspects as well. For cross cutting concerns, use of Aspects is the way to go IMHO. Finally, although this is a maven project using JDK 1.5, there is no reason why this applies to maven only or cannot be used on previous versions of the JDK.

A maven project that demonstrates the above is available for download HERE
. One problem that I faced was getting the maven-aspectj plugin to install correctly. If you do install the same, you might want to add the codehaus repository to the pom.xml to ensure that the plugin is downloaded. To execute the project, from your command line, issue a "mvn install". There is a log4j.properties file in the project whose logging level you can tweak to see differences.

Enjoy :-)!

Saturday, April 11, 2009

Weblogic JMS Standalone Multi-threaded Client Security

I have been building a helper library that provides some convenience functionalities and all of a sudden it started failing with authentication exceptions. Not on obtaining Jms artifacts but during the send of a message. Jeez! One part of me says let go, deal with it on Monday, the other part is hungry to find out why. No prizes for guessing which part of me won :-)

The story so far:

Weblogic client runtime stores credentials in a ThreadLocal of the Thread that creates an InitialContext to obtain a jms resource, i.e., equivalent of saying the thread that has the credentials can execute privileged operations on certain JMS resource but as other threads do not have the credentials and thus, they cannot. Weblogic's security will obtain the information from the ThreadLocal and use the credentials therein for send/receive operations.

Now, in a Jms environment, one would like to create multiple javax.jms.Session, javax.jms.MessageProducer and use multi-threading where appropriate, sharing the same JMS connection. Think of a Servlet container that has multiple threads. If Jms artifacts (Connection factories, Destinations) are obtained only once using a Singleton by one of the Container's thread's, then it is only this thread that can send/receive messages from a JMS destination if the destination has security enabled on the same. The operation of creating a Context places a javax.security.auth.Subject in the ThreadLocal of the thread creating the Context. If the context is closed, the Subject is removed.

Consider the following example where the jms artifacts are obtained in a single thread of execution and a message is sent in the same thread:



public void sameThreadCreateSend() throws Exception {

InitialContext ctx = getInitialContext();

ConnectionFactory connectionFactory = (ConnectionFactory) ctx

.lookup("Connectionfactory");
Destination destination = (Destination) ctx.lookup("test_queue");

// Closing the context causes the send authentication exception
// ctx.close();

Connection connection = connectionFactory.createConnection();

connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

MessageProducer producer = session.createProducer(destination);

// Fails to send message as closing of the context removes the security information

// from the Thread local. If the context is kept open, then it works great.
producer.send(session.createTextMessage());
System.out.println("Sent message when send was called on thread that created context...");

}





In the above example, the message gets sent successfully, What about a case where the Jms artifacts are created on one thread and a thread created from the creator thread tries to send a message? Will the permissions get propagated to the child thread? Look at the code below:



public void testInheritableThreadSend() throws Exception {

InitialContext ctx = getInitialContext();

// Current Thread has the security information
final ConnectionFactory connectionFactory = (ConnectionFactory) ctx

.lookup("connectionfactory");
final Destination destination = (Destination) ctx.lookup("test_queue");

// This thread will have the security as well due to Inheritable thread local
Thread t = new Thread() {

@Override public void run() {
try {

final Connection connection = connectionFactory.createConnection();
connection.start();

Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

MessageProducer producer = session.createProducer(destination);
producer.send(session.createTextMessage());

System.out.println("Sent message using inheritable thread local...");
}
catch (Exception e) {

e.printStackTrace();
}
}
};

t.start();
t.join();
}




Yes the above code sent a message successfully as the credentials in the parent are propagated to the child thread via Inheritable thread local.

Now what about a case where the creation of the Jms artifacts are created on a thread that is not the parent of the thread that sends the message using those artifacts? Look at the sample below:



public void createOnSeparateThread() throws Exception {

// First thread opens a context and had the credentials
ResourceCreator c = new ResourceCreator();

c.start();
c.join();

// Second thread is not a child of the first, thus does not have the security
NonCreatorThreadRunner n = new NonCreatorThreadRunner(c);

n.start();
n.join();
}

private class ResourceCreator extends Thread {
InitialContext ctx;

Destination destination;

Connection connection;

@Override public void run() {

try {
ctx = Example.this.getInitialContext();

connection = ((ConnectionFactory) ctx.lookup("connectionfactory"))

.createConnection();
destination = (Destination) ctx.lookup("test_queue");

}
catch (Exception e) {
e.printStackTrace();

}
}
}

private class NonCreatorThreadRunner extends Thread {

private final ResourceCreator resourceCreator;

public NonCreatorThreadRunner(ResourceCreator resourceCreator) {

this.resourceCreator = resourceCreator;
}

@Override public void run() {

try {
resourceCreator.connection.start();
Session session = resourceCreator.connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);

MessageProducer producer = session.createProducer(resourceCreator.destination);

producer.send(session.createTextMessage());
System.out.println("Sent message when context was created on a separate thread...huh ???");

}
catch (Exception e) {
e.printStackTrace();

}
}
}




So the above send operation failed. Why? Because the second thread does not have the security credentials in its ThreadLocal. Now what if we could use the security information from the first thread on the second thread? We can, using weblogic security classes and using the javax.security.auth.Subject to execute a javax.security.PrivilidgedAction.




private class SubjectHoldingResourceCreator extends ResourceCreator {

Subject subject;

// Obtain the Subject from the thread
@Override public void run() {

super.run();
subject = weblogic.security.Security.getCurrentSubject();

}
}

private class SubjectUsingNonCreatorThreadRunner extends Thread {

private final SubjectHoldingResourceCreator creator;
public SubjectUsingNonCreatorThreadRunner(SubjectHoldingResourceCreator creator) {

this.creator = creator;
}

@Override public void run() {

try {
final Session session = creator.connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

final MessageProducer producer = session.createProducer(creator.destination);

// Execute a secure action using the Subject from the previous thread.
weblogic.security.Security.runAs(creator.subject, new PrivilegedAction<Void>() {

public Void run() {
try {
producer.send(session.createTextMessage());

System.out.println("Sent using Subject created on separate thread....");
}
catch (JMSException e) {

e.printStackTrace();
}
return null;

}
});
} catch (Exception e) {

e.printStackTrace();
}
}
}

public void testCreationOnSeparateUsingSubject() throws Exception {
SubjectHoldingResourceCreator c = new SubjectHoldingResourceCreator();

c.start();
c.join();
SubjectUsingNonCreatorThreadRunner r = new SubjectUsingNonCreatorThreadRunner(c);

r.start();
r.join();
}




The above example worked and sent the message. I have seen others facing a similar issue when using Spring classes such as JmsTemplate and DefaultMessageListenerContainer with Weblogic where this security issue bites them. Some folks have taken the route of initializing the Context before every send/receive of a message. This is clearly not optimal as the creation of an InitialContext is not cheap and can lead to degradation of performance.

My recommendation is to use the Proxy Pattern and have proxied versions of javax.jms.MessageProducer(s) and javax.jms.MessageConsumer(s) which ensure that calls to send/receive are executed within a PrivilidgedAction.
Look at my posting on Weblogic Jms Template to see how Proxies can be used.

The javax.security.auth.Subject can be obtained once in a multi-threaded environment for a particular user authenticator (userName/pass) and then be held for use by all the threads in the environment.

public Subject createSingleSubject(String providerUrl, String userName, String passsword) {

Subject subject = new Subject();
// Weblogic env class

Environment env = new Environment();
env.setProviderUrl(providerUrl);

env.setSecurityPrincipal(userName);
env.setSecurityCredentials(password);

try {
// Weblogic Authenticate class will populate and Seal the subject
Authenticate.authenticate(env, subject);

return subject;
}
catch (LoginException e) {

throw new RuntimeException("Unable to Authenticate User", e);
}
catch (Exception e) {

throw new RuntimeException("Error authenticating user", e);
}
}



If the above method is invoked once to set up a Subject, then the same Subject can be used by Proxies to invoke PrivilidgedActions.

One thing I don't like is that on closing of the obtained Context, the ThreadLocal object is not cleared of all allocated permission related objects. It is only the Subject that is detached. I am looking for a way prevent the caching of security information in the ThreadLocal by WebLogic.

Some Links:
1. Spring JIRA
2. Weblogic Security Documentation

Wednesday, April 8, 2009

Vote for Adam Lambert..a vote more importantant than your vote for Obama

I am not an Idol fanatic by any means, very far from it. I am however following this season. American Idol IMHO is a package, a singer with a great voice, who is sellable, has a dynamic persona, can get the chicks! Once in a while comes a singer who just does it freakin right. Adam Lambert from this seasons American Idol is the man. His rendition of "Mad World" is just super.

This guy has it all. The persona, the package, the voice for the next idol. I have found my American Idol, its Adam...Vote on! We need this guy at No.1. My theory is this person is Elvis reborn. Elvis lives!

Wednesday, April 1, 2009

Liking Emma and FindBugs Eclipse Plugins

I have found myself liking two helpers as I continue to develop, Code Coverage and Finding Bugs. I usually use plugins in maven reporting to help me find issues and coverage information after issuing a "mvn site".

I however prefer to catch the same without having to generate the maven site though and in my IDE. I see two nice eclipse plugins for the same. For the Code Coverage part, I quite like the Emma Eclipse plugin which allows me to run my unit tests in "Coverage" mode and helps me determine the amount of code coverage my unit tests are providing. The coloring is pretty good, green for fully covered code, red for missed code and yellow for partially covered code. Trying to be green...

I have also started to use the Find Bugs eclipse plugin. Professional "Hara Kiri" here but I often get pleasantly surprised by what the utility finds for me :-). It would have been nice if the "Problems" tab in Eclipse showed the issues found by "Find Bugs" via a different icon. Also I am refraining from showing results of either plugin here for obvious reasons :-))))

Monday, March 30, 2009

Java Closure(s) but no cigar?

It has now been a year since I have been working with Java 5+ features. During development, I have welcomed auto-boxing, the concise for loop, vargs, enums and Generics. In particular the last feature has been rather appreciated as type safe programming makes life for a developer so much easier. That said, I will also state that there have been many times that I have been troubled by the wild cards in generics and erasure. However, I find the take aways I get from generics far out weigh the few times I need to stress my brain with wild cards and erasure.

Like Generics, one equally important feature that the Java language has been wanting is Closures. A JSR for closures resulted in multiple proposals. Notably,
  1. Full Closures by the BGGA proposal
  2. CICE Simplified inner classes and
  3. FCM First Class methods.
As a note a poll taken to determine which proposal Java developers would welcome led to, BGGA taking the lead. Interestingly enough, a large percentage of Java developers felt that they do not want Closures in Java. My intuition tells me that a large percentage of the latter voters are saying "I do not want BGGA closures in Java" rather than "I do not want Closures at all".

A famous debate between Neal Gafter who has come forth as the major spokesperson for the BGGA closures proposal and Josh Bloch, a supporter of the CICE proposal has ensued via presentations and blogs. The same can be googled for.

A bit about my stance, I definitely see the power of Closures. However as the saying from Spiderman, the movie goes, "With great power comes great responsibility." I want the power that Closures offer in Java, and I want an implementation that I can understand and be productive with. I want intuitive compilation errors that will immediately alert me to the problem without straining the few @deprecated Grey cells that are still struggling to function in my brain.

I want conciseness, but not at the cost of readability and maintainability. In short, I want power with clarity and brevity. One cannot always get everything they want, sad but true, however, my stance is that if I can benefit considerably most of the time, I do not mind the pain for a little of the time. Think of it like a marriage ;-)))..luckily, the wife does not read my technical blogs lol! A better parallel; (Gain Factor >>>> Pain Factor == Adoption)

One can read about what a Closure is, what a Lambda expression is and I will not spend time on the same. Primary reason being, I cannot understand the same myself :-(

What I want to do in this Blog is to understand Closures by BGGA and try for myself how hard or how easy is it to work with them. I do not use an IDE but revert to using emacs and the command line for this exercise.

I downloaded the BGGA propopal and ran some of the examples from the Java Closures Tutorial so very well explained by Zdeněk Troníček. Then I tried to apply the same to cases I have encountered before or am working with now to see for myself how easy/difficult the proposal is and problems I faced, if any.

Function Types:
I think function types would be a great addition to the language. I understand Mr.Bloch's concern that they might tend to lead to an exotic style of programming, however, I feel exotic styles of programming can even be developed with the simplest of constructs should developers choose to. It is possible for a psychotic developer as myself to take the simplest of problems and provide the most convoluted but workable solutions for the same. If I were introduced to the book Java Puzzlers prior to learning Java, I might have fled the scene. Sure, there will be puzzling cases but thats what code reviews, documentation, etc are all for after all. I am not sure I buy the argument, that "BGGA closures lend themselves to an exotic programming style". One can easily be exotic with the simplest of language constructs IMHO.

Lets look at a couple of examples, I have an eachEntry() method that runs through an java.lang.Iterable and executes the block provided. I also a have a simple filter() that can be used to filter an Iterable which delegates to the eachEntry().



public static <T> Collection<T> filter(Iterable<T> input,
{T=>boolean} filterBlock) {
Collection<T> filteredItems = new ArrayList<T>();

eachEntry(input, {T item =>
if (filterBlock.invoke(item)) filteredItems.add(item);});


return matched;
}

public static for <T, throws E extends Exception>
void eachEntry(Iterable<T> items, {T => void throws E} block) throws E {

for (T item : items) {
block.invoke(item);

}
}



An example usage of the above where Employee objects are filtered:



// Static import the utility functions, filter and eachEntry
import static com.welflex.util.Utils.*;

List<Employee> emps = ...// Get employees

// A closure that uses the Function type of eachEntry to dump out the
// information about each employee
eachEntry(emps, {Employee e =>
System.out.println("Id:" + e.getId()

+ ", Manager:"
+ e.isManager()
+ ", Salary:" + e.getSalary());});

// Filter out only employees who are managers
Collection<Employee> managers = filter(emps, {Employee e => e.isManager()});

// Filter out only managers who earn gt 60000 using a filter of filters
Collection<Employee> mgrsGt = filter(filter(emps, {Employee e => e.isManager()}), {Employee e => e.getSalary() > 60000);

// The above one re-written
mgrsGt = filter(emps, {Employee e = > e.isManager() && e.getSalary() > 60000});



I find the above pretty concise and powerful. I also find the same rather easy to read as well. So no complaints from me there. For those reading, hey I never claimed I was invincible as far as programming goes, close to invincible, yes ;-)

Now the negative, some things I could however not understand,

a. for construct did not work for me:
"for" construct did not work for me. I might not have done it correctly, but the eachEntry() that uses the "for" construct compiled just fine. Compiling the following should have worked, I am not sure what I am missing:



for eachEntry(Employee e : emps) {

System.out.println("Id:" + e.getId());

}



A compilation error leading to:
"Filter.java:20: method forEach in class Filter cannot be applied to given types
required: java.lang.Iterable
,javax.lang.function.OO,java.lang.Class
found: java.util.Collection,{T => void},java.lang.Class
forEach(orig, {T item => if (block.invoke(item)) matched.add(item);},"

The above was not very instructive for me in addressing the issue :-(

b. Static Inner Class when used in the example caused compiler error:

When my Employee class was a static inner class, I ended up with the following exception when I tried to compile the examples class, leading me take it the Employee class to its own separate compilation unit:

exception has occurred in the compiler (1.6.0_11). Please file a bug at the Java Developer Connection (http://java.sun.com/webapps/bugreport) after checking the Bug Parade for duplicates. Include your program and the following diagnostic in your report. Thank you. java.lang.NullPointerException at com.sun.tools.javac.comp.Resolve.isAccessible(Resolve.java:140)

I would like to also provide another example where I am using an ARM block to obtain a JMS Object from JNDI and subsequently closing the context. Note that I am not using actual javax.naming.Context classes but have instead modeled my own for the sake of demonstration. Without closures and using anonymous classes, I have the following:



private <T> T executeContextTask(ContextTask<T> task) throws LookupException {

Context ctx = null;
try {
ctx = new ContextImpl();
return task.executeWithContext(ctx);

} finally {
if (ctx != null) {

try {
ctx.close();
} catch (Exception e) {

//log this
}
}
}
}

private static interface ContextTask<T> {

public T executeWithContext(Context ctx) throws LookupException;

}

public ConnectionFactory getConnectionFactory(final String name)
throws LookupException {

return executeContextTask(new ContextTask<ConnectionFactory>() {
public ConnectionFactory executeWithContext(Context ctx)
throws LookupException {

ConnectionFactory c = (ConnectionFactory) ctx.lookup(name);

// Do something with Connection Factory before returning
return c;
}
});

}
....
public Destination getDestination(final String name)
throws LookupException {

... // Similar to above..except returns a Destination..//
}




The same above example when done using BGGA closures is simplified to:



private static <T, throws E extends LookupException>
T withContext({Context=>T throws E} contextTaskBlock) throws E {

Context ctx = null;
try {
ctx = new ContextImpl();

return contextTaskBlock.invoke(ctx);
} finally {

if (ctx != null) {
try {

ctx.close();
} catch (Exception e) {

// Log error
}
}
}

// Note name is no longer final, neither is there a class called
// Context Task and the anonymous class has been replaced by the
// closure.

public ConnectionFactory getConnectionFactory(String name)
throws LookupException {

return withContext({Context ctx =>
ConnectionFactory c = (ConnectionFactory) ctx.lookup(name); c});

}

.. Similar code for Destination...



Closure Conversion:
I quite like Closure Conversion. For example, I have an interface called Read that reads in an Employee Record. Assigning a closure to the interface type we have the below:

I am liking the conciseness presented by the above over writing an anonymous inner class + method definition + body (although the conversion is translated to the same).



interface Read {
public Employee read(String criteria);

}

Read readRecord = {String criteria =>
System.out.println("Criteria:" + criteria);

Random r = new Random();
new Employee(r.nextInt(5),
r.nextBoolean(),
r.nextInt(10000))};


public void closureConversion() {
Employee e = readRecord.read("select * from Emp where id=\"20\"");

System.out.println("Employee Read:" + e);
}




Arrays:
Arrays have boggle my mind in Generics, Arrays continue to boggle my mind with BGGA closures.



// Will not compile
{ => int} closures[] = new { => int}[10];

// Will not compile
{=>int} closures[] = {{=>5}, {=>6}};

// Compiles
List<{=> int}> list = new ArrayList<{=>int}>();

// But no way of
{=>int} closures[] = list.toArray({=>int} closures[0]);




Non local returns:
When returning from a Closure, should the "return" result in returning from the method itself? That is not very intuitive to me. I am of the opinion that returns from a closure, should only be local and not result in exiting the method. That is room for accidental programing with disastrous results.

Consider the following Code, what do you thing will be the result of the invocation?



static boolean testBooleanLocal(boolean input) {

{boolean =>boolean} closure = {boolean args=>

args
};

boolean result = !closure.invoke(input);

System.out.println("Test Boolean Local Result: " + result);
return result;

}

static boolean testBooleanNonLocal(boolean input) {

{boolean ==> boolean} closure = { boolean arg ==>

return arg;
};

boolean result = !closure.invoke(input);

System.out.println("Test Boolean NonLocal Result:" + result);
return result;

}

public static void main(String args[]) {

System.out.println("Local:" + testBooleanLocal(true));

System.out.println("Non Local:" + testBooleanNonLocal(true));

}



The answer is:



Test Boolean Local Result: false
Local:false
Non Local:true



What just happened to the second println()? All because I had a ==> versus a => along with a return statement?

The Syntax:
Without the assistance of an IDE, I had a few growing pains where I was accidentally doing "= >" instead of "=>", i.e, a space in between. Surely any IDE ready to support BGGA will catch the same. What about "==> "versus "=>"? Will an IDE be able to warn regarding the difference? I sure hope so :-)

Running the Examples:
As always, I am sharing my playground. For the ones interested, I tried the same using:
Download the ...., install the same and then set your PATH to include the existing JDK 1.6. For example,
export PATH=/.../jdk1.6.12/bin:$PATH. Then compile the provided code using the "javac" from the BGGA proposal, for example, "$BGGA_HOME/bin/javac -classpath .:com/welflex/utils:com/welflex/model:com/welflex/example *.java" and run the same using the similar syntax.

Parting Thoughts:
Sadness that Java does not have closures. Visual Basic developers are benefitting and thriving with the same, something I heard. Closures are a construct that has been around since ages, Java compromised at the time of inception via Anonymous classes rather then deal with the complexity of Closures, maybe a good decision for the time. However, time is now neigh for change. If Java has to survive, Closures need to enter the language. One cannot wait between JDK7 to JDK8 without knowing closures will or will not find a place in Java. Java folk are tending to gravitate toward other languages like Scala, Clojure etc. IMHO we need to stop this abandonement. My rationale for the same is (based purely on sentiments), I love Java, its been the reason for my bread and butter over the years, I love developing with it and I want to continue to develop with it. More importantly, its represents Coffee, I cannot wake up without my shot of the same. Scala or Clojure doesn't inspire me as much, maybe an alternate VM language called Nicotine could cut it and spark my interest ;-)

BGGA is not perfect. Sadly, nothing ever is. In my own humble opinion, the warring factions of Gafter/Bloch need to join forces to improve the compiler warnings, syntax and any other ambiguities in the features of BGGA present and look toward introducing it as part of JDK 8.X. Come on guys, you are super smart chaps (Phd's don't come easy) that have collectively led to the creation/enhancement of this great language, make my life easy and do not let me leave my favorite language for some pretenders to the throne :-(. If not, I propose that Gosling take the place of a dictator and get this in..I will welcome the same! Maybe IBM buying Sun will change things... Got to cut em beers when I post, for all you know I might have made a case for "No closures ever in Java via my misadventures :-)", lol!


Sample Code that I have used can be downloaded from here.

Resources: