Tuesday, October 17, 2006

Introduction to Closures

Closures (also referred to as Blocks) are supported in many functional programming languages like SmallTalk, Lisp, Javascript..the newest ones being C# 2.0 and Ruby. So what are closures?

A closure is a block of code that can be passed as an argument to another method. At a most basic level, they are functions defined inside a scope of some sort. You can then pass the function around and call it whenever, and the function continues to execute as if it were still inside the scope it was defined in.

Example 1: Assume that the Remove.invoke method takes in two parameters: the service to call, and the callback function to invoke when the service call finishes.

function getSomethingById(id) {
Remote.invoke("http://domain.com/neat_service/" + id, function(response) {
recordSomethingById(id, response);
});
}

What's going to happen is that when the request finishes, the server's response is going to be passed as an argument to the callback function. This callback function is going to be invoked LONG after this bit of code actually runs to completion (because the remoting request is asynchronous). But still, as you observe, the callback function can use variables that are defined outside the callback, but inside the outer function (e.g. the id parameter), even though the outer function has long since returned. That forms the essence of a closure.

Example 2:
function counter(num)
{
var enclosedVar = num;
return function() {enclosedVar++};
}

Here - as you observe the inner anonymous function defines a closure over the local variable "enclosedVar". The function "counter" returns a reference to this closure, which can then later be executed at any point of time. Note that the local variable "enclosedVar" does not go out of scope, as far as the closure is concerned.

We can put this closure to use as follows:

var myIncFunction1 = counter(5);
var myIncFunction2 = counter(10);

The function references returned by the counter method can be stored in a variable and invoked as follows:

print(myIncFunction1()); // prints value 5
print(myIncFunction1()); // prints value 6
print(myIncFunction2()); // prints value 10
print(myIncFunction2()); // prints value 11

Note that we will get the output as mentioned above, because the two separate calls to counter method actually created two independent closures.

Closures as inside-out objects:
Rightfully referred to as that. Objects are data that have sub-routines attached to them, where as, closures are sub-routines with some data associated with them.

Passing code around, instead of data:
If I have to sort a collection of things, where the collection can possibly contain different types of data, I will have to write separate sort methods in order to handle the various types of data. However, with closures and the ability to pass code / functions as arguments, I can write one single "sort" method that accepts the collection as one parameter and the code to do the actual comparison as the second parameter. Found one code snippet that shows how this can be done:

function sort(collection, comparator) {
var n = collection.length;
for (var i=0; i < n - 1; i++) {
for (var j=0; j < n - i - 1; j++)
if (comparator(a[j+1], a[j])) {
swap(collection, j, j + 1);
}
}
}
}
c = [
{name: "barney", height: 195, weight: 80},
{name: "heather", height: 182, weight: undefined},
{name: "jerry", height: 185, weight: 81}
]c_by_height = sort(c, function(a, b) {
return a.height < b.height;
});
c_by_name_reverse = sort(c, function(a, b) {
return a.name > b.name;
});

So - here the sort method is pretty much generic, we can write different comparators to handle the actual comparison and pass those comparators around.

One good link that gives examples of closures in Javascript: http://blog.morrisjohns.com/javascript_closures_for_dummies

Monday, October 16, 2006

J2ME MIDP 2.0 - A world away from the J2SE world

I have been working on J2ME (Java 2 Micro Edition), particularly MIDP 2.0 (Mobile Information Device Profile) for the last 3 months or so. We have been exploring this profile to develop a POC application that will run on MIDP 2.0 enabled cell phones. Coming from a J2SE background, where we don't really think much about memory and where UI capabilities are assumed to be good, I many times found myself saying.. "What? You cannot even do this? How am I supposed to construct a good-looking UI application then?".

Some obvious things I expected but did not find support for that in MIDP:

1. No file support by default: By default the MIDP 2.0 does not provide you with file IO APIs. So that means you cannot write to / read from files. There is a separate JSR 75, called File Connection Optional Package that provides APIs for accessing file systems on a device.

2. No nesting of panel / container components: In J2ME MIDP 2.0 user interface API, there can be only one outermost container component. This can be a Form, a List or a TextBox. It is not possible to create a container or a panel with child componentns and include that panel as a child of the Form. I found this very restrictive when it comes to building complex, good looking UI screens.

