Tuesday, August 17, 2010

Generic Ajax Component for JEE Application - Part I

I developed a generic Ajax Component as part of the Javascript framework for a JEE Web Application a few months ago. Finally found some time to blog about it.


The requirements for the component are as follows:
  • This component will be used for an existing J2EE Web Application (which is based on a proprietary web framework).
  • This should work even with Java version 1.4 (well, there are clients that do not want to upgrade.)
  • The component should hide the Ajax details from the developers.

With these requirements in mind, I spent a couple of days experimenting with various possibilities and finally settled with the following design. The details of the actual implementation vary from the one presented in this blog. The design has been very much simplified here.

Components Chosen

Yahoo User Interface Library [YUI] - version 2.7.0
JSON-lib

Design

The idea behind this component is to have:

  • "In Parameter(s)" - List of DOM element(s) on the page, part of  input to the Ajax call.
  • "In Parameters Event" - An event on the In Parameter(s) that triggers the Ajax call.
  • "Out Parameters" - List of DOM elements present on the page. The response from the Ajax call will contain values for all these elements.
  • "Service Servlet" - The fully qualified name of the servlet which will be invoked as part of this Ajax call.


A sample of the javascript needed to Ajax-enable a page will look like this:

ClmAjax.AreaCodeAjaxServiceParameters = {
        servletName: "<>/services/AreaCodeService",
        inParameters: ['AreaCode'],
        outParameters: ["AreaCodeMsg"],
        inParametersEvent: "change"
};
ClmAjax.AreaCodeAjaxService = ClmAjax.ClmGenericService(ClmAjax.AreaCodeAjaxServiceParameters);
ClmAjax.AreaCodeAjaxService.addListenerForService();

In the above scenario, the developer wanted to listen change event on the field with Id AreaCode and invoke the AreaCodeService with an Ajax call and have the response targeted to the element with Id AreaCodeMsg.

The component takes care of serializing the data to JSON and invokes the service on the server with the JSON payload, the MVC framework on the serverside consumes the JSON input and serves the output back to the client in JSON format. The client side component deserializes the JSON response and manipulates the DOM based on the type of the out parameter(s).

The client side framework code attaches an event listener at the common container element (div), when the event bubbles up to this element, then the event handler takes care of making the Ajax call and rendering the response. There are hooks available, where the developer can inject logic that can be executed before and after Ajax call.

YUI did serve the purpose very well. I highly recommend it to anyone who would like to any serious front-end development. The component has served the developer needs very well and scales well too.

Next, I plan to port the same to YUI 3, which is an amazing library.
More technical details on this component in a later post...

Saturday, July 19, 2008

BIRT in WebLogic

I recently faced an issue with running BIRT reports [embedded into a web application] to run on WebLogic 9.2 Application Server.

The exception when the report was executed:

java.lang.NoSuchMethodError: initStandardObjects
at org.eclipse.birt.core.script.ScriptContext.(ScriptContext.java:80)
at org.eclipse.birt.report.engine.executor.ExecutionContext.(ExecutionContext.java:313)
at org.eclipse.birt.report.engine.api.impl.EngineTask.(EngineTask.java:160)
at org.eclipse.birt.report.engine.api.impl.EngineTask.(EngineTask.java:176)
at org.eclipse.birt.report.engine.api.impl.RunAndRenderTask.(RunAndRenderTask.java:54)
at org.eclipse.birt.report.engine.api.impl.ReportEngineHelper.createRunAndRenderTask(ReportEngineHelper.java:292)
at org.eclipse.birt.report.engine.api.impl.ReportEngine.createRunAndRenderTask(ReportEngine.java:303)

This I guess is due to the version mis-match of the Rhino jar [js.jar] used by BIRT and WebLogic.

Anyway, this is how I resolved the issue to move along...
Edited setDomainEnv.sh to include the following line:
EXT_PRE_CLASSPATH =
This solved the issue for me...hope this helps someone else with a similar issue.