Nathan Zumwalt's Blog
My Links
Blog Stats
  • Posts - 6
  • Stories - 3
  • Comments - 2
  • Trackbacks - 6
Archives

Wednesday, September 07, 2005

Part of my labor day weekend was spent rebuilding my laptop.  I was working late Friday (and maybe playing a little World of Warcraft) and when I woke up Saturday morning my computer was infested with a host of nasty spyware.  Several sweeps of Ad-aware and Microsoft Anti-spyware couldn't fix the problem, so I had to re-image. 

I was able to back up all the data I could remember to get, but there are always those little nuggets of configuration information that are always forgotten.  In this case, it was my IM logs, my blog reader config and my Mozilla bookmarks.  So, I've vowed to keep all that important information under "My Documents" (which I map to c:\My Documents) for easy backup and retrieval.  I could just back up "Documents and Settings", but there is a bunch of stuff there that I don't want.

Mozilla was easy, I just created a profile with a root under My Documents.  Gaim was harder... there wasn't any way I could specify the location for the log files (very poor design on their part).  If I was running Unix, this wouldn't be a problem.  I'd just create a symbolic link from the hard-coded directory to the one that I wanted to use under My Documents. 

On a whim, I did a Google search on "Windows Symbolic Links" and found that Windows 2000 and above does indeed support symbolic links, though Microsoft has left it completely undocumented and done it's best to ignore the feature.  This article gives more information than you'll ever need to know about symbolic and hard links under Windows:

http://shell-shocked.org/article.php?id=284

It references a great tool by Sysinternals for creating symbolic links:

http://www.sysinternals.com/Utilities/Junction.html

The Sysinternals guys provide the source code along with Junction, so I was able to verify that no trickery is taking place; Windows API’s are used to create the links.  Sysinternals also has a plethora of other utilities along with source code.

In the end I was able to get all my configuration information under My Documents.  The one thing I don't like about Window's implementation of symbolic links is there doesn't seem to be a way to distinguish symbolic links from regular folders.  In the Unix world, links are marked when you do an "ls" and the location of the target is also displayed.

posted @ 8:03 AM | Feedback (2)

Sunday, August 07, 2005

I only recently discovered CruiseControl.  In my years of Java work, I used Ant extensively, but never came across a system like CruiseControl that did builds continually through out the day. 

CruiseControl enforces Continuous Integration, which is the concept that developers should be integrating their code with the larger system at least once a day.  Usually, integration is done infrequently and is a painful exercise.  If integration becomes a part of a programmer’s daily ritual, it becomes less painful as the developer is integrating smaller chunks of code.

In its simplest form, CruiseControl executes a NAnt script on a regular schedule.  That schedule could be when ever code is checked in, or every hour during the day.  If the NAnt script fails, the build manager is notified with an e-mail.  CruiseControl also includes a web-based dashboard that displays the current status of the build and gives the user the ability to force a build.  

It’s been my experience that these interim builds don’t go anywhere.  But, they find many errors long before a deployment to a server.  Generally, these errors are akin to not including a new file in source control, or changing a file locally without checking it out.  In other words, the errors that keep the build manager up late the night before a milestone is supposed to go out to the development server.  It also doesn’t allow developers to check in code that doesn’t compile (a cardinal sin on any project).

Coninuous Integration is a relatively new concept, but one that is generally understood and embraced.  Another concept that CruiseControl can enforce is controlled deploys.  I’ve been on too many projects where deployment requires an entire document of instructions or worse, there is no documentation and a specific individual with special knowledge has to do the deploy.  Usually, these sorts of builds have many steps that include such things as “after copying all files to the server, open a telnet session and type the following arcane commands”. 

If CruiseControl is used for deploys, then the only interaction can be a button click (the force build button in the CruiseControl dashboard).  The NAnt script has to handle all the steps for deployments.  Since only discrete steps can be included the NAnt script, the fuzzy logic associated with a deploy falls away.

