Archive for the ‘Uncategorized’ Category

Clojure environment state of the union, install speedrun screencast

December 19, 2012 6 comments

I’ve been speaking to a colleague about simplifying my workstation setup, minimizing the number of OS instance configurations floating around in my head. I have multiple computers at home and at work, and I need to be able to minimize the time it takes to be productive from point-zero. I thought this would be a great time to try and make a speedrun of getting up and running with a clojure environment, starting with a freshly downloaded ubuntu ISO image and using it as a VM.

All-in-all, it takes 24 minutes, about 8 minutes is waiting for stuff to download. I could practice and get it down to ~15, but this should be a good order-of-magnitude estimate of what it takes. Minutes 16-24 are hassling with emacs, elpa, auto-complete, and order-of-installation issues.

This also serves as a demonstration of what can go wrong when even a full-time clojure developer has to recreate a working environment, and what kind of knowledge of workarounds may be needed. I had some problems with emacs that I can’t explain, I just found a workaround through trial-and-error and my minimal experience :-). Having remembered what it was like to not know these secrets, I know that this hassle can expand into days of digging.

As a community, we should aim to minimize this sort of hassle for beginners. I know there have been ill-fated efforts to do so, with out-of-date documentation and half-usable but well intended tools, and I don’t have an answer for that, but here’s a data point.

Categories: Clojure, Uncategorized Tags:

A StringTemplate Spring MVC integration that doesn’t suck

July 20, 2011 4 comments

I’ve been experimenting with all this web stuff that’s going on these days, and my platform of choice is java.  I have some experience with Spring MVC (2.0 sucks but 3 is ok), but I didn’t feel like using JSP.  StringTemplate is a template engine invented by the ANTLR folks to do code generation, and is a general purpose, fast template engine.  It enforces clean separation of code from presentation.  StringTemplate 4 is pretty recent, and that’s what I’m using for this experimentation.  Anyway, here’s the shiny bits:

Firstly, set up your build environment.  I use maven to pull in dependencies.  Add this to your pom.xml:

1 <dependency>
2 	<groupId>org.antlr</groupId>
3 	<artifactId>stringtemplate</artifactId>
4 	<version>4.0.2</version>
5 </dependency>

Now you need to inform Spring that you’ll be using StringTemplate instead of the standard JSTLView.  Here’s where things get hairy.  Spring uses the InternalResourceViewResolver class to resolve views, and it will instantiate a class that you configure it to use.  What this means is, spring calls new(), and this class doesn’t participate in bean lifecycle processes.  If you want dependency injection, this is one case where you’re hosed unless you find a more elaborate way to do things.  This is as far as I’ve cared to take it.

1 <bean id="viewresolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
2 	<property name="viewClass" value="com.garytrakhman.common.BeanView" />
3 	<property name="prefix" value="/templates/" />
4 	<property name="suffix" value=".st" />
5 	<property name="requestContextAttribute" value="rc" />
6 </bean>

The magic happens in my BeanView class. This class is configured to access a factory and get the real bean view resolver. This enables me to unit-test and configure the actual logic using dependency injection.

 1 public class BeanView extends InternalResourceView {
 2 	private IViewResolver viewResolver;
 3 	{
 4 		Config config = ConfigFactory.getInstance();
 5 		viewResolver = config.getViewResolver();
 6 	}
 8 	@SuppressWarnings({ "rawtypes", "unchecked" })
 9 	@Override
10 	protected void renderMergedOutputModel(Map model,
11 			HttpServletRequest request, HttpServletResponse response)
12 			throws Exception {
13 		viewResolver.renderMergedOutputModel(model, request, response,
14 				getBeanName());
15 	}
16 }

Now the delegation logic has been set-up. We now need the actual StringTemplate loading logic. Spring uses reflection to instantiate the InternalResourceView class, then we override that single method to take control of view rendering.

 1 import;
 2 import java.util.Map;
 4 import javax.servlet.http.HttpServletRequest;
 5 import javax.servlet.http.HttpServletResponse;
 7 import org.springframework.beans.factory.annotation.Autowired;
 8 import org.springframework.stereotype.Component;
 9 import org.stringtemplate.v4.AutoIndentWriter;
10 import org.stringtemplate.v4.ST;
11 import org.stringtemplate.v4.STGroup;
12 import org.stringtemplate.v4.STGroupFile;
14 import com.garytrakhman.common.IViewResolver;
15 import com.garytrakhman.common.impl.URLMap;
16 import;
18 @Component
19 public class STViewResolver implements IViewResolver {
21 	// assume thread safe modifying access to templates, adaptors, attributes,
22 	// imports, and renderer access on STGroup/ST (they are synchronized).
23 	//
25 	@Autowired
26 	private URLMap urlMap;
28 	private Map<String, STGroup> groups = Maps.newConcurrentMap();;
30 	@Override
31 	public void renderMergedOutputModel(Map<String, ?> model,
32 			HttpServletRequest request,
33 			HttpServletResponse response, String viewName) throws Exception {
35 		ST template = getView(viewName);
37 		template.add("model", model);
38 		template.add("url", urlMap.get());
40 		PrintWriter writer = response.getWriter();
42 		template.write(new AutoIndentWriter(writer));
44 		writer.flush();
45 		writer.close();
46 	}
48 	private STGroup getGroup(String key) {
49 		STGroup out = groups.get(key);
50 		if (out != null) {
51 			return out;
52 		}
54 		out = new STGroupFile("templates/" + key + ".stg");
55 		out.delimiterStartChar = '%';
56 		out.delimiterStopChar = '%';
57 		groups.put(key, out);
58 		return out;
59 	}
61 	private ST getView(String viewName) {
62 		STGroup group = getGroup(viewName);
63 		ST template = group.getInstanceOf(viewName);
64 		return template;
65 	}
66 }

What’s happening here is pretty simple.  The object sets up a concurrent cache of the template groups (each file is a group).  They are organized in my src/main/resources/templates directory, and it uses the view name as the key to load the file.  Once a template is requested a second time, it loads straight from the cache.  Since these templates are compiled and fast, it makes for some very speedy behavior.  In my testing with JMeter, I was able to perform ~9k requests/sec with 100 threads hammering on a simple view on a core i5 2600K, running on jetty.  I also set-up some default keys/values for the templates, mainly the model and url keys.  You could easily use the request objects or anything else.  StringTemplate provides flexibility by accessing your beans with reflection or letting you implement adapters to map template data to objects.  So far, I’m very happy with it.

Categories: Uncategorized