Friday, 16 April 2010

New Writers for Unl33t

I've invited some of my friends and former colleagues to post here, in order to offer different perspectives on a wider subject matter. All of them are extremely well versed and highly experienced in varying areas of software development, and I'm looking forward to reading their posts.

The first is Rich Lowenberg. Rich has been a big presence in the professional Flash and Flex world for some time. He's done a lot of work leading teams to bring together many very slick flash and flex based sites. He's done some very cool stuff with Papervision3d as well. He's also very well versed in web standards development and some server side technologies. He's also a musician and writer, loves to travel, and recently moved to Amsterdam.

Enjoy!

Friday, 9 April 2010

Grails: Java's Saviour?

Grails is a RAD framework that runs on the JVM. The project, formerly called Groovy on Rails before the RoR folks complained, is essentially just what their initial name describes. It's meant to bring Rails-like productivity to the JVM world, while maintaining integration with all the lovely java-based API's available. To many, what exists in the Rails world will be sufficient, but in some areas, Rails just isn't there. Domain specific APIs (medical, banking, insurance, etc...) as well as some of the more beefy packages that would appeal to enterprise (security, workflow, rules, etc...) tend to come in Java or Java and .Net. Hence, the ability to get at these while gaining the velocity of Rails is very attractive.

Before we go too much further, though, a few points about what Grails is. Grails uses Spring and Hibernate, and can leverage the usual set of JS libraries (scriptaculous, prototype, jquery, etc...).

Code is written in Groovy, a dynamically typed language modeled to some extent on Java, but making heavy use of reduced syntax for common operations, and closures. Closures are a new beast in the java world, but should be familiar to those who write a lot of JS. Enclosing code in braces creates an implicit object which wraps that functionality and can be passed around. While this can take a bit of time for us Java guys to grok, it can be very useful.

Many dev actions are performed from the command line, using the "grails" command. This will be familiar to anyone who's used Rails. For example, grails create-domain-class Book will create a domain class named "Book". Subsequently running grails generate-all Book will generate scaffolding (a controller and various views) that can act as either a basis for code to use that object, or an out-of-the-box admin interface for that object. If you want to learn more about the details of using Grails, their Quick Start Guide is a good place to start.

While Grails has a lot of pieces of the puzzle, it still leaves a lot to be desired. The Eclipse plugins for Grails and Groovy have been in a dismal state for some time. SpringSource recently released a package for these which is a big improvement, yet problems persist. The dynamic typing nature of Groovy means method insight is rarely available, and the eclipse plugins appear to have huge memory consumption and some leaks. While a gc cleans up most of the memory (but not all), the frequency of gc'ing required really impinges on the dev velocity.

There continue to be bugs with complex relationships. Abstract domain classes cannot have many-to-many relationships or the app will fail to start. A given domain class can only reference itself once. This can prove challenging if one wants to build graph structures, for example. This is especially troublesome, since Hibernate supports these. Hence, something that translates Grails mapping syntax into Hibernate has serious flaws.

Grails also adds classes to the default imports, and these will have bizarre conflicts should any of your domain classes be named the same. The framework, and the tooling in the eclipse plugin, give no warning of potential problems.

I had the misfortune of having a domain class named PropertyValue. It lead to some very weird behaviour. The app would start fine and run fine, but a change to any class (controller, service, etc...) and the app would fail to run. I figured out later that something done in reloading the class would trigger the default import to take precedence, resulting in methods I was calling on my domain object not being present. When the app was assembled into a war for promotion, the app would fail to start entirely, for the same reason.

While Grails has a great many advantages, it is cumbersome to get into, and the failure in handling complex mapping situations will trouble many who are trying to build more advanced apps. I'm anxious to check out Spring's new ROO framework, which looks to circumvent the problems posed by the new abstraction layers between the user code and the underlying frameworks in Grails by generating modifiable "glue code", rather than the grails approach of implicit glue code. Anyone have any experience with Roo?

Thursday, 21 January 2010

My Employer Decloaked: Brightsquid

As some of you may know, startups need to spend a lot of their ramp up time off the radar, in order to allow their product(s) to mature. That phase just ended for my employer who has officially revealed themselves.