3. Very limited Layout support: Forget all the fancy GridLayout, FlowLayout and GridBagLayouts here! All you can specify is that I want a new line after a component or before a component and that I want all the 3 text fields to appear on one row. And that too, I observed is not necessarily the effect you will get in the end. It all depends on the screen size and the KVM implementation on the device I guess.

4. Key pressed events for characters: Don't you expect that if MIDP 2.0 does provide you with a KeyListener and does generate a keyPressed event, that it should generate these events for character keys as well? Well - you can, but in the case of MIDP 2.0 and cell phone world - it is too much to expect. The reason is that, the keycodes generated for the character keys are / can be different on different cell phones. That is why, MIDP 2.0 as a standard, does not mandate generation of key events for the character keys. Standard key codes and event generation can be assumed only for digits: 0 to 9 and some other keys like # and *.

We were trying to develop a custom text field component and therefore wanted to catch the events for character keys. One of the ways I got to know from someone to implement it, is to have a timer task, set a particular time interval, and map consecutive key presses to characters. For example: If digit 2 is pressed thrice in quick succession, interpret it as 3. Find this a very crude way of doing it and obviously restricts my code to a English key pad.

5. Standard components do not let me set the foreground and background colors: All I wanted was to have a different background color for a label component. I had to develop a custom label component just for that so that I could set the desired background and foreground colors.

The purpose of this blog is not to point out only the negatives or the limitations, the point I am trying to make here is only the absence of some of the things we take for granted in the PC world!

Thursday, September 28, 2006

Today's discovery: Google AJAX Search API

Look around a little... Do you see that Google Search text box at the top right corner of my blog? :-) Yes..there you go. That is the latest addition to my blog template and will remain there for some time at least. And today's blog is going to be about this little discovery I had today.

Google AJAX Search API (http://code.google.com/apis/ajaxsearch/)is a Javascript library that can be used to embed our very own Google Search in our web pages and web applications. The library provides simple-to-use Javascipt objects that perform inline searches over a number of Google services, which interestingly include:

1. Google Web Search (this is our very own google search engine)
2. Google Video Search (this is something interesting, especially from the point of view of one of the projects we might be doing)
3. Google Blog Search
4. Local Search
5. Google Map Search

Steps to follow to include Google Search within a web page:

1. Include the URL of the Google AJAX Search API Javascript library via a <script> tag in the web page as follows:
<script src="http://www.google.com/uds/api?file=uds.js&v=0.1&key=ABCDEFG" type="text/javascript"></script>

Note the "key" parameter. The value needs to be replaced by your key that you can get by signing up for one. (This seems a little unfriendly, discussed below as a down-side)

2. Include the CSS stylesheet that is used by the Google search component:
<link href="http://www.google.com/uds/css/gsearch.css" type="text/css" rel="stylesheet"/>

3. GSearchControl is the main class of the API that co-ordinates the search across different services. These services are to be added as children of this class.

4. GlocalSearch, GwebSearch, GblogSearch and GvideoSearch are the objects representing the various services. One or more of these can be added to the GSearchControl component using the "addSearcher" method.

5. Layout option: All these different searchers can be added on one page. They can be laid out linearly or in a tabbed page. Take a look at the google search I have added to my blog site. When you search for something, three tabs come up - Web Search, Google Blog Search and Blogger Search.

6. The control is drawn using the "draw" method of GSearchControl

7. When the user enters a search expression in the search textbox and clicks Search button, the "execute" method of the GSearchControl object is to be called to perform the actual search

8. The results are displayed inline. The number of results to be shown by default can also be controlled.

Some good points about this API:

1. With this API, I can very easily include Search capabilities in my web pages
2. The Video Search feature also provides a Playback feature using which I can play videos in the web page itself
3. The search results could be distributed or shared with other people. This is done by providing a "Copy" option below the links. So, when I click on the "Copy" option a callback function can be called. In this function, I can write my own logic for storing / copying these links. Makes a lot of sense in a "Bookmarks" kind of an application I am trying to develop right now. So the user can search for new URLs from within my application and store them as bookmarks then and there.

Some of the down-sides as of today:

1. This is still an experimental API, current version is 0.1. Google will be coming up with a version 1.0 soon which is expected to be a little different from this version. So at that time people might also have compatibility issues. And since this is just a basic first version, it will have bugs and early adopters will have to face some issues.

2. To use Google AJAX Search API in your web pages, you need to sign up for a key for a particular URL. The idea is that one can use that key in all the web pages under that directory. I am finding this a little tricky (especially when it comes to testing out applications that I am testing on my local Tomcat server) and also a little fishy, in terms of business use.

3. Browser compatibility: Currently supports Firefox, IE 6, and Safari, with support for additional browsers coming soon..

All in all - pretty exciting to try this out in some of the web applications.

P.S.: If you want to add Google Search capability to your blog, let me know :-)

