Sunday, June 13, 2010

Grails & App Engine is just not there yet

Just a quick follow up to my previous post; I've unsuccessfully tried to get the 'Hello, World' application running on App Engine. The java script pop-up never works and I run into timeout's far too frequently once deployed. There also doesn't seem to be much in the way of support for this combination yet.

For those interested, there was a brief mention of the problem during a fireside chat at Google IO. Here's the wave which summarizes the Q/A. If you haven't yet, I highly recommend the Google IO videos.


Labels: , , ,

Sunday, May 30, 2010

Groovy, Grails and GWT (G3WT) Tutorial

While HTML 5 holds tremendous promise, my days of fiddling with CSS are over. Fortunately GWT offers an alternative to the traditional Web Application paradigm; by cross compiling Java into Javascript you only need one language for both your server and your client. Back to the future.

Being a big believer in rapid prototyping, I'd much prefer having a Groovy -> Javascript compiler. Unfortunately Groovy isn't supported in the Client side GWT code since it's the .java files themselves that get cross compiled , not the bytecode. Still, it is possible to use Groovy ( Grails ) on the server side. using Grails and the GWT plugin. This provides the utility of Grails helper/scaffolding scripts and if you know Groovy it may save you time. Groovy's close coupling with Java also means that we need to not depart to far from the GWT paradigm either.

In order to learn Grails/GWT I decided to create a 'Hello World' application which uses RPC. Here's the step by step instructions I used to make it for those who are curious:

First make sure Groovy, Grails, and GWT are installed. Then we can create our Grails app:
>grails create-app g3wt

Now let's install the gwt plugin:
>cd g3wt
>grails install-plugin gwt

Create a GWT to provide the server side logic:
>grails create-gwt-module g3wt.Application

Create the client facing page which exposes the module we just created:
>grails create-gwt-page main/index.gsp g3wt.Application

It will (may?) prompt to ask if you want to create the main controller. Choose y for yes.

Now, lets git rid of the default grails page in favour of our new gwt page. You can do so by editing grails-app/conf/UrlMappings.groovy. Change "/"(view:"/index") to "/"(view:"/main/index") so that it picks up our newly created gwt page.

Now you're ready to try it. From a terminal the following to start up your development web server:
>grails run-app

Now start up GWT's "Development Mode" tool by running the following in another terminal:
>grails run-gwt-client

Click on the launch default browser button. Your new GWT should open and establish a connection with the Development Mode tool. At this point there's not really much here, so let's add a hello world rpc service.

First we create our Grails service:
> grails create-service Data

Edit the file grails-app/services/g3wt/DataService.groovy. Remove the empty serviceMethod method. Then add the following below "static transactional = true":

static expose = [ 'gwt:g3wt.client' ]
This line tells the grails helper script where to put the Java interfaces for the RPC calls.

Next replace serviceMethod with:

String helloWorld() {
return "Hello, World!"
}

Then we create the required normal and asynchronous interfaces under the src/java directory:
>grails generate-gwt-rpc

That's it for the server side. Now we edit the client scaffolding that was generated for us in
src/gwt/g3wt/client/Application.java.

Add the following import statements:


import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.Window;

Place the following in the onLoad method:

DataServiceAsync myService = (DataServiceAsync) GWT.create(DataService.class);

ServiceDefTarget endpoint = (ServiceDefTarget) myService;

// Note the URL where the RPC service is located!
String moduleRelativeURL = GWT.getModuleBaseURL() + "rpc";
endpoint.setServiceEntryPoint(moduleRelativeURL);

// Call a method on the service!
myService.helloWorld( new AsyncCallback() {
public void onSuccess(Object result) {
// It's always safe to downcast to the known return type.
String resultString = ( String ) result;
Window.alert( resultString );
}

public void onFailure(Throwable caught) {
}

}
);
There's a lot of GWT magic here. My understanding is that the GWT looks at this entire line when it cross compiles and generates the right javascript object for our rpc calls. Then we can perform an rpc call using anonymous call that implements the AsyncCallback interface.

Run it again:
>grails run-app

Start up GWT's "Development Mode" tool by running the following in another terminal:
>grails run-gwt-client

You should see our "Hello, World!" alert box.

In the next installment I'm going demonstrate how to run our example under Google App Engine.

Labels: ,

Sunday, May 16, 2010

Groovy++ Sources

It seems as though my cynicism was unfounded. You can find the Groovy++ source here.

My apologies to the author(s?). In my defence browsing the source tree through google code only yields the demo examples and last I checked the downloads only provided the examples as well.




Labels:

Saturday, May 15, 2010

Groovy++? Ok, so where's the beef?

Update: You can find the sources at http://code.google.com/p/groovypptest/downloads/list

If you're a software professional who uses Groovy, you or your colleagues greatest concern about it is likely to be performance. Groovy++, while having a horrible name, provides a jar which apparently provides some mag-i-cal Groovy performance gains. According to its authors', this new 'Groovy-ness' will be released under the Apache Public License. Terrific! Wonderful! Hurray!

So where's the fracking code?

I can understand a need for control. I can understand the author's desire to turn this into something significant for themselves financially. A man's got to eat. But until the code is open and can be inspected by some experts, I remain skeptical of Groovy++. I am hopeful however that performance improvements can be made given enough manpower and talent. Too bad we all have day jobs ;)

Labels:

Tuesday, December 22, 2009

Easy Hex SHA-1/MD5 Hashes with Groovy

The Java API has included support for a number of cryptographic hash functions ( MD5, SHA-1, etc) since Java 1.4 via the java.security.MessageDigest class. If you ever tried to use these in a web-centric context you've probably been a bit annoyed by the fact that it only provides hash results as byte arrays. Here's a quick and easy solution using Groovy that I thought I'd share:


def messageDigest = MessageDigest.getInstance("SHA1")
messageDigest.update( stringToHash.getBytes() );
def sha1Hex = new BigInteger(1, messageDigest.digest()).toString(16).padLeft( 40, '0' )


Notice the padding of zeros since the length of the SHA-1 hex needs to be 40 characters. If you're using a different hashing hex string length will change.

Note: Code updated to reflect an improvement submitted in the comments.

Labels:

Wednesday, December 16, 2009

Production Groovy Part I: The trouble with Grape

Like Perl, Groovy's utility is most evident while leveraging the work of others. In Groovy 1.7, Grape makes doing so intuitive with the addition of annotations on import statements:



@Grab( group = 'com.sun.jersey', module='jersey-core', version = '1.1.2-ea' )
import com.sun.jersey.api.core.DefaultResourceConfig
@Grab( group = 'com.sun.jersey', module='jersey-server', version = '1.1.2-ea' )
import com.sun.jersey.api.container.httpserver.HttpServerFactory



The trouble with Grape is that by default it resolves dependencies by contacting or attempting to contact certain Maven2 repositories. Now, this isn't a problem if you're a web startup looking to bring a product to market as quickly and cheaply as possible. But it is a problem if you're looking to start deploying Groovy to a secure production environment. Fortunately, Groovy's close coupling with Java provides a clean and elegant solution.

The key is that Maven2 remote repository caching and local repository hosting has been made easy by Artifactory. It can be configured to dynamically dial out and cache artifacts on demand from remote repositories. It can also more simply be used to manually manage artifact deployment. Thus provinding both flexibility and control.

In order to take advantage of Artifactory you'll want to modify the default Grape/Ivy configuration so it points to your internal Artifactory repository by default. The bad news is that you'll need to modify the an xml file and rebuild the the jar. The good news is that the groovy source itself uses Ivy so modifying the xml and building Groovy is really easy.

Simply download the latest Groovy source zip. Then modify '/src/main/groovy/grape/defaultGrapeConfig.xml'. You can then build yourselve a new zip distribution by running 'ant createJars -DskipTests=true'.
Skipping the tests is optional, of course.

Thats it. Once you explore Artifactory a bit you'll discover that it can provide as little or as much control of the artifacts available to Grape as you desire.

Labels: , , ,

Wednesday, December 2, 2009

Groovy Serialization - Part 2 - Objects

In my previous post I discussed the serialization of simple Groovy data structures. Arbitrary objects can also be serialized using ConfigObject and ConfigSluper and a little trickery. The fact Groovy config files may also contain code makes this all possible.

In order to instantiate objects inside a Groovy config file, you need import the referenced objects. You also need to override the toString to create the proper instantiation string.


package MyPackage
class MyObject {
def data;
String toString() {
def serializedString = "new MyObject( data : '${data}' )"
return serializedString
}
}

//create the datastructure
def myObject = new MyObject( data: 'wtf')
def configObj = new ConfigObject()
configObj.testing = [1, 2, 3]
configObj.nested = [ objects : myObject ]

//serialize it
new File( 'newout.groovy' ).withWriter{ writer ->
writer.write( "import ${myObject.getClass().getName()}\n" )
configObj.writeTo( writer )
}


Parsing it is simple:

def config = new ConfigSlurper().parse(new File('newout.groovy').toURL())
println config


Finally one could use .metaClass to override the toString of any Java object and make it work with this serialization technique. Be careful not to shoot yourself in the foot by doing this, as other code might expect the regular toString().

Labels: ,

Tuesday, December 1, 2009

Groovy Serialization

Groovy's lists and maps provide the simple building blocks of more complex structures. Occasionally you want to serialize these complex structures to files/streams/whatever. Previously I wrote about using JSON with Groovy. While this is still my weapon of choice for this problem, another alternative would be to use the ConfigObject and the ConfigSlurper classes from the Groovy API.

Here's how you would serialize the data using this method:

//create the datastructure
def configObj = new ConfigObject()
configObj.testing = [1, 2, 3]
configObj.nested = [ objects : 'wtf' ]

//serialize it
new File( 'newout.groovy' ).withWriter{ writer ->
configObj.writeTo( writer )
}


Then when you want to parse it:

def config = new ConfigSlurper().parse(new File('newout.groovy').toURL())
println config


One disadvantage of this method is that the highest level structure must be a map, since that's what ConfigObject inherits from. The data also contains a lot of white-space formatting. Which could be a good or bad depending on the problem you're solving.

Labels: ,

Friday, November 27, 2009

Groovy 1.7-RC1 Released / Groovy 1.7 Before Christmas

Groovy 1.7 RC1 has just been released and the final Groovy 1.7 is to be released by Christmas. By far my favourite new feature is the ability to add annotations on import statements. This allows you to put your @Grape() calls at the import statement that actually loads the packages grabbed which is where it should be IMHO.

While I'm still wrestling with the correct model for packaging 'grapes' in a production environment, as a veteran Perl coder I think grape will take Groovy to another level; It finally makes the Java ecosystem accessible and leveraging other's work easy. Now we just need a repository and IDE's that are grape aware :)

Labels:

Friday, October 23, 2009

Groovy CLI Parameters Made Easy

After getting thoroughly frustrated with the CliBuilder ( groovy.util.CliBuilder ), for its lack of documentation and unintuitive usage, I stumbled upon GOP (groovy-option-parser). Its almost exactly what I was looking for.GOP makes processing Groovy command line parameters (args) easy. Checkout the synopsis on its project page.

On a side note, Groovy really needs a CPAN.org equivalent. It has a fanastic runtime dependency loading/resolving system in Grape. It just need a single home/community for people to share modules just like this one.

Labels: , , ,