Brightsquid is a company who's goal is enable online collaboration for healthcare professionals. We have great product, and some phenomenal to be announced partnerships. We have a bright future (no pun intended).

When I was approached with the option to work at Brightsquid I jumped at it. The idea of helping those who cure the sick and save the dying is appealing to me. To be offered the opportunity to contribute to the staggering efforts put forward by healthcare practitioners is inspiring in no small way. Further, the more I learned about Brightsquid, the more I could see what game changer it is. I hate to use marketing-jargon, but this is a paradigm shift if ever there was one.

One of our founders, Rahul Sood, has a blog post more insightful than anything I could ever hope to muster, so I'll simply link to his post, and encourage everyone to read it.

Tuesday, 19 January 2010

Site update

I went back over some of my old posts and realised the code readability was horrible. I've added in syntax highlighting, should make things a little cleaner.

Enjoy!

Tapestry and Restlet Part 2

In my previous writeup on Tapestry and Restlet, I missed something, which fortunately our integration tests turned up.

Since Tapestry is ignoring calls to our REST api, we aren't hooked into their plumbing.  The problem here is that Tapestry stores a lot of stuff in ThreadLocal and removes it based on a Tapestry Filter.

Thus, while the result of my previous post will work in simple scenarios, one ends up with things like long running Hibernate sessions, and since Tapestry's transaction management is a bit wonky, long running transactions as well.

To fix this problem, we need to create a Restlet Filter that will handle triggering Tapestry's cleanup, and hook it onto our Router.  The cleanup filter:
package firstSteps.filter;

import org.apache.log4j.Logger;
import org.apache.tapestry5.ioc.services.PerthreadManager;
import org.restlet.Context;
import org.restlet.Request;
import org.restlet.Response;
import org.restlet.data.Status;
import org.restlet.routing.Filter;

public class CleanupFilter extends Filter {
private PerthreadManager perthreadManager;

public CleanupFilter(Context ctx, PerthreadManager perthreadManager) {
super(ctx);
this.perthreadManager = perthreadManager;
}

@Override
protected void afterHandle(Request request, Response response) {
perthreadManager.cleanup();
}
}

To hook this onto the router would be something like the following at the end of your Restlet Application's createRoot method.

CleanupFilter cleanupFilter = new CleanupFilter( getContext(),
getService(PerthreadManager.class) );
cleanupFilter.setNext( router );
return cleanupFilter;

Tuesday, 12 January 2010

Tapestry and Restlet - Updated

As one of our last big initiatives on Tapestry before we migrate platforms we're starting to build a REST api.

REST stands for Representational Entity State Transfer, which explains nothing to someone not already familiar with it.  Essentially, one uses URL's to define resources (http://mysite.com/users/trails for example), and leverages existing HTTP features instead of overloading parameters.  Specifically, using things like the HTTP method instead of a custom "action" parameter to specify the desired action to be performed on the resource specified by the url.

A former employer of mine, Gavin Terrill once pointed me to this introduction to REST article which is highly informative, and immediately sold me on the concept.

I have been for some time been a big fan of standards-based HTML.  Using things like <strong> instead of <span style="font-weight:bold"> always struck me as an improvement in elegance; to leverage the tooling provided by a medium means others have an easier time understanding what your app is talking about, be it screen readers, browsers, search engines, etc...

REST strikes me as an analogue to standards-compliant HTML, the intent being to leverage things already defined by HTTP rather than re-inventing the wheel.  It turns out that HTTP is fairly feature-rich, much more so than the POST-and-GET-with-cookies extent to which it used by most webapps today.

REST certainly has a couple points of ambiguity, for example batching, but there are options here with various tradeoffs.

Even though we plan to decommission Tapestry in our application, we're going ahead with this REST implementation because a) business needs dictate that we need this API b) the implementation is fairly independent of Tapestry.

There are a great many REST packages out there, we landed on Restlet simply because it seemed to require minimal integration, has a great set of features, and had the recommendation of a colleague.

We're using their 2.0 package which is in a fairly high state of flux at the moment, but offers improvements over their 1.X version that make this worthwhile.  The code herein is based on their 2.0-M6 milestone release.