Monday, September 18, 2006

One day with Google Gadgets

I came across the Google Gadgets API today (I know that is an old news already!). Google Gadgets API lets you write gadgets (referred to by Yahoo as widgets) or mini-applications that can run on a Google Personalized web page, Google Desktop or Google Pages (http://pages.google.com).

Here is the URL of Google Gadgets API: http://www.google.com/apis/homepage/index.html. As the overview page says, with basic knowledge of HTML and Javascript you can get upto speed wihin minutes with developing your first Google Gadget! Follow the steps given in the developer guide to build a simple gadget (it is a simple XML file), upload it on google pages or google base or any public web server and you are raring to go.

Try one simple gadget I developed (? :-)) to start with:

1. Go to www.google.com
2. Go to the Personalized Home
3. Click on the "Add more to this page" link at the top left hand corner
4. Click on the "Add by URL" link, next to the "Search Homepage Content"
5. Enter the URL http://arati.rahalkar.googlepages.com/myfirsttimegadget.xml
6. A dialog box saying "You are about to add a feature that was not created by Google. Do you wish to continue?" will appear. Choose OK.
7. The gadget will get added to your personalized Google home page displaying the current time and a greeting depending on the time of the day.
8. You can change some of the preferences by clicking on the "edit" button. This will show the preferences in a pop-up. Specify your name, the date-time format and the background color and click Save. See the preferences being applied to your gadget.
9. The next time you visit your Personalized Google home page, don't miss my first time gadget :-)

Pretty cool for starters huh?

One of the things I was searching for is to be able to embed these google gadgets in web pages other than just the Google pages. I tried embedding my gadget on my Google pages home page (you have to enable experimental features in Google Pages settings in order to embed standard / third-party gadgets). Check out my google pages home page at: http://arati.rahalkar.googlepages.com/.

However, I had to follow a very crude approach to embed this gadget on a web page. Viewed the source of my Google pages home page, and copy-pasted the div section that contained the gadget. It worked, but without the "Edit Preferences" option, as you can see below:



One of the nice things about Google gadgets which I have not really trid it out on the first day is that you can write AJAX-enabled gadgets. So you can have gadgets that fetch data from the server asynchronously and show you latest updated information.

As with all the other Web2.0 things and AJAX enabled toolkits, Goolge gadgets is not the only one in market. There are Yahoo widgets which have been around for a longer time, cannot compare the two since I haven't checked it out still.

On a side note: With AJAX and Web 2.0 coming so strong, I think good knowledge of Javascript is definitely going to be one of the skills a programmer needs to have. Cannot keep running away from Javascript code anymore!

Tuesday, September 12, 2006

Design by Contract

Dr. Bertrand Meyer, the man behind the Eiffel language the famous Design by Contract approach had come to our company to deliver a lecture. Although I did not know much about this approach, I attended the talk along with a few of my colleagues.

The talk was nice, with timely comic interludes. He talked about Eiffel as a language, the various features it provides, how it is better than any other existing language :-) and of course finally the Design by Contract approach.

The whole approach is centered around contracts - specified as pre-conditions and post-conditions. It is like signing a contract between the caller and the callee.
He gave an example of a water tank with two valves - input and output valve. The function of filling the tank is done by a method "fill". Now the pre-conditions for this method are:

1. Input valve should be open
2. Output valve should be closed (otherwise as he mentioned, it will take a long time to fill it :-))

The post-conditions are that:
1. Input valve is closed
2. Output valve is closed
3. Tank is full

This seems like a difficult thing to achieve in languages like .Net, Java, C++, but Eiffel language provides support for defining such contracts, thus making them a part of the design process itself. He gave examples of this language being used in many mission critical applications, one of the examples was the Chicago trade center - with terminals and monitors showing real-time stock data almost 24*7.

I do not know much about this approach, but as one of my colleagues who attended the talk with me said - He has been following this technique and approach with C++ and has found it to be very effective.

Tuesday, September 05, 2006

Preparing Powerpoint Slides - A skill?