Having to use NAnt for deployments doesn’t limit the scope of what can be done, but it does force the build manager to really think about their deployments and be very specific about each step.  NAnt has the ability to do everything from copying files to executing arbitrary .NET code.  In that spectrum of functionality the build manager should be able to codify the deployment.

This is a better situation for several reasons.  First, the deploy process can be put into source control along with every other piece of code in the system.  This allows the process to be versioned, reviewed and tightly controlled, just like any piece of code. 

Since the build is now kicked off by a single button click, any one can do a deploy to the server.  The build manager being sick, on vacation or generally inaccessible doesn’t preclude the possibility of a deploy.  This becomes key when those show stopping errors are found and a new build needs to be pushed out immediately.

In general, the process of deploying a system to the server is one of those “details” that is overlooked until the tail end of the project.  The build and deploy process should be as rigorously tested as any component of the system.  Using the combination of CruiseControl and NAnt, allows for controlling deploys as tightly as builds.

posted @ 3:47 PM | Feedback (0)

Tuesday, February 01, 2005

I love data structures.  In college, it was the only class that taught pertinent information (as least in my humble opinion), and it’s something programmers use every day (even if they don’t realize it). 

 

Many programmers don’t like creating their own data structures for some reason.  I don’t know if it’s because it’s intimidating, or they’re just lazy.  What the short-sighted programmer doesn’t realize is that exclusively using Java’s built in data structures and creating work around code to implement requirements makes code less intuitive and harder to maintain.  Instead, if a requirement isn’t easily implemented using one of Java’s many built in data structures, then a custom data structure should be created...

 

Read on for supporting arguments, opinions and juicy bits of code.

 

posted @ 6:00 PM | Feedback (0)

Monday, January 03, 2005

Generally, I’m not a big fan of web services and SOAP in particular.  SOAP is bloated and awkward.  It’s difficult to read (let alone write) the requests and responses associated with the WSDL.  It’s frustrating when you have to create a 30 line WSDL file so your 5 line Java file will be recognized as a web service.  Apparently the good folks at Apache feel the same frustration and gave to us Axis. 

 

On the server side, Axis does for web services what JSP did for Servlets: provide a simplified, file-based approach to registering web services.  The first step is to download the Axis package, which you can do here:

 

http://ws.apache.org/axis/

 

Then, drop the web application conveniently found in the zip file into your web container of choice.  Keeping with the Apache theme, I’ve used Tomcat for this demonstration.  Now that the infrastructure is in place, I can start creating my web services.  I took the following code and put it in a file named TestWebService.jws in the root of the ‘axis’ web application:

 

import org.apache.axis.client.Call;

import org.apache.axis.client.Service;

 

import javax.xml.namespace.QName;

 

public class TestWebService {

 

      public static String ping()  {

            return System.currentTimeMillis() + "";

      }

 

      public static Integer add(Integer value1, Integer value2)  {

            return new Integer(value1.intValue() + value2.intValue());

      }

}

 

This done, I fired up my web browser (Firefox, of course), and went to this URL:

 

http://localhost:8080/axis/TestWebService.jws

 

Axis tells me that my web service is now alive.  If I append “?WSDL” to the URL, I get WSDL that Axis created for me.  That’s right; I didn’t have to create a lick of XML for the WSDL.  And, just like JSP files, if I update my JWS file, the WSDL and code will be updated in the web container without have to reconfigure and restart.

 

On the client side, Axis gives some moderate simplification as well.  To test out my new web service, I created this Java class:

 

import org.apache.axis.client.Call;

import org.apache.axis.client.Service;

 

import javax.xml.namespace.QName;

 

public class TestClient {

 

  public static void main(String[] args) {

    try {

      String endpoint =     

        "http://localhost:8080/axis/TestWebService.jws";

 

      Service service = new Service();

      Call call = (Call) service.createCall();

      call.setTargetEndpointAddress(new java.net.URL(endpoint));

 

      call.setOperationName(

        new QName("http://soapinterop.org/", "ping"));

      System.out.println("ping response=" +

        call.invoke(new Object[] {}));

 

      call.setOperationName(

        new QName("http://soapinterop.org/", "add"));

      System.out.println("add response=" +

        call.invoke(new Object[]{

        new Integer(100), new Integer(2000)}));

 

    } catch (Exception e) {

        e.printStackTrace();

    }

  }

}

 