You'll need to setup the dependencies in your pom (I assume you're using maven), for the following artifacts which can be retrieved from Restlet's public maven repo at http://maven.restlet.org/:


org.restlet.jee
org.restlet
2.0-M6


org.restlet.jee
org.restlet.ext.servlet
2.0-M6

Note the jee in the group id. This can be swapped for jse if you're operating in a jse environment.

Restlet at its simplest is built based on the idea of an "application" which manages "resources".  While it can certainly do much more complex stuff, this is sufficient for now.  We are familiar with resources as a core concept to REST, but the idea of adding on object called "Application" into your application might feel a little counter intuitive.  Your restlet "Application" can more easily be thought of as a REST url mapper.  It is the central object for your REST API.

You'll need to build a basic one and an initial resource.  For these, please look at the resource and application in this restlet tutorial.

You'll need to tweak the web.xml for your webapp to add the following snippet:


org.restlet.application

firstSteps.FirstStepsApplication




RestletServlet

org.restlet.ext.servlet.ServerServlet




RestletServlet
/api/*


I've mapped my REST stuff to appear under [application context]/api ,  [application context] being whatever you've setup your Tapestry application to run under.

We need to tell Tapestry to ignore the rest api, so we need to add the following to our main AppModule:

public static void contributeIgnoredPathsFilter(
Configuration configuration){
// Tell tapestry to ignore this subpath,
// which will be handled by the rest application
configuration.add("/api/.*");
}

This will prevent tapestry from trying to service requests to the REST api.

The final piece of the puzzle is to hook up Resources to url templates, and have those Resources interact with Tapestry-managed services.  Typically, the approach would be to create singleton resources, and retrieve them through Tapestry's IOC via a strategy pattern, mapping url templates to singleton Tapestry-managed Resources or something similar.  The challenge here is that restlet's resources are necessarily one-off and restlet handles the instantiation.  Specifically, from the ServerResource javadoc:
Concurrency note: contrary to the Uniform class and its main Restlet subclass where a single instance can handle several calls concurrently, one instance of ServerResource is created for each call handled and accessed by only one thread at a time.

This could, I'm sure, be overridden, but this requires more plumbing code than I care to write.

To get our Resources talking to our Tapestry services, the restlet Resource will ask the restlet Application for services, hence the restlet Application needs access Tapestry's registry, accomplished using the following:
package firstSteps;  

import org.restlet.Application;
import org.restlet.Restlet;
import org.restlet.routing.Router;
import javax.servlet.ServletContext;
import org.apache.tapestry5.TapestryFilter;
import org.apache.tapestry5.ioc.Registry;

public class FirstStepsApplication extends Application {

private Registry registry;
/**
* Creates a root Restlet that will receive all incoming calls.
*/
@Override
public synchronized Restlet createRoot() {

if ( this.registry==null ) {
//This only works on RESTLET versions 2.0m6 or above
//http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2426537
ServletContext ctx = (ServletContext) getContext().getAttributes().get(
"org.restlet.ext.servlet.ServletContext" );
registry = (Registry)ctx.getAttribute(TapestryFilter.REGISTRY_CONTEXT_NAME);
if ( registry==null )
throw new RuntimeException(
"Failed to obtain a reference to Tapestry`s registry");
}
// Create a router Restlet that routes each call to a
// new instance of HelloWorldResource.
Router router = new Router(getContext());

// Defines only one route
router.attach("/hello", HelloWorldResource.class);

return router;
}

public T getService(Class service) {
return registry.getService(service);
}
}

Inside the createRoot method, we retrieve the registry from the ServletContext, and store it in an instance member.  We also add a method for service retrieval to be used by resources.  One could also add an additional method to retrieve Tapestry services by id, if needed.

Finally, we augment our resources:
package firstSteps;  

import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;
import com.myApp.service.MyService;

/**
* Resource which has only one representation.
*
*/
public class HelloWorldResource extends ServerResource {
private MyService myService;

public HelloWorldResource(){
myService = ((FirstStepsApplication)getApplication()).getService(
MyService.class);
if ( myService ==null )
throw new RuntimeException("Failed to obtain a reference to the MyService");
}

@Get
public String represent() {
return myService.getRepresentation();
}

}

