Saturday, March 26, 2011

bing goes boing with axis2

If you've read posts hereabouts before, you know quite well how I feel about Axis2. You will understand, I hope, my lack of surprise at finding yet another piece of elegant congruence that Axis2 had wrecked by usurping the throne from ye olde Axis. Axis worked well with Commons HTTPClient and that library from the Apache Commons, like so many others, made life easier for a lot of developers. When Axis2 reared its ugly head from the sea of mediocrity and ambitious juvenile over-engineering, it made sure that this association was squashed. Here is how.

Have you ever tried using the Bing Maps web services using Axis? The curious aspect of these web services lay in how one had to request a token. This amounted to a request that used digest authentication instead of basic authentication. This was not such a problem if you had used ye olde Axis.

Unfortunately, you had moved into the future and had generated client code using the WSDLs and the tools in the JAX-WS RI. You then prepared to use this code atop the Axis2 JAX-WS stack (at which point you did not heed the pealing of alarm bells in the distance). Voila! The stack could do nothing for the first HTTP 401 response. There you were, in the middle of the ocean, staring at sharks as they discussed the latest episode of the hottest new sea soap opera, while waiting for a good time to transfer you to the dinner plate.

You had seen this code work with the standard Java Development Kit. Why was Axis2 being so different and difficult? You look at the code you wrote to use the generated client classes to see what you did wrong, to see if you had missed a step. You see the call to Authenticator.setDefault with the credentials. You know this is all you need to do. And yet.

Oh! goes your brain. Axis needed the Commons HTTPClient to help it with digest authentication. Surely, Axis2 could use Commons HTTPClient as well (after all, some of the developers on Axis2 had also committed code to Commons HTTPClient). You open axis2.xml and the first wave of horror hits you. The configuration already uses a class derived from Commons HTTPClient. The second wave of horror hits you almost immediately. They wrote their own middling class that left all the glory of Commons HTTPClient behind and treated it now as a messenger.

At this point, you hunt for something to hurt, wound, maim and dismember as you gnash your teeth.

Miraculously, Commons HTTPClient has a few tricks of its own and all you really need is the magic below.

import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScheme;
import org.apache.commons.httpclient.auth.CredentialsNotAvailableException;
import org.apache.commons.httpclient.auth.CredentialsProvider;
import org.apache.commons.httpclient.params.DefaultHttpParams;

    CredentialsProvider provider = new CredentialsProvider()

      public Credentials getCredentials(AuthScheme scheme, String host,
          int port, boolean proxy)
          throws CredentialsNotAvailableException
        Credentials creds = 
           new UsernamePasswordCredentials("BingMapsUserName",

        return creds;

        "http.authentication.credential-provider", provider);

And that, as several not-so-famous people have said before, is all. You can get rid of Authenticator.setDefault(new AuthenticatorImpl("BingMapsUserName", "BingMapsPassword")). Don't forget to replace BingMapsUserName and BingMapsPassword with the values that you use. I'm sure you can figure that out. If you can't, you deserve to continue reaping the benefits of Axis2.

As soon as you find the right opportunity, walk away very slowly from Axis2. Go find something else that doesn't look like a school project.

No comments:

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.