Wednesday, July 16, 2008

Groovy is ... well Groovy!

There are so many great things about Groovy from helper classes for Collections, XML/HTTP/SWING/etc builders, simple parsers, closures, a built in shell to run classes and groovy scripts, and many more. Since this is a blog and not a book, I wanted to highlight one interesting feature of Groovy that helped me understand the true concept of the "meta-language".

Groovy in a way generalizes many of the classes that most Java developers are accustomed to managing in day to day code. In Groovy we deal with POJOs, Plain Old Groovy Objects (POGOs), and interceptors. Groovy has provided a layer to capture each object type. In general this layer is called the Meta-Object Protocol (MOP).

Let's take each object type for a bit of a spin...


class TestMethods extends GroovyTestCase
{
void testPOJO()
{
def val = new String("test method call on POJO")
assertEquals "test method call on POJO" , val.toString()
}

void testInterceptedPOJO()
{
def val = new Integer (999)
Integer.metaClass.toString = {-> 'intercepted at testIntercepted test case' }
assertEquals "intercepted at testIntercepted test case" , val.toString()
}

void testInterceptable()
{
def obj = new InterceptableObject()
assertEquals 'intercepted existingMethod on object', obj.method1()
assertEquals 'intercepted existingMethod on object', obj.method2()
assertEquals 'intercepted existingMethod on object' , obj.existingMethod()
assertEquals 'intercepted existingMethod on object' , obj.nonExistingMethod()
}

}

// Interceptable Object
class InterceptableObject implements GroovyInterceptable
{
def invokeMethod(String name, args) {'intercepted existingMethod on object'}
def method1() {'method1 called'}
def method2() { 'method2 called' }
}

// POGO
class GroovyObject
{
def method1() { 'method1' }
def method2() { 'method2' }
def closureProp = { 'closure called' }
}


Notice that there are several methods for intercepting objects based on the object type (POGO, POJOs, and interceptors) It is also possible to create closures at runtime which essentially injects a new method into an object.

The Interceptable class and testInterceptable method demonstrate a few ideas. The first is that invokeAll will overide all methods in an object. Both method1() and method2() will return "intercepted existingMethod on object" in these examples. Also, Groovy provides the existingMethod() and nonexistingMethod() which define closures for any existing or nonexisting method. This can be useful for catching generic cases that might not fall under a set of predefined methods.

There is a lot more to describe with MOP and dynamic Groovy, and more can be found here. Also, I hope to soon cover DSLs and Groovy which is itself a great topic.

Friday, July 11, 2008

Run Windows XP on Ubuntu using VMWare

I had a few apps that I still use in Windows :( which motivated me to run Windows XP on my 64bit Ubuntu v2.6.24-19 using VMWare server. Thanks to my amigo Dave Riches for getting me started on this. For all my other colleagues that have asked about this, here are the steps and some details on how to set this up.

First, download the VMWare Image Converter from here. Install this on your Windows box and create a VMWare image using the VMWare image converter wizard. The details within the wizard depend on your situation. I believe most settings can be modified later, so your setup is by no means permanent. If you have the ability to clean out your Windows OS before making an image, I would recommend a good cleanup. I had 56GB of files and starting this image later in VWWare server proved to be extremely slow. An image of a clean OS install would be the best scenario.

Next, move the image to your Ubuntu OS. I had a 500GB external hard drive that I used to move the images over. The image converter allows copying over the network too to your target Ubuntu server. All you need is a Samba mount on Ubuntu to move the files over if you choose to move your image over the network.

Now install the VMWare Server on your Ubuntu OS. There are also instructions out there which describe the VMPlayer setup too. Here's a good article on how to do that, and this also describes how to workaround a header issue that some Ubuntu versions (v2.6.24.16) had with VMWare Player/Server installation.

You will also need a C compiler installed on your Ubuntu machine. The VMWare install will compile all of the libraries during install. The installation will give you specifics if you are missing anything.

Fire up VMWare Server/Player now! You might see something like this..

VMware Player unrecoverable error: (vcpu-0)

Failed to allocate page for guest RAM!


A log file is available in "/path/to/VM/vmware.log". A core file is

available in "/path/to/VM/core". Please request support and include

the contents of the log file and core file.

To collect data to submit to VMware support, run "vm-support".

We will respond on the basis of your support entitlement.


Looking at the VMware log file will show the message "Could not mmap

paging file : No such device".


There is a setting in the Virtual Machine's .vmx config file to fix

this. Edit the config file, add

mainMem.useNamedFile=FALSE



I was finally able to start my VMWare image. The next issue was extremely slow startup time. No biggie, I'll just go grab a cup of coffee.... in the next state! Yah this was slow. I had to tweek some things to get the speed into acceptable condition. These tweeks included...

  1. Set the VMWare image memory settings closer to the recommended memory. VMWare server will tell you the recommended setting. Mine was 256M, but I doubled that to 512M and I immediately saw an improvement.

  2. Install VMWare tools. VMWare Server has an option to do this.

    NOTE:
    the tools are installed into the VMWare image, not the player/server. I am presuming that once the tools are installed into my image I could go back and run my image in VMWarePlayer with the same tools installed.

    Once the VMWare tools were installed, I noticed improvements in both video resolution and less choppy mouse movements.

  3. I removed a lot of crud on my image. This included PICASA which does some background processing at the startup of my VMWare image. There was a floppy drive that I removed from the image that will never be used. This is really the part where you can be creative and is also why I earlier recommended creating an image with the smallest footprint possible.
So that's it. I was up and running after all this. I dont see any real big issues at this point. My Nortel VPN doesnt seem to be working, but I know of folks that have this running, so I'm sure I need to provide an update on my network settings for my image. You may also need to work out licensing with Windows. I had a serial number from the Windows I wiped off my old laptop and that seemed to work OK.

Good luck!