Many freshers have joined our group very recently, and as part of their mentoring programs, each of them had to give a 10 minute long presentation on the scope of their mentoring assignment, what they are going to do, a brief look at the technologies to be used etc. etc.

I sat through all of them and at the end of it, actually ended up having a list of TO-DOs and the NOT-TO-DOs as far as preparing powerpoint slides is concerned. I am not talking about the "talking skills" or the "rendering" part, that is a different domain altogether - and takes more of personal capabilities, confidence, attitude etc. than mere TO-DOs. And I am discounting all the fresh graduates from that aspect - some people like me take time to get over their stage and people fear :-) So I know how it is and I am not even going there.

So here are some of the points to remember:

1. Use a good, pleasing template
Should be peaceful to the eyes of the reader. Please don't have a total black background with white text on it - so irritating to the eyes!

2. Be uniform, consistent as far as the font, font size, style, bullets are concerned
Microsoft PowerPoint gives you a lot of options I know - but that does not mean you have to try and use a different one in each slide. Consistency and uniformity is the way to go!

3. How much text to put on a slide?
There might be a lot you want to say, but make sure you do not clutter up the slide with your entire speech poured on it!
The other extreme, just two points in small font on one big slide with lots of white, blank space - again a no-no.

The whole idea is - Be crisp, short, to the point (words that make a lot of sense especially when you are making presentation slides)

4. Use animation wherever possible
While I say that, I also want to say what my manager rightly mentioned: Don't overdo it, don't have a cartoon character come running from somewhere and pointing at something on your slide :-)

But yes, animation used in just about the right proportion goes a long way in making an OK presenation an impressive one! (If not anything, you are going to have people wonder how you managed to get that animation :-))

5. Have an agenda at the start of the presenation
This will help you decide the direction of the presentation while you are making one and ofcourse at the time of giving the presentation as well. And then, it also helps the listeners know what is in store for them.

6. Agenda and the Contents of the presenation should go hand-in-hand
This seems obvious, but I have seen presentations where the agenda said one thing, and I, as a listener, kept on waiting for that one thing in the agenda that had interested me and well..that point never showed up later!

7. Full-stops come at the end of a "sentence" please
Yes - I have seen a lot of people putting a full-stop at the end of a point. A point is not a proper sentence and should not be ended with a full-stop. Definitely not at the end of the labels in an architecture diagram!

8. Flow of the presentation is important
Remember - you, the presenter, decide the direction of the presentation. People rely on you to take them in the right direction. You are the captain of the ship. Make sure the flow of the presentation is such that you take people along with you, get them interested in what you are saying and kind of come up with slides and content that they expect to be seeing next.

9. Spelling and grammar mistakes
Creates a very bad impression unnecessarily. You may be a great orator, but when I see obvious english mistakes in your slides - I am going to remember..yes - this is the guy who does not understand the difference between "Its" and "It's, Their and There, the importance of a 'a' and a 'the' at the right places".

It is just about being a little more careful really, isn't it? But I have observed that many people just don't care! And this "not caring", "casual" attitude may be "cool" sir, but I am not impressed.

10. A Thank you - Any Questions? slide is a good way to end the presentation (in some cases after References slide)
You are done, you have talked what you wanted to - leave the floor open for people to ask questions and doubts.
And of course - it is ok if you cannot answer them. "Lets take it offline" is a good way to handle questions or better still "I haven't really looked into this aspect in detail.. I will get back to you on this".

Next time you make a presentation, think before you write :-) And I am sure you have already started thinking of many more TODOs that I have perhaps missed.

Tuesday, August 29, 2006

What is Google upto?

Till almost 2 years back, Google was synonymous with Search. For my brother and father, both doctors, people who have become Net savvy very recently - Net means one of their Medical site and Google for anything that they cannot find otherwise.

However, if you just look around today, you hear Google coming up in far too many conversations - apart from the Search domain. You cannot help but wonder - What is Google upto?

It is amazing to see the vast array of tools Google is providing and the technologies Google is dabbling with:

GMail - has totally redefined e-mail applications
Google Talk - Like many others, I am taken in by its simplicity and useful features
GTalk integration with Gmail - cool idea!
Google Calendar
Google Spreadsheets
Google Checkout - haven't really checked it out :-)
Google Search API - now you can integrate Google Search into your web applications
Google Web Toolkit - awesome engineering idea
Google Maps
Google Earth - great, despite all the furore over security and privacy