That should be enough to get you rolling on Restlet and Tapestry.

UPDATE: I realized I missed a couple of things in this post.  Firstly, and most critically I missed triggering the cleanup of Tapestry resources which get stored in ThreadLocal.  This is addressed in a subsequent post.  Further, I had based some of the above code off of out of date doumentation, and have since corrected one or two method names.  Finally, I have corrected the maven dependencies, one is not required to deploy these artifacts oneself.

Tuesday, 1 December 2009

Spring, JRuby and Rails

I'm the process of porting our application.  Our objective is to increase the velocity of our development.  Our current framework, Tapestry5, has proven cumbersome and problematic (I dicussed my thoughts on Tapestry5 earlier, feel free to read through for details).  In furtherance of velocity, one should always consider the RAD frameworks, mainly RoR and Grails.

Given some of the API's we need to use we can't entirely get away from the Java world, but we have a large, highly talented pool of Ruby on Rails developers to draw on.  We also have a robust service layer built using packages like Hibernate, Quartz, and Spring Security, as well as domain-specific packages that are more mature in the Java world.

This presents a challenge; the talent pool screams RoR and the service layer constraints scream JVM (Grails).   From a purely technical standpoint, Grails seems the obvious choice, however, the ability to leverage an existing, vetted RoR resource pool is too appealing to a small tech company to resist.  Further, while I love Grails, it is a bit immature still.

I'm POC'ing a way to have my cake and eat it too (and avoid a data migration).  The approach is to hook a RoR web tier onto a Spring managed service layer, using the wonders of JRuby.  I want to be clear, I don't suggest this to anyone looking to build a new application.  Chris Nelson, who wrote a plugin used in this, says:
"If you're a Java programmer new to (J)Ruby and are thinking: "Awesome, I'll use Spring in all my Rails apps because Spring is awesome!" you need to hold up a second. Spring is awesome -- when you are developing Java applications. But in Ruby, dependency injection turns out to be unnecessary a whole lot of the time. This is because the Ruby language allows you to change things in a more straightforward way. And even if there were cases where you needed DI in Ruby there are probably better choices. I see the Spring plugin being useful where you have existing J2EE code wired together with Spring and want to front end it in JRuby on Rails."

I couldn't have said it better myself. So, bearing that in mind, on to the technical details.

First, you need to pull down the latest version of Goldspike, a JRuby on Rails integration package.  This can be done with the following command in the root of your rails app:

jruby -S script/plugin install svn://rubyforge.org/var/svn/
jruby-extras/trunk/rails-integration/plugins/goldspike


I'm going to assume you already know how to setup your Spring context, if you don't the Spring docs can help.  You'll need to make sure you compile a jar with dependencies.  To accomplish this, add the following inside the build/plugins of your pom.xml:

maven-assembly-plugin


jar-with-dependencies




make-assembly
package

single




You need to get the resulting jar into your Rails application's lib folder.

You'll need to install warbler:

jruby -S gem install warbler


Run warble and then copy the generated tmp/war/WEB-INF/web.xml into the Rails application's config folder.

You'll need to modify the web.xml to add the Spring context listener by adding the two following:


contextConfigLocation
classpath*:service-context.xml



org.springframework.web.context.
ContextLoaderListener



I have my spring context, called service-context.xml in my jar and am loading it from there.

Now all we need to do is call a spring service from a Rails controller, and it turns out thanks to Chris Nelson's work this uses no ugly glue code in the controller like one might expect:

class SpringTestController > ApplicationController
include Spring
spring_bean :testService

def show
@value = testService.value
end

end

In the above, I pull a spring bean id'ed as testService out of the Spring context and from that pull a value and store it in a rails variable.  I can then use that as a normal rails variable in .html.erb

At this point you should be good to go, but I ran into problems with getting JRuby on Rails to connect to mysql.  Turns out you need to specify the mysql gem in your config/warble.rb to ensure it's included in the war.  I just added this line to it:
config.gems += ["activerecord-jdbcmysql-adapter"]

After that, run warbler using the warble command in your rails package, and the war should be created in the rails application's root.  Move it over to your favorite web container and you should be set.