The Service object maps to a web service, which I can then call operations on.  We still have to dive into the XML muck via the QName object, but overall it’s less painful than Sun’s “official” API’s for accessing web services.

 

Overall, Axis makes great strides in simplifying web service access using SOAP.  There are some limitations to the file based approach (such as not being able to define custom serializers/deserializers), but for quick web services it’s the way to go. 

 

 

posted @ 10:27 AM | Feedback (0)

Wednesday, December 01, 2004

I noticed today that Amazon.com has recently updated their web services.  I’m a big fan of Amazon Web Services (AWS) for several reasons.  First, it was the impetus for my online media library (currently offline pending my move to the country), which allows me to retrieve information on any media known to man given a keyword, or an ISBN if it happens to be a book.  Second, AWS doesn’t require the use of SOAP.  Personally, I find SOAP bloated and awkward.  Instead, Amazon provides a rich URL-based API that returns XML.

 

For example, if I wanted to search for Star Trek DVD’s, I would use this URL:

 

http://webservices.amazon.com/onca/xml?

Service=AWSECommerceService&SubscriptionId=1NW536V6NDVV1P4F0V82

&Operation=ItemSearch&Keywords=star+trek&SearchIndex=DVD&Sort=

 

The SubscriptionId is provided after registering… all the other parameters are fairly self explanatory.

 

Another reason I like URL-based API’s is that Java makes it very easy to parse the XML.  This method loads the XML from the URL and returns a Document:

 

private static Document getDocument(String url)

     throws ParserConfigurationException, IOException, SAXException {

     DocumentBuilderFactory factory =

          DocumentBuilderFactory.newInstance();

     DocumentBuilder builder = factory.newDocumentBuilder();

     return builder.parse(url);

}

 

Once you have the Document, it’s easy to read data using DOM.  I’m an XPath man myself:

 

  public static void searchDVDs(String keywords) {

    try {

      String url = "http://webservices.amazon.com/onca/xml" +

        "?Service=AWSECommerceService" +

        "&SubscriptionId=" + SUBSCRIPTION_ID +

        "&Operation=ItemSearch&Keywords=" + keywords +

        "&SearchIndex=DVD" +

        "&Sort=";

      System.out.println("Searching DVD's: " + keywords);

      Document document = getDocument(url);

      NodeList titles = XPathAPI.selectNodeList(document, "//Title");

      for (int x = 0; x < titles.getLength(); x++) {

        System.out.println(

          titles.item(x).getFirstChild().getNodeValue());

      }

    } catch (Exception e) {

      e.printStackTrace();

    }

  }

 

The latest enhancement is a queue service, which uses the same URL-based API approach or SOAP if you’re so inclined.  I’m not sure what Amazon hopes to achieve (in other words make money) by offering a general purpose queue, but its darned cool.

 

I thought about creating a JMS driver around Amazon’s queue, but didn’t want to wade into the JNDI muck.  Instead I created a quick Queue class that can create, delete, read and write as well as a QueueListener class that could kick off processes when a message is put on the queue (similar to JMS’s onMessage functionality).  Check out the code here:

 

http://blogs.parivedasolutions.com/nzumwalt/articles/168.aspx   

 

For more information on AWS, Amazon provides detailed API documentation as well as sample code on their website:

 

http://www.amazon.com/gp/aws/landing.html

 

posted @ 6:56 PM | Feedback (0)

Friday, November 19, 2004

Creating a socket-based server in Java is almost as easy as creating a socket connection.  Actually, the same class (java.net.Socket) is used on both ends of the communication channel.  This is a great solution for those “hard“ integration tasks with legacy systems.  Check out the approach and juicy code samples in my complete article: Sockets for Integration. 

posted @ 11:03 AM | Feedback (0)
Nathan Zumwalt