So much more than the great Search Engine they are famous for!

There is so much out there to learn!

This post isn't about any specific task that was giving me problems and about how and what I did to work around the problem..

Instead this is just a very humble confession - there is so much, so much out there that I don't know about. So much happening on so many fronts, and I as a developer / engineer sitting in the front of a desktop machine in a company in Pune, India have not yet seen even the tip of the iceberg for that matter.

It is overwhelming at times to just log onto google and see the terabytes and gigabytes of data Google throws at you to read from. Over the last few days / months, I have been doing what every engineer's dream could perhaps be (especially when he is bogged down by deadlines and not finding any extra time for himself). I have been reading up stuff, checking out new technologies, searching extensively on the Net and reading new terms almost every day.

What I need to do in the coming few days - Look at SWT, Eclipse plug-in framework, Graphical Editor framework, Draw 2D (I know this isn't new, but GEF seems to be a very good piece of design work). If this isn't enough, I am now also hooked onto Web 2.0 (whatever that means!) - AJAX, Google Web Toolkit and everything that comes along with it, DOJO, Scriptaculous, AJAX Comet - phew!

One caveat is however to not get lost by this bombardment of information and be able to instead have a definite path carved for myself and my team.

Thursday, August 24, 2006

Back to the basics of isolation levels and locking

In one of my older projects, we were using WebSphere's Scheduler in order to schedule tasks that will run at regular intervals or just once at the specified time. The WebSphere Scheduler exposes certain APIs and mandates that the task be implemented in a certain way. The business logic to be executed at the scheduled time (i.e. what you want the task to do) is to be written in the "process" method of a stateless session bean that implements the "TaskHandler" interface. The information about this stateless session bean is registered with WebSphere at the time of scheduling the task. WebSphere in turn invokes this process method at the scheduled time in order to invoke the task. WebSphere stores the information about the tasks in its own tables, the main one being the TASK table.

For a very long time, we were facing a peculiar, consistent problem when it came to actually starting the tasks at the scheduled time. The WebSphere Server used to hang whenever the WebSphere Scheduler tried to start a scheduled task. The only option and a way out used to be restarting the server and telling everyone around - hey, you can test the remaining application all you want, but please do not schedule any tasks to run immediately!

We did figure the problem later on, and it really turned out to be a very computer science basics issue.

It had to do with locking of the TASK table. At the time of starting a scheduled task, WebSphere Scheduler does the following:

1. Gets a "ROW" level "write" lock on the row of the TASK table that contains information about the current task to be executed. It updates the table with the new state and the next fire time of the task
2. Invokes the task's process method in order to actually execute the business logic therein.
3. Once the task completes and the process method returns, the WebSphere Scheduler commits the transaction and then releases the lock.

Thus, all the calls to the Scheduler API are transactional.

Now, what was happening in our case was:

In our process() method implementation, we were trying to update our internal data structures with the next fire time of the task and hence trying to read the task information from the TASK table. This is when it was trying to get a "ROW" level "read" lock on the TASK table. However, since the row was already locked by WebSphere Scheduler and the transaction was not yet complete, our request for a read operation was getting blocked. It was a typical "deadlock" situation, ultimately resulting in the server threads getting hung.

So the solution to our problem was as simple as not reading the information from the TASK table at that point of time and moving that code to a later point in time. It all boiled down really to the basics of isolation levels, locks, transactions, levels of locks etc.

Overall - time well spent that made me refresh my "database locking" concepts once again!

Tuesday, August 22, 2006

J2ME and Mappoint integration

I happened to read a very good article by Michael Yuan, titled: Let the mobile games begin. It is a pretty old article actually, but contains a nice comparison of J2ME and .Net CF platforms for mobile application development. One example in this article is about using Microsoft's Mappoint web service for getting directions, routes and maps for desired locations, thus providing location based services from the convenience of a mobile phone.

I decided to try it out, with my basic knowledge of J2ME and especially about web services support in J2ME. As described in the article, I did the following:

1. Generated Java stubs using WSDL2Java tool of Apache Axis from the Mappoint Staging WSDL (available at http://staging.mappoint.net/standard-30/mappoint.wsdl
2. Wrote a wrapper class MappointClient that used these stubs to invoke the Mappoint web service
3. Exposed this wrapper class as a web service on Apache Axis (This is a nice idea actually that helps save a lot of wireless bandwidth and time. Explained well in the article. This wrapper class serves as a facade, which in turn makes multiple calls to the Mappoint web service to get the required information, over the relatively faster wired network).
4. Used custom Axis HTTP Connection handler that supports digest authentication (required by Mappoint web service, but not supported by default by Axis, again explained well in the article)
5. Used a third party library ksoap to invoke the facade web service from a J2ME MIDlet.

Well, you will think that things should just work fine, since they are explained so well in the article.. Yes - they should have, but they did not.

When I ran the whole set up, and invoked the facade web service from my J2ME MIDlet using ksoap, I got the following exception, that made no sense to me for a very long time:

Server redirected too many times (20)

To debug the problem then, I added a few debug statements to the custom HTTP Connection handler to check out the values of the HTTP headers. I realized that I was getting a text/html response back, where as I should have been getting a text/xml content in the response. On digging a little deeper, I figured that I was getting a Proxy-Authenticate header in the response with the following HTTP status code:

407 Proxy Authentication Required

Thus, this clearly was a proxy server issue. My machine was behind my company's firewall, and something was going wrong with the proxy settings.

First Try:

I set the system properties: http.proxyHost, http.proxyPort, http.proxyUser and http.proxyPassword to the correct values.

Did not work.

Second Try:

May be, my tomcat server was not picking up the System properties, hence I explicitly passed these values as runtime parameters to Tomcat. (In Tomcat 5.5, you do this by opening the Java tab and specifying the runtime parameters)

This did not work either.

Third and a successful try:

Stumbled upon this link http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html that explained the meaning of the various HTTP status codes.

The explanation of error code 407, as given in the site mentioned above:

"Indicates that the client must first authenticate itself with the proxy. The proxy MUST return a Proxy-Authenticate header field containing a challenge applicable to the proxy for the requested resource. The client MAY repeat the request with a suitable Proxy-Authorization header field."

So, this clearly was how the proxy server was behaving in my case. I included a small fix given below in the custom HTTPConnection handler's writeConnection method:

String userPassword = "username:password";
String encoded = Base64Coder.encode(userPassword);
conn.setRequestProperty("Proxy-Authorization", "Basic "+encoded);

Tested with:
1. Apache Axis 1.2 (but should work just fine with Axis 1.4)
2. J2ME: CLDC 1.1 and MIDP 2.0
3. ksoap for web services support
4. Tomcat 5.5

It was fun doing this exercise. Learnt quite a few things and in the end got a nice looking, impressing J2ME MIDlet up and running - one which shows turn by turn directions given the start and end locations and shows a nice map with the route highlighted :-)

Get the WSDL styles basics right!

This blog is really a continuation of the earlier blog about J2ME Web Services, and document/literal support of Axis.

As it turns out, Apache Axis was generating the correct response - as far as the document/literal WSDL-SOAP binding is concerned. In my particular example, what I needed to use was the document/literal wrapped WSDL binding. Wish I had read this article before:

http://www-128.ibm.com/developerworks/webservices/library/ws-whichwsdl/

A very good article that really clears the confusion a novice like me might have around the different WSDL "style" and "use" attribtues and their meaning. A must read!

Monday, August 21, 2006

Playing around with J2ME Web Services Optional Package (JSR 172)

Problem at hand:

I have been exploring J2ME for the last few months. One of the things I wanted to do was to check out the J2ME Web Services Optional Package (JSR 172) and write a simple sample POC MIDlet that uses the J2ME Web Service Client APIs to invoke a web service. I had already tried using the third party library ksoap and had been successful at it.

One thing to note about J2ME Web Services Optional Package is that it supports only document/literal type of web services for now. So that meant figuring out how to write a document/literal service using Apache Axis.

The set-up I had at the server side was:
1. Tomcat 5.5
2. Apache Axis 1.2

The set-up at the client side was:
1. Sun Wireless Toolkit for CLDC version 2.5
2. Eclipse 3.2
3. Supported versions: CLDC 1.1 and MIDP 2.0

Server side:

1. Wrote a very simple HelloWorld class in Eclipse, with the following three methods:
   a. String sayHello()
   b. String sayHelloWithTime()
   c. String sayHelloToMe(String me)
2. Exposed this simple HelloWorld class as a web service in Apache Axis 1.2. To make sure the web service is of type document/literal, I made the following settings in the wsdd file (apart from the usual ones): provider="java:RPC" style="document" use="literal"
3. Used to AdminClient tool to deploy the web service onto Axis.

And lo - my web service was deployed and accessible in no time.

Client side:

1. J2ME Web Services Optional Package does not have support for dynamic invocation of a web service (the way ksoap has). Therefore, it is necessary to generate static stubs (which is not that much of a problem really).
2. Sun Wireless Toolkit provides a Stub Generator utility that, given the location of the WSDL file, generates the J2ME client stubs.
3. Once the stub was generated, I wrote a simple MIDlet with only one form to use this stub class (that acts just like a normal local class) to invoke the web service.

Having done all this (of course I had achieved this after having spent some time on the Net), I was expecting things to work fine, although I soon realized that I had just opened a Pandora's box! I kept on hitting problems one after the other, and I kept on solving one at a time. Lately I have realized that I actually enjoy such small struggles, at the end of it they almost invariably give me some sense of an achievement, however small that might be..

OK - so lets see what all came out of the Pandora's box:
1. I kept on getting weird useless exceptions such as: Invalid element in server response, Invalid namespace, found xxx, expected yyy
2. While trying to find some logical explanation to what was happening, my fertile mind came up with the following few conclusions (which obviously proved wrong later):
   a. That Apache Axis Server is generating a different response when the web service is invoked from a J2ME web service client (Yes - so you see, blame it on the JSR 172 implementation!)
   b. The Apache Axis Server is not able to handle methods with the same signature (OK - so if nothing works, I can always pass dummy parameters to have all methods have different signatures, can't I?)
3. Something was definitely going wrong with the response, since I was not getting one that I expected (or rather the one that my stub was expecting), so I decided to use the oh-so-useful SOAPMonitor of Apache Axis.

Enabling the SOAPMonitor:

I enabled the SOAPMonitor by following the steps given here: http://www-scf.usc.edu/~csci571/2006Spring/axisinstall.html

My first conclusion (2 a) was soon proved wrong when I checked out the response I received from the server using both a J2ME and a normal J2SE web service client. In both cases, I was getting a wrong response. To give an example, the response I received was:
<soapenv:Body>
<meReturn xmlns="http://helloworldsample">Hello Arati</meReturn>
</soapenv:Body>

Where as according to the WSDL, I should have got the following: (Note the differences in the element name and the namespace)

<soapenv:Body>
<sayHelloToMeReturn xmlns="http://localhost:8081/axis/services/HelloWorldService">Hello Arati</sayHelloToMeReturn>
</soapenv:Body>

Some desperate attempts to get it working:

1. After cursing Axis 1.2 too much, I moved on to Axis 2. This however, turned out to be a wrong decision - did not really help, Axis 2 has been completed rearchitected, redesigned and I unnecessarily spent almost one day figuring out how to deploy a very simple web service on Axis 2 and then how to enable the SOAPMonitor on it.

2. I posted my queries, my doubts on the J2ME Forums and a few other forums (ex. Artima).

3. Having received no help from there, I moved on to the safe Axis 1.4 version. And then once again started fiddling around with the SOAPMonitor. One thing I realized (which I should have seen earlier) was that the SOAP request itself was not being formatted correctly. For example, on invoking the String sayHelloToMe(String me) method, the SOAP request was as follows:

<soapenv:Body>
<me xmlns="http://helloworldsample">Arati</me>
</soapenv:Body>

Ideally, with my basic knowledge of SOAP, XML et al, I knew that this is wrong. The response should definitely have contained the method name (sayHelloToMe) - how the hell is the Axis server otherwise going to understand which method to invoke?

4. This finally put me on the right track. I then doubted the document/literal support of Axis for the first time (that was a correct doubt) and on reading up a little realized the difference between the style "document" and style "wrapped". Check out this in detail in Axis's user guide at Service styles section

5. I made changes to the wsdd file to use style="wrapped" instead of document style, redeployed the web service, regenerated the stub classes using the stub generator and then checked out the MIDlet once again. This time I had hit the jackpot! The J2ME web service client worked beautifully, and the SOAPMonitor also started showing me expected results!

Well - so after a little fight and desperate searching on the Net for about 2 days (duh - I know I should have got this sooner than this) - I have cracked J2ME Web services + Axis combination, at least for the simple things..

Three cheers for the SOAPMonitor - Hip hip hurray, Hip hip hurray, Hip hip hurray!