tag:blogger.com,1999:blog-337564802024-02-08T11:41:06.086-05:00Tembrel's TomeTim Peierls' blog: a matter of expediencyTembrelhttp://www.blogger.com/profile/12360655614437868477noreply@blogger.comBlogger40125tag:blogger.com,1999:blog-33756480.post-12879535541680223612012-03-16T20:29:00.000-04:002012-04-17T16:10:48.841-04:00Converting Forms in Restlet to POJOs with Jackson and GuavaPunchline first. This article presents code that you can use to convert HTML forms into POJOs, mapping property names in the natural way, with support for compound objects and arrays/lists. A long-winded set-up for that punchline follows.<br />
<br />
Many of my Restlet resources are designed to support both JSON and HTML representations with resource interfaces that look like this:<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">public interface PersonResource {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> @Get Person getPerson();</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">}</span><br />
<br />
where Person is a POJO that might look like this:<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">public class Person {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> public String getName() { ...}</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> public List<Address> getAddresses() { ... }</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> <i>... other bean stuff: setters, fields ...</i></span><br />
<span style="font-family: 'Courier New', Courier, monospace;">}</span><br />
<br />
and the implementation of the resource looks like this:<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">public class PersonServerResource </span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> extends ServerResource implements PersonResource {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> @Override public Person getPerson() {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> return <i>... construct Person from domain data ...</i></span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> }</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">}</span><br />
<br />
I register custom ConverterHelpers with the Restlet Engine. One of them knows how to use Jackson to convert Person into JSON, one knows how to obtain a Freemarker HTML template associated with the Person type and render it with the Person as its data model.<br />
<br />
It works like magic. When I use a browser to point to the resource, it returns the HTML generated with Freemarker. When I ask for it with, say, jQuery, requesting JSON, I get ... JSON. When I get a Restlet ClientResource proxy for PersonResource at that URI, I get a Person object back when I call getPerson() on the client side; the value returned by getPerson() on the server is serialized to JSON, sent over the wire, and deserialized back into a Person object.<br />
<br />
The only problem I had was for PUT and POST method handlers, because there was no automatic way to convert form data to my domain types. I had to create an additional method to handle forms as parameters:<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">public interface PeopleResource {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> @Post("json:json") Person addPerson(Person person);</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> @Post("form:html") Person addPersonForm(Form person);</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">}</span><br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">public class PeopleServerResource </span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> extends ServerResource implements PeopleResource {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> @Override public Person addPerson(Person person) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> ...</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> }</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> @Override Person addPersonForm(Form personForm) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> Person person = new Person();</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> // Extract values from personForm and set</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> // them to person.</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> return addPerson(person);</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> }</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">}</span><br />
<br />
I suffered this for a long time, and then I began to think that the application/www-form-urlencoded media type was, at least for simple types, not far from JSON. Could I translate form data to JSON and then use Jackson to deserialize that? Of course I could. In fact, it wasn't too hard to define some conventions whereby sequences (lists/arrays) and nested structures could be modeled. An encoded form for Person as produced by an HTML page might look like this, in part:<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">name=Tim&address.1.street=Main&address.1.city=Anytown...</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> ...&address.2.street=Elm&address.2.city=Smallton...</span><br />
<br />
and the corresponding JSON would be:<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">{</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> "name":"Tim",</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> "address":[{</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> "street":"Main",</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> "city":"Anytown",</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> ...</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> },{</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> "street":"Elm",</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> "city":"Smallton",</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> ...</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> },</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> ...</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> ]</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">}</span><br />
<br />
I wrote <a href="http://pastebin.com/7hKt4Caa">FormDeserializer</a> to do this. It takes a Jackson <a href="http://jackson.codehaus.org/1.9.4/javadoc/org/codehaus/jackson/map/ObjectMapper.html">ObjectMapper</a> to do the heavy lifting. Here's the Javadoc for the deserialization method:<br />
<br />
<br />
<pre style="background-color: white;">public <t> T <b>deserialize</b>(<a href="http://www.restlet.org/documentation/2.1/jse/api/org/restlet/data/Form.html?is-external=true" title="class or interface in org.restlet.data">Form</a> source, <a href="http://download.oracle.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</a><t> targetType)</t></t></pre>
<dl style="background-color: white;"><dd>Converts a Form to a Java object of the target type, using each <code>name=value</code> pair to set the corresponding property on the target object.</dd><dd><br />
Compound names, using period (.) as the delimiter, are treated as pseudo-dereferences (a la JavaScript or Groovy) to set properties of sub-objects, e.g., <code>a.b=c</code> for bean targets is treated like a call to <code>target.getA().setB(c)</code>.<br />
<br />
Numeric components of compound names are treated as indices into a sequence named by the preceding components, e.g., <code>a.1=c</code> is treated as <code>target.getA()[1] = c</code> (or <code>target.getA().set(1, c)</code>, if the "a" property of the target is a list rather than an array). Unless an element with index 0 is set, the indices are origin 1.<br />
<br />
Sequences are also created by names with multiple values, e.g., <code>a=x&a=y</code> is equivalent to <code>a.1=x&a.2=y</code>, with the value of the "a" property in the target being a sequence of two values.<br />
When a name appears both indexed and non-indexed, the last assignment wins: <code>a=x&a.1=a1&a.2=a2</code> will set the "a" property to a sequence of values <code>[a1, a2]</code>, but <code>a.1=a1&a.2=a2&a=x</code>will set the "a" property to <code>x</code>.<br />
<br />
If the top level consists only of integer indices, the subobjects will be interpreted as elements of a sequence (and T must be a List or List subtype instead).<br />
<br />
The values are deserialized using the Jackson ObjectMapper that was used to construct this FormDeserializer. Any type that can be deserialized from a string can be used. While it is possible for Jackson to deserialize object graphs that have internal references, it is not possible for the form values to refer outside of themselves.<br />
<br />
Runtime exceptions from Jackson conversion are propagated without <span style="background-color: white;">exception translation. This could be considered a bug.</span></dd><dd>
<dl>
<dt><b>Parameters:</b></dt>
<dd><code>source</code> - the Restlet Form object to be deserialized</dd><dd><code>targetType</code> - the type of the target object into which the form is to be deserialized.</dd>
<dt><b>Returns:</b></dt>
<dd>the deserialized object of the target type</dd></dl>
</dd></dl>
<br />
<br />
The converter class that uses this machinery is <a href="https://pastebin.com/GdXNNrwY">FormConverter</a>. It uses a marker annotation, <a href="https://pastebin.com/mV3y7x1a">FormDeserializable</a>, that signals when a class is suitable for deserialization from a form.<br />
<br />
The upshot is that I can now write:<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">public interface PeopleResource {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> @Post Person addPerson(Person person);</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">}</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">// And no need for additional method in implementation!</span><br />
<br />
<br />
Big reduction in the amount of boilerplate I have to write, and the code is easier to read.<br />
<br />
Here are the links to the code in one place:<br />
<br />
<ul>
<li><a href="https://pastebin.com/7hKt4Caa">FormDeserializer.java</a></li>
<li><a href="https://pastebin.com/GdXNNrwY">FormConverter.java</a></li>
<li><a href="https://pastebin.com/mV3y7x1a">FormDeserializable.java</a></li>
</ul>
<br />
I have @Inject tags on some constructors, but you can ignore them unless you want to use them for dependency injection.<br />
<br />
The implementation makes heavy use of Guava. If you don't or can't use Guava, then you'll have to roll your own machinery. (Good luck!)<br />
<br />Tembrelhttp://www.blogger.com/profile/12360655614437868477noreply@blogger.com6tag:blogger.com,1999:blog-33756480.post-69382851747573152852012-03-15T18:48:00.000-04:002014-11-28T19:22:36.113-05:00Restlet Guice extension considered ... unnecessaryI wrote some code back in 2008 to help inject my
<a href="http://www.restlet.org/" target="_blank">Restlet</a>
resources using Guice and then
<a href="http://tembrel.blogspot.com/2008/07/resource-dependency-injection-in.html">blogged about it</a>.
In 2009, the Restlet team added it to their "incubator" as a
potential Restlet extension.
(Calling it a Guice extension is a bit of a misnomer, since part of it is
independent of Guice and applies to any JSR-330-compliant DI framework.)
They've talked about promoting it out of the incubator as early as release 2.2. <i>Update: It's now <a href="http://restlet.com/learn/javadocs/2.2/jse/ext/org/restlet/ext/guice/package-summary.html" target="_blank">part of Restlet 2.2</a> and I've updated code references to point to the 2.2 branch.</i><br />
<br />
More recently, I argued (and Restlet's Jérôme Louvel seemed to accept the argument)
that Restlet needs a uniform way to create a non-standard Finder for all the Restlet
classes that have methods accepting a
<code>Class<? extends ServerResource></code> in place of a Restlet.
This would make the use of the Guice extension invisible when wiring up
the routing structure:
Currently you have to convert the resource type to a Restlet explicity,<br />
<pre> router.attach("/path/to/resource", finderFactory.finder(MyResource.class));
</pre>
<pre></pre>
and the extra support would let you write:<br />
<pre> router.attach("/path/to/resource", MyResource.class);
</pre>
<pre></pre>
It's all very gratifying, except I realized suddenly this week that for
most people who just want to inject their
<a href="http://restlet.com/learn/javadocs/2.2/jee/api/org/restlet/resource/ServerResource.html" target="_blank">ServerResource</a>
subclasses <strong>it's completely unnecessary</strong>.
It's much simpler to define
<a href="http://www.restlet.org/documentation/2.1/jee/api/org/restlet/resource/Resource.html#doInit()" target="_blank">doInit()</a>
to inject the resource's members, and then you can just use the second, simpler form above.
I wrote an abstract base class extending <code>ServerResource</code> that does just that:
<br />
<br />
<a href="https://github.com/restlet/restlet-framework-java/blob/2.2/modules/org.restlet.ext.guice/src/org/restlet/ext/guice/SelfInjectingServerResource.java" target="_blank">SelfInjectingServerResource.java</a><br />
<br />
Notice that <code>SelfInjectingServerResource</code> uses only the standard
<a href="http://docs.oracle.com/javaee/6/api/javax/inject/Inject.html" target="_blank">@Inject</a> annotation
and nothing specific to Guice.
In order to make it actually work with Guice, you need to tell Guice that you want self-injecting server resources.
The following class is a Guice Module that accomplishes this by requesting static injection of the
<code>SelfInjectingServerResource</code> class and providing an implementation of its nested
<code>MembersInjector</code> interface to perform the injection.
<br />
<br />
<a href="https://github.com/restlet/restlet-framework-java/blob/2.2/modules/org.restlet.ext.guice/src/org/restlet/ext/guice/SelfInjectingServerResourceModule.java" target="_blank">SelfInjectingServerResourceModule.java</a>
<br />
<br />
Install this module when creating the top-level injector,
make sure that the server resources you want injected inherit
from <code>SelfInjectingServerResource</code>, and
it just works.
Here's a JUnit test class that shows a trivial example of the idea in practice:
<br />
<br />
<a href="http://pastebin.com/WsVQse5X" target="_blank">SelfInjectingServerResourceModuleTest.java</a>
<br />
<br />
We'd like this technique to co-exist with other techniques that manage
resource injection differently (e.g., the current Guice extension),
without worrying about whether it's OK to extend
<code>SelfInjectingServerResource</code>,
so this code uses an atomic boolean to prevent multiple injections.
(AtomicBoolean is probably overkill, but it can't hurt to be safe.)
<br />
<br />
<i>[Deleted obsolete discussion of how to use prior to adoption as part of Restlet.]</i><br />
<br />
I said that the old Guice extension was unnecessary for <strong>most</strong>
users, but there are a few things the old code does that the new code doesn't do:
<br />
<ol>
<li>It does constructor injection, letting you have final fields with
injected values.
</li>
<li>It lets you create a Finder for a resource <em>interface</em>,
decoupling the target of the routing from the resource implementation.
</li>
<li>It lets you use
<a href="http://docs.oracle.com/javaee/6/api/javax/inject/Qualifier.html" target="_blank">qualifiers</a>
when looking up resource types, further decoupling the target of
an attachment from the implementation.
</li>
<li>It doesn't require inheritance from a common abstract base class.
</li>
<li>You don't have to remember to call <code>super.doInit()</code> when
you override <code>doInit</code>
</li>
</ol>
As it happens, I'm taking advantage of #2 in my current work.
(Note that there's no way to avoid the explicit <code>finder</code>
call in this case, even with added Restlet support, because the
Restlet signatures expect a <code>ServerResource</code> subclass.)
So I'm stuck with my mistake for the foreseeable future.
But no one else need be, now.<br />
<h4>
Update (2013 July 9)</h4>
<div>
I got rid of my dependency on #2 above, and I am now using the new approach exclusively, and I strongly recommend others do the same.<br />
<h4>
Further update (2014 Sep 1)</h4>
</div>
<div>
The Restlet Guice extension package docs discuss how to use each of three approaches, so you aren't forced to use the approach that I prefer.</div>
<br />Tembrelhttp://www.blogger.com/profile/12360655614437868477noreply@blogger.com19tag:blogger.com,1999:blog-33756480.post-41819055243095248432012-03-12T22:37:00.000-04:002012-03-20T09:16:56.263-04:00Further distributed CacheLoader developments<i>Updated 2012-Mar-13 and 2012-Mar-20; see notes at end.</i>
<p>
In a <a href="https://groups.google.com/d/msg/guava-discuss/6E61UxtwErw/Rm9KYmHCEW4J">discussion on the Guava mailing list</a> after <a href="http://tembrel.blogspot.com/2012/03/executorservice-returned-by.html">my previous post</a>, Charles Fry and Louis Wasserman had some great ideas that spurred me to rewrite the distributed <a href="http://docs.guava-libraries.googlecode.com/git-history/v11.0.2/javadoc/com/google/common/cache/CacheLoader.html">CacheLoader</a> functionality from scratch.
<p>
The first part is static factory methods to turn an <a href="http://docs.guava-libraries.googlecode.com/git-history/v11.0.2/javadoc/com/google/common/util/concurrent/AsyncFunction.html">AsyncFunction</a> into a CacheLoader:
<p>
<a href="http://pastebin.com/vLHxe12Q">CacheLoaders.java</a>
<p>
This is independent of any mention of Hazelcast; it works with any AsyncFunction. The Iterable-ness of the keys passed to loadAll is preserved all the way through, so asynchronous processing can start before the keys have been completely iterated. This could be handy if, for example, the keys themselves are being generated asynchronously.
<p>
The other piece is a class with methods to create an AsyncFunction out of a Hazelcast-based Executor:
<p>
<a href="https://pastebin.com/CYJsBAm1">HazelcastAsyncFunction.java</a>
<p>
Note that the public API of this class does not use any Hazelcast types.
<p>
The whole implementation is much cleaner and takes full advantage of existing Guava machinery. Here's what it looks like in use in my code:
<pre>
AsyncFunction<String, AccountInfo> asyncLookup =
HazelcastAsyncFunction
.from(syncLookup());
.onExecutor(hazelcastExecutor())
.withTaskKeyFunction(mapAccountToServer());
LoadingCache cache = CacheBuilder.newBuilder().build(
fromAsyncFunction(asyncLookup, 30L, TimeUnit.SECONDS));
...
// Later on, this call causes the account lookups to be
// magically distributed across the cluster:
Map accountNameToInfo = cache.get(accountNames);
</pre>
<p>
<i>Update 2012-Mar-13:</i> Louis Wasserman pointed out (in comments to this post) a race
in the implementation of CacheLoaders. I've updated the code to remove the race.
It doesn't use as many cool Guava tricks, but it's quite a bit simpler now.<p>
<p>
<i>Update 2012-Mar-20:</i> Unpacked the example to make it less frightening.Tembrelhttp://www.blogger.com/profile/12360655614437868477noreply@blogger.com7tag:blogger.com,1999:blog-33756480.post-23726286004216520612012-03-10T16:36:00.001-05:002012-03-13T10:59:35.995-04:00An invokeAll for Hazelcast ExecutorServices and a distributed CacheLoader[A <a href="http://tembrel.blogspot.com/2012/03/in-discussion-on-guava-mailing-list.html">more recent posting</a> describes a much cleaner implementation of the functionality described in this article.]
<p>
The ExecutorService returned by
<a href="http://www.hazelcast.com/docs/2.0/javadoc/com/hazelcast/core/HazelcastInstance.html#getExecutorService()">Hazelcast[Instance].getExecutorService()</a>
does not support invokeAll, but I needed this functionality for work I'm doing,
so I rolled my own restricted version:
<p>
<a href="https://pastebin.com/yUqEZxpu ">ExecUtil.java</a>
<p>
ExecUtil has several variants of invokeAll. The generic variants take these values:
<ul>
<li>an ExecutorService, which is must have been returned by a Hazelcast getExecutorService call;
<li>an Iterable of DistributedTasks<T>, where T is the common result type; and
<li>a FutureCallback<T>, which is a
<a href="http://code.google.com/p/guava-libraries/wiki/GuavaExplained">Guava </a>
interface for specifying what to do with
each returned result (and what to do, if anything, with exceptions thrown during task execution).
</ul>
The non-generic variants use the Void result type.
Generic and non-generic have two variants each, one that waits indefinitely and one that
waits a given amount of time for all the results to finish.
<p>
The use of Iterable<DistributedTask<T>> allows lazy provision of the tasks.
(Supporting this feature prevented a simpler implementation with just a CountDownLatch
initialized to the number of tasks, because we don't know the number of tasks in advance.)
<p>
The main awkwardness is that both the Callable<T> used to create the DistributedTask
and T itself must be Serializable, but this is, of course, a requirement imposed by DistributedTask.
<p>
<i>Update (2012-Mar-11):</i> I added a static method to ExecUtil that wraps an ExecutorService,
implementing <tt>invokeAll</tt> in terms of <tt>ExecUtil.invokeAll</tt> if the argument was created by Hazelcast.
Also added a <a href="https://pastebin.com/Y9GV7Fkw">ConcurrentFuction</a> that wraps an existing Function
for concurrent or distributed application.
<p>
<b>A concurrent Guava CacheLoader</b>
<p>
I then realized that this machinery could be used to provide a nice implementation of Guava's
<a href="http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/cache/CacheLoader.html">CacheLoader</a>,
used to build
<a href="http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/cache/LoadingCache.html">LoadingCache</a>
instances with
<a href="http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/cache/CacheBuilder.html">CacheBuilder</a>.
LoadingCache has a
<a href="http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/cache/LoadingCache.html#getAll(java.lang.Iterable)">getAll(Iterable<? extends K> keys)</a>
method that
returns a Map<K, V> from keys to cached values.
It calls
<a href="http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/cache/CacheLoader.html#loadAll(java.lang.Iterable)">CacheLoader.loadAll(Iterable<? extends K> keys)</a>
-- if it's implemented -- to load
the values in order to cache them.
If loadAll isn't implemented, it just loads the keys sequentially.
<p>
I wrote a CacheLoader implementation that can use ExecUtil.invokeAll to load the values
using DistributedTasks.
While I was at it, I made it so that if you don't have a
<a href="http://www.hazelcast.com">Hazelcast</a>-based ExecutorService,
you can use a normal ExecutorService to load the values concurrently (in the same JVM).
<p>
The result is ConcurrentCacheLoader:
<p>
<a href="https://pastebin.com/SpwH8k8i">ConcurrentCacheLoader.java</a>
<p>
It has a nested Builder class that allows you to specify:
<ul>
<li>the ExecutorService used (including shortcuts for default HazelcastInstance ExecutorServices),
<li>a time limit for loadAll,
<li>a function to map a cache key to a key object for the DistributedTask, and
<li>the actual function that maps cache keys to values.
</ul>
There's a minimal set of tests here:
<p>
<a href="https://pastebin.com/m5LMZCkd">ConcurrentCacheLoaderTest.java</a>
<p>
Here's how I'm using it:
<p>
<a href="https://pastebin.com/yBi307YU">Sample usage</a>
<p>
That's a ConcurrentCacheLoader.Builder used to build an argument to a CacheBuilder method.
<p>
The upshot is that my call to getAll runs on all the nodes in my Hazelcast cluster.
<p>
<b> Addendum: </b>
<p>
The motivation for all this was the desire to make dozens of calls to
<a href="http://www.jclouds.org">JClouds'</a>
<a href="http://demobox.github.com/jclouds-maven-site-1.4.0-rc.2/1.4.0-rc.2/jclouds-multi/apidocs/org/jclouds/blobstore/BlobStore.html#getBlob(java.lang.String, java.lang.String)">BlobStore.getBlob()</a>
in the space of a single HTTP request.
The standard for-loop approach was taking too long, and I suddenly realized I could be asking the Hazelcast cluster to do the work.Tembrelhttp://www.blogger.com/profile/12360655614437868477noreply@blogger.com0tag:blogger.com,1999:blog-33756480.post-76213836701715848272012-01-23T20:15:00.000-05:002012-03-13T10:59:53.811-04:00Deploying Restlet components in Elastic BeanstalkI spent some time finding a way to deploy a Restlet component in ElasticBeanstalk without giving up the option of deploying it as a standard Java executable for local development and testing. People have expressed interest in seeing the approach, but I don't have the time to create a full-fledged framework, so I've extracted the following template instead (links to code embedded in the prose). Just copy to your own environment, changing package and class names as you see fit, add your Guice Modules, define your Restlet applications and resources, and you should be able to run the resulting component both standalone and (by bundling everything in a WAR) via Elastic Beanstalk. I make no claims that this code is correct, that it is safe to use, or even that it will compile. You have to read it, compile it, and judge for yourself.<br />
<div>
<br /></div>
<div>
The code depends on Restlet, Guice, <a href="http://99soft.github.com/rocoto/">Rocoto</a>, Guava, and (minimally) SLF4J. I've included commented-out code that uses the Restlet-Guice extension, which is in incubator status in the Restlet codebase.<br />
<div>
<div>
<br /></div>
<div>
The <a href="http://pastebin.com/Ub0CPmi9">Main</a> class is a GuiceServletContextListener and it has a main method. When you run com.example.server.Main from the command line, the GuiceServletContextListener methods are ignored. When you deploy a WAR that contains the associated <a href="http://pastebin.com/G8WeAsiv">web.xml</a> file, the main routine is never called. You can inject the current <a href="http://pastebin.com/pDZSAWeS">DeploymentMode</a> into your classes if you want to change behavior depending whether you're running standalone or in Elastic Beanstalk (i.e., as a servlet).</div>
<div>
<br /></div>
<div>
The <a href="http://pastebin.com/P06CpGRe">MainComponent</a> class is where your Restlet component logic goes. Its lifecycle is managed by the <a href="http://pastebin.com/De1mpuXx">MainService</a> class, which is where you can manage other services with lifecycles. (If you use JClouds BlobStores, for example, you can ensure that a singleton BlobStoreContext is closed when the MainService is stopped. Another example: a LifecycleService for the Hazelcast data grid) There is some trickiness to handling shutdown in various cases; make sure you nest try-finally clauses so that every one of your services gets a chance to shut down even if the previous shutdown attempt throws an exception or error.</div>
<div>
<br /></div>
<div>
The <a href="http://pastebin.com/jEPCk7Gk">MainServletModule</a> and <a href="http://pastebin.com/DBzMpysk">MainServlet</a> classes deal with the details of embedding the component in a servlet (which is necessary in order to use Elastic Beanstalk).</div>
<div>
<br /></div>
<div>
<a href="http://pastebin.com/6dJaSEKG">AwsCredentialsModule</a> is an example of how you can inject AWS credentials from either of two sources: system properties defined on the command line (or via Ant invocation) and system properties defined by an Elastic Beanstalk configuration.<br />
<div>
<div>
<br /></div>
</div>
</div>
</div>
</div>
<div>
The flow of control when running standalone is that the main routine creates an instance of Main with the STANDALONE deployment mode, creates the injector, gets the singleton MainService, and starts it, which causes (in a different thread), the MainComponent to be started.</div>
<div>
<br /></div>
<div>
The flow of control when running as a servlet is that a default instance of Main is created (due to the web.xml directive) and gets the SERVLET deployment mode. Its contextInitialized call creates the injector, which injects the MainService and starts it, causing (in a different thread), the MainComponent to be started. </div>
<div>
<br />
Files:<br />
<ul>
<li><a href="http://pastebin.com/G8WeAsiv">web.xml</a> - web application descriptor</li>
<li><a href="http://pastebin.com/Ub0CPmi9">Main</a> - has main() routine for standalone; is context listener for servlet mode</li>
<li><a href="http://pastebin.com/P06CpGRe">MainComponent</a> - the Restlet component we want to be able to deploy in both modes</li>
<li><a href="http://pastebin.com/De1mpuXx">MainService</a> - manages lifecycle of MainComponent and (optionally) other services</li>
<li><a href="http://pastebin.com/jEPCk7Gk">MainServletModule</a> - included in module list in Main; configures Restlet-Servlet bridge</li>
<li><a href="http://pastebin.com/DBzMpysk">MainServlet</a> - injects MainComponent and returns it as the component it wraps</li>
<li><a href="http://pastebin.com/pDZSAWeS">DeploymentMode</a> - enum with two values: STANDALONE and SERVLET</li>
<li><a href="http://pastebin.com/6dJaSEKG">AwsCredentialsModule</a> - example of passing AWS credentials for binding with @Named</li>
</ul>
</div>
<div>
<br /></div>Tembrelhttp://www.blogger.com/profile/12360655614437868477noreply@blogger.com1tag:blogger.com,1999:blog-33756480.post-26000074617361849462011-12-06T10:44:00.001-05:002011-12-06T11:18:45.764-05:00Overriding common bindings with test bindings in JukitoThis post is about how to get common bindings for Jukito tests without having to write too much boilerplate. (Obviously not a general interest post!)<br />
<br />
A <a href="https://groups.google.com/d/topic/jukito/gyWwjLcTOFw/discussion">recent conversation on the Jukito newsgroup</a> discusses various proposals for reducing the amount of boilerplate involved in setting up common bindings for tests that have a common superclass. I've noticed that the underlying assumption to these proposals is that bindings in modules are inheritable in the same way that methods are, but that's not generally the case. You can override methods by defining a new version in a subclass, but to override the bindings in a module, you need to use <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">Modules.override</span>, which doesn't work via inheritance.<br />
<br />
I've written a template to illustrate how to override with test bindings; it uses Jukito 1.1 as is:<br />
<br />
<a href="http://pastebin.com/BLQnMEqx">http://pastebin.com/BLQnMEqx</a><br />
<br />
The key is to declare a static method in a common test superclass that returns a single module, which is easy to do with <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">Modules.combine</span>. Then in the concrete test class, use<br />
<br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> Modules.override(commonBindings).with(testBindings)</span><br />
<br />
This strikes what I think is the right balance between compactness and clarity: You have one place <b>in the concrete test class</b> that says what the basic bindings are (<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">commonBindings</span>) and what test bindings are being used to override for the purposes of this test (<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">testBindings</span>). There's no hunting around through the inheritance hierarchy for modules with the right characteristics.<br />
<br />
Because the <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">Modules.combine/override</span> approach is so simple, the case for adding special Jukito support (based on inheritance alone, annotations alone, or on a combination of inheritance and annotations) for auto-installing commonly-used modules becomes much weaker. Jukito is already pretty magical; it doesn't need to add mystery to its magic.Tembrelhttp://www.blogger.com/profile/12360655614437868477noreply@blogger.com0tag:blogger.com,1999:blog-33756480.post-88201807355279649112011-07-20T15:56:00.001-04:002011-07-20T16:05:15.280-04:00Java Standards AnnoyancesThe <a href="http://lanyrd.com/2011/oscon/sggkd/">Java Standards Annoyances session at OSCON 2011</a> looks like fun. I wish I could be there. <br />
<br />
If I <b>were</b> there, after first expressing congratulations mixed with condolences to Ben Evans and the <a href="http://londonjavacommunity.wordpress.com/about/">London Java Community</a> on the election to the EC, I'd probably say that the most important part of building standards is knowing when and what <b>not</b> to standardize. The PMO measures success quantitatively, in terms of numbers of JSR stage transitions, but the inevitable result has been that a lot of the JSRs that made it to final release are junk that should never have been accepted in the first place. The EC actually did one useful thing during my time as a member: It <b>rejected</b> the PFD of a (well-intentioned) JSR that was not ready for prime time. <br />
<br />
So talk of "streamlining" the process makes me nervous. I wouldn't want to make it easier to introduce garbage, and I don't trust the EC to be a responsible gatekeeper, nor do I trust the JCP as a whole to provide high-quality feedback during public review; there's too much noise, and it's too easy for a spec lead to ignore substantial criticism.<br />
<br />
There are good JSRs. Naturally I think the JSRs on whose EGs I have served are good ones, the most recent being JSR 334 ("Coin"). But I think the enthusiasm and energy of the community should be directed more at building great libraries and frameworks than at getting them accepted as standards.Tembrelhttp://www.blogger.com/profile/12360655614437868477noreply@blogger.com2tag:blogger.com,1999:blog-33756480.post-2968974306008823322010-12-07T11:38:00.000-05:002010-12-07T11:38:20.341-05:00Resigned from ECToday I resigned from the SE/EE Executive Committee of the Java Community Process. I lasted about a year before giving up hope that the ECs would ever do anything meaningful. <br />
<br />
The last straw for me was Oracle's failure to address the ambiguous licensing terms in JSRs 336 and 337 (the Java SE7/8 umbrella JSRs) before the EC had to vote on them. At first I abstained, but I was so dismayed by Oracle's silence that I changed my vote to No, joining the Apache Software Foundation and Google. <br />
<br />
Several of the other EC members expressed their own disappointment while voting Yes. I'm reasonably certain that the bulk of the Yes votes were due to contractual obligations rather than strongly-held principles. It's not that I'm shocked, shocked that votes can be bought, but it finally made it clear to me that my vote was worthless.<br />
<br />
Add to that Oracle's expressed intent to proceed with the SE7/8 JSRs whatever the outcome of the vote, and one can only conclude that the SE/EE EC is never going to be more than a rubber stamp for Oracle. (The belligerent tone with which this message was delivered does not come across in the public minutes, but it was loud and clear over my phone connection.)<br />
<br />
That's not to say that I'm against the technical aspects of the JSRs. In fact, I'm a member of the Expert Group for JSR 334 ("Project Coin") and I'm participating in discussions about some of the library-related work on JSR 335 ("Project Lambda"). I think these are both good projects that will ultimately be beneficial to the Java language and libraries.<br />
<br />
But here's a funny thing: To my own surprise, I'm coming to believe something heretical, that it actually is <b>not</b> all that crucial for Java to move forward, at least not to the constituency I felt that I represented on the EC, the tens of thousands of Java developers who don't work for a big company with an Oracle contract. <br />
<br />
The big boys want big apparent forward motion because it means more stuff to sell, more contracts and control. As a result, we are whipped to a frenzy with messages (both subliminal and explicit) that Java is falling behind, losing mind-share, being lapped by C#, anything to sell the idea that more is desperately needed, when in fact most folks could make do with a lot less.<br />
<br />
So while I think things like Project Coin and Project Lambda are worth working on, the Java ecosystem is already so amazingly rich that the absence of these features (and of all the other good things planned for SE7 and SE8) in practice doesn't get in the way of real progress for developers like me, who just want to put together maintainable, type-safe programs, taking advantage of field-tested readily-available libraries and frameworks.<br />
<br />
It's nice to be back in the real world, writing Java code. Here's a partial list of what I'm using, besides Java:<br />
<br />
Ant<br />
Freemarker<br />
Guava<br />
Guice<br />
Hazelcast<br />
iText<br />
Ivy<br />
Jackson<br />
JavaScript<br />
JClouds<br />
Joda Time<br />
jQuery<br />
JUnit<br />
Mockito<br />
Restlet<br />
Rhino<br />
SnakeYAML<br />
YUI CompressorTembrelhttp://www.blogger.com/profile/12360655614437868477noreply@blogger.com26tag:blogger.com,1999:blog-33756480.post-76652367539592221152010-10-26T09:00:00.002-04:002010-10-26T15:08:17.488-04:00Vote for Bob Lee and prove Doug Lea wrong!In explaining <a href="http://gee.cs.oswego.edu/dl/html/jcp22oct10.html">why he is not seeking another term</a> on the JCP SE/EE Executive Committee, Doug Lea encourages us to prove him wrong about the growing irrelevance of the Java Community Process.<br />
<br />
The best hope for proving Doug wrong lies with folks who have experience working on JSRs that weren't simply rubber stamps — and Bob Lee is the best of those folks. Bob is running for one of <a href="http://jcp.org/aboutJava/communityprocess/elections/2010.html">two open seats on the SE/EE EC</a> against Azul, Eclipse, Google, and three others, and (if you're a member of the JCP) I urge you to vote for him.<br />
<br />
Bob is running as an individual, which means that his votes will not be tied to the commercial and legal interests of a large corporation, but will instead reflect his personal expertise and judgment about the best interests of the Java community.<br />
<br />
There's no denying that the JCP has been moribund for too long, and that Oracle's ham-handed moves have made the prospect of a true revitalization far less likely than anyone expected a year or so ago. But it's worth a shot, and I don't know anyone better equipped to help make that shot than Bob Lee. (Except Doug Lea, of course, but that's water under the bridge.)Tembrelhttp://www.blogger.com/profile/12360655614437868477noreply@blogger.com0tag:blogger.com,1999:blog-33756480.post-79308003345414213092010-08-30T10:40:00.001-04:002010-08-30T10:40:28.426-04:00Doug Lea in New York Times articleDoug Lea, my colleague and co-author, is quoted in a <a href="http://www.nytimes.com/2010/08/30/technology/30oracle.html?hpw">New York Times article about the Oracle-Google patent infringement lawsuit</a>.Tembrelhttp://www.blogger.com/profile/12360655614437868477noreply@blogger.com0tag:blogger.com,1999:blog-33756480.post-90397668015713097942010-07-13T09:14:00.000-04:002010-07-13T09:14:12.207-04:00Moderating Chinese commentsI've been rejecting comments in Chinese whenever I can't be sure that the comment isn't spam, i.e., always. Google Translate renders them as unobjectionable but content-free, but so far none of them seem to have come from an actual person who read my post.<br />
<br />
If you can read my blog posts and you'd like to comment in Chinese, please include an English translation.Tembrelhttp://www.blogger.com/profile/12360655614437868477noreply@blogger.com0tag:blogger.com,1999:blog-33756480.post-6679620958091560302010-06-14T14:21:00.000-04:002010-06-14T14:21:23.404-04:00Google Collections is dead, long live Guava!Kevin Bourrillion wants to get the word out: <a href="http://smallwig.blogspot.com/2010/06/guava-release-05.html">Google Collections is dead, long live Guava</a>! Guava is a proper superset of Google Collections, so the passing of the latter is cause to rejoice, not mourn.<br />
<br />
I've only scratched the surface of Guava in my own work on Seat Yourself, but I can tell already that it makes large parts of our "common" code unnecessary. Being able to replace your own code with a well-tested open source library is a wonderful thing, like getting someone else to mow the lawn for free.<br />
<br />
In what feels to me like a dark time, as big companies privately negotiate the fate of Java and the JCP, Google's ongoing and generous investment in and championing of open Java-related technologies (Guava, GWT, GAE/J, Android, to name a few) is a welcome bright spot. Without their work ... well, I'd still be a Java developer, but I'd probably be looking for a way out.<br />
<br />
That I'm still enthusiastic about coding in Java, in spite of the murky politics, is largely due to my friends at Google, which should tell you something.Tembrelhttp://www.blogger.com/profile/12360655614437868477noreply@blogger.com2tag:blogger.com,1999:blog-33756480.post-31466480332099894312010-05-24T22:46:00.004-04:002011-03-03T13:53:18.950-05:00The Minstrel Boy<i>The Minstrel Boy</i>, a piece I wrote nearly 25 years ago during graduate work in Computer Science at Cornell (with a minor in Music Composition), received its first public performance yesterday at the <a href="http://www.uucsr.org/">Unitarian-Universalist Congregation at Shelter Rock</a>. I had shown the score to the music director there, <a href="http://www.stephenmichaelsmith.com/">Stephen Michael Smith</a>, who has a track record of fostering new works and composers, and to my surprise and pleasure, he very quickly arranged for a group of singers—Leslie Craigie, Farah Chandu, Leslie Pirchinello, Chee Shun Tan, and Brace Negron—to perform it as part of the regular Sunday service. (Pianists Evan Solomon and Akira Eguchi assisted during rehearsals.)<br />
<br />
The piece is a setting for SSATB (with solo sections) of Thomas Moore's <a href="http://en.wikipedia.org/wiki/The_Minstrel_Boy">poem of the same name</a>. It's normally sung to the tune of "The Moreen", and I used that melody heavily in my setting. The composition teacher under whose supervision I wrote it, <a href="http://www.stevenstucky.com/">Steven Stucky</a>, was not, I think, entirely on board with my wholesale appropriation of these existing materials—he might reasonably have felt that I should be producing my own music instead of rehashing others', at least on his watch—but I persisted anyway.<br />
<br />
This was the second world premiere of my work in as many months: In April, <a href="http://tracylynnconner.com/">TracyLynn Conner</a> performed a <a href="http://bit.ly/tlcsong">song I wrote for her</a>, as part of a American Cancer Society benefit concert. <br />
<br />
Both of these events were big thrills for me. If you don't count my music for theater, arrangements, orchestrations, or works for personal occasions, the last time I had a world premiere was in ... 1984.Tembrelhttp://www.blogger.com/profile/12360655614437868477noreply@blogger.com0tag:blogger.com,1999:blog-33756480.post-13553206914512494192009-11-27T10:25:00.030-05:002018-10-16T12:38:53.452-04:00Concurrently initialized singletons in GuiceWilliam Pietri <a href="http://groups.google.com/group/google-guice/browse_thread/thread/d56f336baae2113e?tvc=2">asked</a> whether it would be possible to take advantage of concurrency and Guice's knowledge of dependencies to provide interdependent (and expensive to create) singleton services in parallel.<br />
For example, say that service A depends on services B and C and that B and C don't know about each other (and so could be constructed concurrently). Obviously, you could explicitly construct B and C in separate tasks running in a thread pool, then construct A once B and C exist.<br />
<pre>class A {
A(B b, C c) { /* ... use b and c ... */ }
}
class B {
B() { /* ... takes a long time ... */ }
}
class C {
C() { /* ... takes a long time ... */ }
}
class Services {
A a; B b; C c;
void init() throws InterruptedException {
final CountDownLatch ready = new CountDownLatch(2);
Executor pool = Executors.newCachedThreadPool();
pool.execute(new Runnable() {
public void run() { b = new B(); ready.countDown(); }
})
pool.execute(new Runnable() {
public void run() { c = new C(); ready.countDown(); }
})
ready.await();
a = new A(b, c);
// Now publish a, b, and c safely -- not shown.
}
}
</pre>
But it's a pain to have to orchestrate this yourself. You have to know the dependencies intimately and write a lot of tricky code. If the dependencies change, the code has to be completely rethought. Wouldn't it be nice if Guice could do this for you automatically without giving up on the opportunities for concurrency? Well, it turns out that it can.<br />
The idea is to use a variant of singleton scope that runs the providers of all bindings for that scope in separate threads. Naturally some of these providers block in their own thread while their dependencies finish in other threads, but those services that <strong>can</strong> be constructed in parallel <strong>will</strong> be.<br />
Here's what the Guice version looks like:<br />
<pre>@ConcurrentSingleton
class A {
@Inject A(B b, C c) { /* ... use b and c ... */ }
}
@ConcurrentSingleton
class B {
@Inject B() { /* ... takes a long time ... */ }
}
@ConcurrentSingleton
class C {
@Inject C() { /* ... takes a long time ... */ }
}
</pre>
No special initialization code needed, just inject A, B, and C wherever they are needed. (Note that if you have circular dependencies, this probably won't work. So don't have circular dependencies.)<br />
<a href="https://github.com/Tembrel/Guice-Util/blob/master/src/main/java/net/peierls/guiceutil/ConcurrentSingleton.java">ConcurrentSingleton</a> is just a scope annotation. The actual scope implementation is <a href="https://github.com/Tembrel/Guice-Util/blob/master/src/main/java/net/peierls/guiceutil/ConcurrentSingletonScope.java">ConcurrentSingletonScope</a>. I have a fleshed-out version of the A, B, C example, <a href="https://github.com/Tembrel/Guice-Util/blob/master/src/test/java/net/peierls/guiceutil/ConcurrentSingletonExample.java">ConcurrentSingletonExample</a>, that is slightly different from the code above; it uses Providers for B and C so that A can do some work before getting B and C in the constructor.<br />
You aren't forced to do all the expensive work in the constructor. You could also inject a start method with injected parameters to provide needed dependencies.<br />
In the same thread that provoked the ConcurrentSingleton response, Jesse Wilson suggested the use of the experimental lifecycle facility in Guava. This could prove useful in the current context if, for example, you have singleton services that take a while to stop and could benefit from being stopped in parallel.<br />
<br />
<h4>
<span class="Apple-style-span" style="font-size: 15px; font-weight: bold;">Update 2009-11-30</span></h4>
I added a call to <code>pool.shutdown()</code> in the scope implementation to make sure the pool threads don't prevent the JVM from exiting. It might not be necessary, but I don't think it hurts.<br />
<br />
<h4>
<span class="Apple-style-span" style="font-size: 15px; font-weight: bold;">Update 2010-7-3</span></h4>
Added explicit notice that the sources are in the public domain.<br />
<br />
<h4>
Update 2018-10-16</h4>
<div>
Added a <a href="https://github.com/Tembrel/Guice-Util">GitHub repository</a> with the concurrent singleton code and other utilities, as the old links to code weren't working any more. Now using MIT open source license.</div>
Tembrelhttp://www.blogger.com/profile/12360655614437868477noreply@blogger.com7tag:blogger.com,1999:blog-33756480.post-41656179864977111822009-10-26T00:49:00.005-04:002010-10-26T15:05:53.433-04:00The Emperor's New ClothesI posted Ray Mason's video of <span style="font-style:italic;">The Emperor's New Clothes</span>, a Theatre Three Children's Theatre production of a show that Jeff Sanzel and I wrote together, on my Facebook profile and my YouTube channel, broken up into scene length segments.<br />
<br />
See the links section in the right-hand column -- you'll want to look at the YouTube version unless you're my Facebook friend, and even then you might prefer to watch the YouTube playlist, something for which there is no analogue in Facebook ... is there?<br />
<br />
I haven't bothered to post to MySpace this time around.Tembrelhttp://www.blogger.com/profile/12360655614437868477noreply@blogger.com0tag:blogger.com,1999:blog-33756480.post-37182447269666813732009-09-11T10:10:00.004-04:002009-09-11T10:39:21.959-04:00Joshua Rosenblum's siteJosh Rosenblum has a website worth checking out:<br /><br /><a href="http://rosenblummusic.com/" target="_blank">http://rosenblummusic.com</a><br /><br />The site was designed and implemented by Josh's 13-year-old son, Julian.<br /><br />And don't be afraid to go ahead and buy those albums! :-)Tembrelhttp://www.blogger.com/profile/12360655614437868477noreply@blogger.com0tag:blogger.com,1999:blog-33756480.post-12270479672799336612009-05-12T16:55:00.006-04:002013-01-18T11:59:46.624-05:00Dependency injection in Restlet 2.0 with GuiceI'm very excited about Restlet 2.0, which is in testing now and scheduled for release at the end of 2009. Among other things, the newly refactored Resource API encourages more readable code through the use of a small number of annotations. Here's a very simple server-side resource:<br />
<pre>
public class DefaultResource extends ServerResource {
@Get public String represent() {
return "Default resource, try /hello/resource or /hello/handler";
}
}</pre>
<br />
ServerResource has a no-arg constructor, so you don't need to pass Context, Request, and Response objects to super().<br />
<br />
Nice as this is, I still want to inject my resources using Guice, so I've updated the Restlet-Guice classes from my <a href="http://tembrel.blogspot.com/2008/07/resource-dependency-injection-in.html"> previous post</a> to support both the new ServerResources and the old Handlers. It incorporates the enhancement mentioned in the updates: You can override methods to use different providers for Application, Context, Request, and Response, although for most purposes the default providers should suffice.<br />
<br />
<h2>
Update 2009-Dec-11</h2>
<br />
I've been working on a Guice extension for Restlet as an <a href="https://github.com/restlet/restlet-framework-java/tree/master/incubator/org.restlet.ext.guice">incubator project</a> that uses the ideas in this posting. My goal is to make this extension independent of Guice at the interface level, so that people can provide implementations for different DI frameworks, of which Guice is only the first.Tembrelhttp://www.blogger.com/profile/12360655614437868477noreply@blogger.com2tag:blogger.com,1999:blog-33756480.post-49869637464681475602008-12-15T15:52:00.013-05:002008-12-16T09:23:36.125-05:00Musical numbers from my showsAfter years of vague promises to cast members to provide a record of the shows that Jeff Sanzel and I have written together for <a href="http://www.theatrethree.com">Theatre Three</a> children's theatre productions, I finally got up my courage to edit together the tapes I'd made into more or less coherent individual musical numbers. I've been posting them to <a href="http://www.youtube.com/user/TembrelPie">YouTube</a>, <a href="http://www.facebook.com/video/?id=728160483">Facebook</a>, and <a href="http://vids.myspace.com/index.cfm?fuseaction=vids.channel&channelid=55340888">MySpace</a> as I finish them.<br /><br />The tapes were made by setting up a camera (or two) before each performance, pointing it towards the stage, turning it on, and leaving it there unattended. In some cases I also recorded a separate audio track with a decent stereo mic. There are several problems with this approach:<ul><li> The camera is stationary, so any zooming or panning has to be applied after the fact. This makes for blurry closeups. </li><br /><li> The autofocus is often confused by stage lighting changes. </li><br /><li> Each performance is slightly different, so synching lip movements can be tricky. I got it wrong in several instances. </li><br /><li> The mic in the camera is not as good as the separate stereo mic, and the sound quality varies depending on where the camera is placed. So only <i>The Fairy Princess</i> has good sound.</li><br /></ul>But I hope the end results are entertaining, if only for the performers who took part in the productions.<br /><br />Eventually I'd like to create a video or sequence of videos covering an entire show, for watching in a YouTube playlist, for example. I made studio recordings of <i>Hansel and Gretel</i> and <i>The Fairy Princess</i> (and I hope to do so for <i>The Elves and the Shoemaker</i>), so it is possible that I could use that material for the soundtrack.Tembrelhttp://www.blogger.com/profile/12360655614437868477noreply@blogger.com0tag:blogger.com,1999:blog-33756480.post-89725025612167660562008-09-25T09:34:00.004-04:002008-12-15T15:50:34.271-05:00New CD: "Colloquy"I am once more proud to announce the release of a CD that I produced: <span style="font-style:italic;"><a href="http://www.amazon.com/Colloquy/dp/B001ECM024">Colloquy</a></span>, an album of music by <a href="http://www.garywilliamfriedman.com/">Gary William Friedman</a>. And once more, I am several weeks late in my announcement. Maybe I planned it that way. Yeah, that's it.<br /><br />I wrote the liner notes for this album, and I won't repeat them here, so go get a copy and read them. Or don't read them, just listen to the music -- I don't mind.<br /><br />Update:<br /><br />There's also a <a href="http://www.youtube.com/watch?v=LWC0GifFopQ">video</a> about the making of one of the pieces on the album.Tembrelhttp://www.blogger.com/profile/12360655614437868477noreply@blogger.com0tag:blogger.com,1999:blog-33756480.post-18921425343614249462008-07-24T17:06:00.006-04:002008-12-15T15:51:29.349-05:00New CD: "Before Love Has Gone"I'm proud to announce the release, one month ago, of a new album from <a href="http://www.stevieholland.com">Stevie Holland</a>, <span style="font-style:italic;">Before Love Has Gone</span>, that I co-produced with <a href="http://www.toddbarkan.com/">Todd Barkan</a> and <a href="http://garywilliamfriedman.com/">Gary William Friedman</a>. (The actual release date was June 24, but I kept forgetting to blog about it and decided to wait out the full month.)<br /><br />Go get it and listen to it. The whole album is great, but if you're really stingy and can only spring for one tune, I recommend "Lazy Afternoon". It's phenomenal.<br /><br />Update:<br /><br />There's also an <a href="http://www.youtube.com/watch?v=AyZE3xZ2pH8">EPK</a> for the album.Tembrelhttp://www.blogger.com/profile/12360655614437868477noreply@blogger.com0tag:blogger.com,1999:blog-33756480.post-81816417572436148562008-07-24T15:56:00.015-04:002013-02-19T20:07:49.144-05:00Resource dependency injection in Restlet via Guice(See <a href="http://tembrel.blogspot.com/2009/05/dependency-injection-in-restlet-20-with.html">a more recent posting on this subject</a>.)<br />
<br />
I have a body of code that already benefits from Guice dependency injection, and I want to migrate it from a servlet-based architecture to Restlet without losing those benefits. I've had some success, and I figured I'd report on it.<br />
<br />
I <span style="font-weight: bold;">don't</span> mean that I wanted to use Guice to wire up an object graph of Restlets (Components, VirtualHosts, Applications, etc.). It's straightforward enough to use the builder-like API of Restlet, and such code is nicely confined in a few places where it doesn't bother the meat of the application, its resources.<br />
<br />
What I <span style="font-weight: bold;">do</span> want is to have those resources created by Guice, so that they can be constructed with dependencies injected into them. With the Finder approach, resource constructors get a Context, a Request, and a Response, but that's it. I suppose I could find a way to stash an Injector in one of these so that resources could look up the dependencies they need, but I wanted something more direct. I came up with the following scheme, which seems to be working pretty well:<br />
<br />
I use a custom Finder that knows how to look up a Handler/Resource by class or Guice key -- instances of these custom Finders are provided by a FinderFactory:<br />
<pre>
public interface FinderFactory {
Finder finderFor(Key<? extends Handler> key);
Finder finderFor(Class<? extends Handler> cls);
}</pre>
<br />
The class RestletGuice has static methods named createInjector that parallel those of the Guice class. The difference is that it adds bindings for Context, Request, Response, and FinderFactory. In my Guiced version of the FirstStepsApplication from restlet.org, the following lines create an Injector with some bindings and then look up the FinderFactory that will produce Finders that will be able to make use of those bindings. (These bindings are not necessarily good practice; they just demonstrate the technique.)<br />
<pre>
Injector injector = RestletGuice.createInjector(new AbstractModule() {
public void configure() {
bind(Handler.class)
.annotatedWith(HelloWorld.class)
.to(HelloWorldResource.class);
bindConstant()
.annotatedWith(named(HelloWorldResource.HELLO_MSG))
.to("Hello, Restlet-Guice!");
}
});
FinderFactory factory = injector.getInstance(FinderFactory.class);</pre>
<br />
HelloWorldResource is slightly changed. It has a private final field, msg, that is used to generate the text representation. The msg field is initialized via an injected value.<br />
<pre>
@Inject public HelloWorldResource(@Named(HELLO_MSG) String msg,
Request request,
Response response,
Context context) {
super(context, request, response);
this.msg = msg;
getVariants().add(new Variant(MediaType.TEXT_PLAIN));
}
static final String HELLO_MSG = "hello.message";</pre>
<br />
This all comes together in the Application class when attaching a Finder for the default routing.<br />
<pre>
Finder finder = factory.finderFor(Key.get(Handler.class, HelloWorld.class));
Router router = new Router(getContext());
router.attachDefault(finder);
return router;</pre>
<br />
I read this as "Route any request for this application to whatever resource is bound to @HelloWorld-annotated Handlers, injecting that resource's dependencies," which was exactly what I wanted.<br />
<br />
For those who don't want to have to call a special RestletGuice method, there is a public class FinderFactoryModule extending AbstractModule that can be used with <code>Guice.createInjector(...)</code> to get the same effect. <br />
<br />
FinderFactoryModule also implements FinderFactory, so you can construct an instance in your Restlet wiring code and use it right away. You can then use the FinderFactoryModule to create an injector explicitly.<br />
<br />
As a special convenience, if you don't use a FinderFactoryModule to create an injector, one will be created implicitly the first time one of its Finders is used to find a target Handler/Resource. This encourages a style where each Application gets its own implicit Injector by creating a local FinderFactoryModule and using it to create Finders.<br />
<br />
That's basically it. It works with plain Guice 1.0 and Restlet 1.1 (since it uses Handler as the base type for all Resources). I haven't had time to package it nicely, but you can follow the links below for the actual code.<br />
<br />
Sources (links are out of date, use <a href="https://github.com/restlet/restlet-framework-java/tree/master/incubator/org.restlet.ext.guice/src/org/restlet/ext/guice">this</a> instead):<br />
<a href="http://dev.priorartisans.com/tim/restlet-guice/src/main/java/net/peierls/restlet/util/FinderFactory.java">FinderFactory.java</a><br />
<a href="http://dev.priorartisans.com/tim/restlet-guice/src/main/java/net/peierls/restlet/util/FinderFactoryModule.java">FinderFactoryModule.java</a><br />
<a href="http://dev.priorartisans.com/tim/restlet-guice/src/main/java/net/peierls/restlet/util/RestletGuice.java">RestletGuice.java</a><br />
<br />
Example (links are out of date, use <a href="https://github.com/restlet/restlet-framework-java/tree/master/incubator/org.restlet.ext.guice/src/org/restlet/ext/guice/example">this</a> instead):<br />
<a href="http://dev.priorartisans.com/tim/restlet-guice/src/main/java/net/peierls/restlet/example/FirstStepsApplication.java">FirstStepsApplication.java</a><br />
<a href="http://dev.priorartisans.com/tim/restlet-guice/src/main/java/net/peierls/restlet/example/HelloWorld.java">HelloWorld.java</a><br />
<a href="http://dev.priorartisans.com/tim/restlet-guice/src/main/java/net/peierls/restlet/example/HelloWorldResource.java">HelloWorldResource.java</a><br />
<a href="http://dev.priorartisans.com/tim/restlet-guice/src/main/java/net/peierls/restlet/example/Main.java">Main.java</a><br />
<br />
<h3>
Update (August 2008) </h3>
<br />
Chris Lee discovered that Context.getCurrent() doesn't work reliably as of 1.1m5; the workaround is to use Application.getCurrent().getContext(). A more comprehensive fix, that I hope to post soon, would involve letting subclasses of FinderFactoryModule override the methods that create the Providers for Request, Response, and Context.<br />
<br />
<h3>
Update (2009-Feb-3) </h3>
<br />
Leigh Klotz has a <a href="http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=1098001">workaround</a> for using Guice Finders with WadlApplication. And I still haven't had time to package any of this more nicely. (<em>Feb 7:</em> Jérôme Louvel took Leigh's suggestion and checked it in on the Restlet trunk.)Tembrelhttp://www.blogger.com/profile/12360655614437868477noreply@blogger.com6tag:blogger.com,1999:blog-33756480.post-29736127893831045072008-04-22T10:12:00.005-04:002009-02-23T08:59:13.133-05:00Concert at Kosciuszko HallI attended a lovely concert at Kosciuszko Hall in Manhattan on Monday night. Cellist <a href="http://www.geocities.com/mairid/">Mairi Dorman-Phaneuf</a> and composer-pianist <a href="http://www.einsteinsdreamsthemusical.com/cast.html">Joshua Rosenblum</a> performed works by Schumann, Brahms, de Falla, Prokofieff, Rosenblum, Bolling, and others, assisted by soprano Joanne Lessner, bassist Bill Ellison, drummer Bruce Doctor, and special guest Julia Murney. <br /><br />Mairi's particular interest (she referred to it as an obsession) is in performing songs with the cello taking the voice part, and she made a compelling case for her obsession in the songs of Schumann, Brahms, and de Falla. I particularly liked Brahms' <span style="font-style:italic;">Wie Melodien</span>.<br /><br />The concert included the world premiere of Josh Rosenblum's setting for soprano, cello, piano, and contrabass of T. S. Eliot's poem, <span style="font-style:italic;">The Love Song of J. Alfred Prufrock</span>. I liked it a lot, and I hope to make a recording of it soon so it can be shared with others.<br /><br />I was very pleased to see that the three CDs on sale in the lobby were all produced (or co-produced) by me! Not surprising, of course, because they all feature Josh Rosenblum's music:<ul><li><a href="http://www.amazon.com/Sundry-Notes-Joshua-Rosenblum/dp/B0011NVBIU/">Sundry Notes</a></li><li><a href="http://www.amazon.com/Bush-Bad-Joshua-Rosenblum/dp/B000DN5XY2/">Bush is Bad</a></li><li><a href="http://www.amazon.com/Fermats-Tango-Joanne-Sydney-Lessner/dp/B00005QZMA/">Fermat's Last Tango</a></li></ul>There is another Peierls-produced Rosenblum album, <a href="http://www.amazon.com/Impetuosities-Joshua-Rosenblum-Christopher-Thompson/dp/B00008YJED/">Impetuosities</a>, but it wasn't on sale at the concert.<br /><br />Another world premiere of Josh's music can be heard at the upcoming <a href="http://www.joyce.org/calendar_detail.php?event=157&theater=2">performance</a> of the dance company, <a href="http://chasebrockexperience.com">The Chase Brock Experience</a>. Chase Brock commissioned a ballet from Josh, and I produced a recording of the piece for use during the performance. It's called ... are you ready? ... <span style="font-style:italic;">Cut to the Chase</span>.Tembrelhttp://www.blogger.com/profile/12360655614437868477noreply@blogger.com0tag:blogger.com,1999:blog-33756480.post-68375871644348483932008-02-02T16:51:00.001-05:002008-05-16T09:22:52.135-04:00Magic in the CityIf you're looking to hire a magician for a New York City area children's birthday party, <a href="http://jazzothegreat.com">Jazzo the Great</a> comes highly recommended: <br /><a href="http://jazzothegreat.com" target="_blank"><br /> <img src="http://jazzothegreat.com/magic/riffle.gif" alt="Card Riffle" /><br /></a>Tembrelhttp://www.blogger.com/profile/12360655614437868477noreply@blogger.com0tag:blogger.com,1999:blog-33756480.post-81207079883831995772008-01-16T15:05:00.001-05:002008-05-16T09:09:21.373-04:00The Red and the GreenSo <a href="http://www.sciam.com/podcast/episode.cfm?id=7A81E74F-E554-39DF-62E0C6F540A3CDF8">wine tastes better with an expensive price tag</a>. And I thought I just had good taste.Tembrelhttp://www.blogger.com/profile/12360655614437868477noreply@blogger.com0tag:blogger.com,1999:blog-33756480.post-59151228133866399652007-11-05T15:18:00.000-05:002009-10-12T08:40:29.496-04:00Concurrency issues in Restlet<a href="http://restlet.tigris.org/issues/show_bug.cgi?id=368">Issue #368</a> in the Restlet issue tracker was originally focused on the Guard class. Since then, I've taken a look at the rest of the <code>org.restlet</code> package and found that the fields of most classes are <a href="http://tembrel.blogspot.com/2007/10/basic-rules-for-threadsafe-classes.html">accessed without appropriate synchronization</a>. <span style="font-style:italic;">[Update 2008-Feb-6: All of these have been fixed as of Restlet 1.1 M1.]</span><br /><br />Most of these problems would disappear if the fields could be final, but that would mean taking away setter-injectability.<br /><br />There is hope, however: Methods that are used only for setter injection (and not, for example, used to reconfigure an instance dynamically), should be documented as setter-injection-only, meaning they must not be called after the instance has been (safely) published. Fields set by such methods get their values before publication, and those values never change; such fields are <span style="font-style:italic;">effectively immutable</span>. I don't know of any standard documentation conventions for this, but the important thing is to decide for each non-final, non-volatile field whether it is truly mutable or only setter-injected before publication.<br /><br />I have a long-standing gripe about the Spring documentation that it doesn't state, at least not in terms that I recognize, under what conditions beans are safely published. The vanilla use cases (standard ApplicationContext implementations) are almost certainly fine, but if you have any doubts about whether your dependency injection framework can guarantee safe publication, then you should either guard your setter-injected fields with a lock or make them volatile. I have a personal preference for using volatile in this case, but most of my <span style="font-style:italic;"><a href="http://www.jcip.net">Java Concurrency in Practice</a></span> co-authors have the opposite preference.<br /><br />Even if you're fairly confident about your DI framework's guarantees, it is never wrong to guard field access or make a field volatile, only potentially wasteful. For a framework like Restlet that should be usable in any DI context, I think it would be prudent to assume the worst of that context.<br /><br />But is setter injection really necessary? Most of the injected fields are of distinct types, so constructor injection in Spring would be straightforward. Getting rid of setter injection entirely would allow most, if not all, fields to be final, which would greatly reduce the risk of concurrency problems in Restlet.Tembrelhttp://www.blogger.com/profile/12360655614437868477noreply@blogger.com4