<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-33756480</id><updated>2012-01-27T10:56:59.403-05:00</updated><category term='Personal'/><category term='DWR'/><category term='Music and Theatre'/><category term='Java'/><category term='Restlet'/><category term='Concurrency'/><category term='Guice'/><title type='text'>Tembrel's Tome</title><subtitle type='html'>Tim Peierls' blog: a matter of expediency</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>37</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-33756480.post-7621383670171584827</id><published>2012-01-23T20:15:00.000-05:00</published><updated>2012-01-27T10:56:59.411-05:00</updated><title type='text'>Deploying Restlet components in Elastic Beanstalk</title><content type='html'>I 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.&amp;nbsp;People have expressed interest in seeing the approach, but&amp;nbsp;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.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The code depends on Restlet, Guice, and&amp;nbsp;&lt;a href="http://99soft.github.com/rocoto/"&gt;Rocoto&lt;/a&gt;. I've included commented-out code that uses the Restlet-Guice extension, which is in incubator status in the Restlet codebase.&lt;br /&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The &lt;a href="http://pastebin.com/Ub0CPmi9"&gt;Main&lt;/a&gt; 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 &lt;a href="http://pastebin.com/G8WeAsiv"&gt;web.xml&lt;/a&gt; file, the main routine is never called. You can inject the current &lt;a href="http://pastebin.com/pDZSAWeS"&gt;DeploymentMode&lt;/a&gt; into your classes if you want to change behavior depending whether you're running standalone or in Elastic Beanstalk (i.e., as a servlet).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The &lt;a href="http://pastebin.com/P06CpGRe"&gt;MainComponent&lt;/a&gt; class is where your Restlet component logic goes. Its lifecycle is managed by the &lt;a href="http://pastebin.com/De1mpuXx"&gt;MainService&lt;/a&gt; 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&amp;nbsp;LifecycleService for the&amp;nbsp;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.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The &lt;a href="http://pastebin.com/jEPCk7Gk"&gt;MainServletModule&lt;/a&gt; and &lt;a href="http://pastebin.com/DBzMpysk"&gt;MainServlet&lt;/a&gt; classes deal with the details of embedding the component in a servlet (which is necessary in order to use Elastic Beanstalk).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://pastebin.com/6dJaSEKG"&gt;AwsCredentialsModule&lt;/a&gt; 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.&lt;br /&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;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.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;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.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;Files:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://pastebin.com/G8WeAsiv"&gt;web.xml&lt;/a&gt;&amp;nbsp;- web application descriptor&lt;/li&gt;&lt;li&gt;&lt;a href="http://pastebin.com/Ub0CPmi9"&gt;Main&lt;/a&gt;&amp;nbsp;- has main() routine for standalone; is context listener for servlet mode&lt;/li&gt;&lt;li&gt;&lt;a href="http://pastebin.com/P06CpGRe"&gt;MainComponent&lt;/a&gt;&amp;nbsp;- the Restlet component we want to be able to deploy in both modes&lt;/li&gt;&lt;li&gt;&lt;a href="http://pastebin.com/De1mpuXx"&gt;MainService&lt;/a&gt;&amp;nbsp;- manages lifecycle of MainComponent and (optionally) other services&lt;/li&gt;&lt;li&gt;&lt;a href="http://pastebin.com/jEPCk7Gk"&gt;MainServletModule&lt;/a&gt;&amp;nbsp;- included in module list in Main; configures Restlet-Servlet bridge&lt;/li&gt;&lt;li&gt;&lt;a href="http://pastebin.com/DBzMpysk"&gt;MainServlet&lt;/a&gt;&amp;nbsp;- injects MainComponent and returns it as the component it wraps&lt;/li&gt;&lt;li&gt;&lt;a href="http://pastebin.com/pDZSAWeS"&gt;DeploymentMode&lt;/a&gt;&amp;nbsp;- enum with two values: STANDALONE and SERVLET&lt;/li&gt;&lt;li&gt;&lt;a href="http://pastebin.com/6dJaSEKG"&gt;AwsCredentialsModule&lt;/a&gt;&amp;nbsp;- example of passing AWS credentials for binding with @Named&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-7621383670171584827?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/7621383670171584827/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=7621383670171584827' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/7621383670171584827'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/7621383670171584827'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2012/01/deploying-restlet-components-in-elastic.html' title='Deploying Restlet components in Elastic Beanstalk'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33756480.post-2600007461736184946</id><published>2011-12-06T10:44:00.001-05:00</published><updated>2011-12-06T11:18:45.764-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Guice'/><title type='text'>Overriding common bindings with test bindings in Jukito</title><content type='html'>This post is about how to get common bindings for Jukito tests without having to write too much boilerplate. (Obviously not a general interest post!)&lt;br /&gt;&lt;br /&gt;A &lt;a href="https://groups.google.com/d/topic/jukito/gyWwjLcTOFw/discussion"&gt;recent conversation on the Jukito newsgroup&lt;/a&gt; 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 &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Modules.override&lt;/span&gt;, which doesn't work via inheritance.&lt;br /&gt;&lt;br /&gt;I've written a template&amp;nbsp;to illustrate how to override with test bindings; it uses Jukito 1.1 as is:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://pastebin.com/BLQnMEqx"&gt;http://pastebin.com/BLQnMEqx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The key is to declare a static method in a common test superclass that returns a single module, which is easy to do with &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Modules.combine&lt;/span&gt;. Then in the concrete test class, use&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; Modules.override(commonBindings).with(testBindings)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This strikes what I think is the right balance between compactness and clarity: You have one place &lt;b&gt;in the concrete test class&lt;/b&gt; that says what the basic bindings are (&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;commonBindings&lt;/span&gt;) and what test bindings are being used to override for the purposes of this test (&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;testBindings&lt;/span&gt;). There's no hunting around through the inheritance hierarchy for modules with the right characteristics.&lt;br /&gt;&lt;br /&gt;Because the &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Modules.combine/override&lt;/span&gt; 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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-2600007461736184946?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/2600007461736184946/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=2600007461736184946' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/2600007461736184946'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/2600007461736184946'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2011/12/overriding-common-bindings-with-test.html' title='Overriding common bindings with test bindings in Jukito'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33756480.post-8820180735527964911</id><published>2011-07-20T15:56:00.001-04:00</published><updated>2011-07-20T16:05:15.280-04:00</updated><title type='text'>Java Standards Annoyances</title><content type='html'>The &lt;a href="http://lanyrd.com/2011/oscon/sggkd/"&gt;Java Standards Annoyances session at OSCON 2011&lt;/a&gt; looks like fun. I wish I could be there. &lt;br /&gt;&lt;br /&gt;If I &lt;b&gt;were&lt;/b&gt; there, after first expressing congratulations mixed with condolences to Ben Evans and the &lt;a href="http://londonjavacommunity.wordpress.com/about/"&gt;London Java Community&lt;/a&gt; on the election to the EC, I'd probably say that the most important part of building standards is knowing when and what &lt;b&gt;not&lt;/b&gt; 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 &lt;b&gt;rejected&lt;/b&gt; the PFD of a (well-intentioned) JSR that was not ready for prime time. &lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-8820180735527964911?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/8820180735527964911/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=8820180735527964911' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/8820180735527964911'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/8820180735527964911'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2011/07/java-standards-annoyances.html' title='Java Standards Annoyances'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33756480.post-296897430600882332</id><published>2010-12-07T11:38:00.000-05:00</published><updated>2010-12-07T11:38:20.341-05:00</updated><title type='text'>Resigned from EC</title><content type='html'>Today 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. &lt;br /&gt;&lt;br /&gt;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. &lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.)&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;But here's a funny thing: To my own surprise, I'm coming to believe something heretical, that it actually is &lt;b&gt;not&lt;/b&gt; 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. &lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;br /&gt;Ant&lt;br /&gt;Freemarker&lt;br /&gt;Guava&lt;br /&gt;Guice&lt;br /&gt;Hazelcast&lt;br /&gt;iText&lt;br /&gt;Ivy&lt;br /&gt;Jackson&lt;br /&gt;JavaScript&lt;br /&gt;JClouds&lt;br /&gt;Joda Time&lt;br /&gt;jQuery&lt;br /&gt;JUnit&lt;br /&gt;Mockito&lt;br /&gt;Restlet&lt;br /&gt;Rhino&lt;br /&gt;SnakeYAML&lt;br /&gt;YUI Compressor&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-296897430600882332?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/296897430600882332/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=296897430600882332' title='26 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/296897430600882332'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/296897430600882332'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2010/12/resigned-from-ec.html' title='Resigned from EC'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>26</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33756480.post-7665236753959222115</id><published>2010-10-26T09:00:00.002-04:00</published><updated>2010-10-26T15:08:17.488-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Vote for Bob Lee and prove Doug Lea wrong!</title><content type='html'>In explaining &lt;a href="http://gee.cs.oswego.edu/dl/html/jcp22oct10.html"&gt;why he is not seeking another term&lt;/a&gt; on the JCP SE/EE Executive Committee, Doug Lea encourages us to prove him wrong about the growing irrelevance of the Java Community Process.&lt;br /&gt;&lt;br /&gt;The best hope for proving Doug wrong lies with folks who have experience working on JSRs that weren't simply rubber stamps &amp;mdash; and Bob Lee is the best of those folks. Bob is running for one of &lt;a href="http://jcp.org/aboutJava/communityprocess/elections/2010.html"&gt;two open seats on the SE/EE EC&lt;/a&gt; against Azul, Eclipse, Google, and three others, and (if you're a member of the JCP) I urge you to vote for him.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-7665236753959222115?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/7665236753959222115/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=7665236753959222115' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/7665236753959222115'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/7665236753959222115'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2010/10/vote-for-bob-lee-and-prove-doug-lea.html' title='Vote for Bob Lee and prove Doug Lea wrong!'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33756480.post-7930800334541421309</id><published>2010-08-30T10:40:00.001-04:00</published><updated>2010-08-30T10:40:28.426-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Doug Lea in New York Times article</title><content type='html'>Doug Lea, my colleague and co-author, is quoted in a &lt;a href="http://www.nytimes.com/2010/08/30/technology/30oracle.html?hpw"&gt;New York Times article about the Oracle-Google patent infringement lawsuit&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-7930800334541421309?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/7930800334541421309/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=7930800334541421309' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/7930800334541421309'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/7930800334541421309'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2010/08/doug-lea-in-new-york-times-article.html' title='Doug Lea in New York Times article'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33756480.post-9039766801571309794</id><published>2010-07-13T09:14:00.000-04:00</published><updated>2010-07-13T09:14:12.207-04:00</updated><title type='text'>Moderating Chinese comments</title><content type='html'>I'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.&lt;br /&gt;&lt;br /&gt;If you can read my blog posts and you'd like to comment in Chinese, please include an English translation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-9039766801571309794?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/9039766801571309794/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=9039766801571309794' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/9039766801571309794'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/9039766801571309794'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2010/07/moderating-chinese-comments.html' title='Moderating Chinese comments'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33756480.post-667962095809156030</id><published>2010-06-14T14:21:00.000-04:00</published><updated>2010-06-14T14:21:23.404-04:00</updated><title type='text'>Google Collections is dead, long live Guava!</title><content type='html'>Kevin Bourrillion wants to get the word out: &lt;a href="http://smallwig.blogspot.com/2010/06/guava-release-05.html"&gt;Google Collections is dead, long live Guava&lt;/a&gt;! Guava is a proper superset of Google Collections, so the passing of the latter is cause to rejoice, not mourn.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-667962095809156030?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/667962095809156030/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=667962095809156030' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/667962095809156030'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/667962095809156030'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2010/06/google-collections-is-dead-long-live.html' title='Google Collections is dead, long live Guava!'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33756480.post-3146648033209989431</id><published>2010-05-24T22:46:00.004-04:00</published><updated>2011-03-03T13:53:18.950-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Personal'/><category scheme='http://www.blogger.com/atom/ns#' term='Music and Theatre'/><title type='text'>The Minstrel Boy</title><content type='html'>&lt;i&gt;The Minstrel Boy&lt;/i&gt;, 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 &lt;a href="http://www.uucsr.org/"&gt;Unitarian-Universalist Congregation at Shelter Rock&lt;/a&gt;. I had shown the score to the music director there, &lt;a href="http://www.stephenmichaelsmith.com/"&gt;Stephen Michael Smith&lt;/a&gt;, 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&amp;#8212;Leslie Craigie, Farah Chandu, Leslie Pirchinello, Chee Shun Tan, and Brace Negron&amp;#8212;to perform it as part of the regular Sunday service. (Pianists Evan Solomon and Akira Eguchi assisted during rehearsals.)&lt;br /&gt;&lt;br /&gt;The piece is a setting for SSATB (with solo sections) of Thomas Moore's &lt;a href="http://en.wikipedia.org/wiki/The_Minstrel_Boy"&gt;poem of the same name&lt;/a&gt;. 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, &lt;a href="http://www.stevenstucky.com/"&gt;Steven Stucky&lt;/a&gt;, was not, I think, entirely on board with my wholesale appropriation of these existing materials&amp;#8212;he might reasonably have felt that I should be producing my own music instead of rehashing others', at least on his watch&amp;#8212;but I persisted anyway.&lt;br /&gt;&lt;br /&gt;This was the second world premiere of my work in as many months: In April, &lt;a href="http://tracylynnconner.com/"&gt;TracyLynn Conner&lt;/a&gt; performed a &lt;a href="http://bit.ly/tlcsong"&gt;song I wrote for her&lt;/a&gt;, as part of a American Cancer Society benefit concert. &lt;br /&gt;&lt;br /&gt;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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-3146648033209989431?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/3146648033209989431/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=3146648033209989431' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/3146648033209989431'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/3146648033209989431'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2010/05/minstrel-boy.html' title='The Minstrel Boy'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33756480.post-1355320691451249419</id><published>2009-11-27T10:25:00.030-05:00</published><updated>2010-08-03T09:44:03.291-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Concurrency'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Guice'/><title type='text'>Concurrently initialized singletons in Guice</title><content type='html'>&lt;p&gt;William Pietri &lt;a href="http://groups.google.com/group/google-guice/browse_thread/thread/d56f336baae2113e?tvc=2"&gt;asked&lt;/a&gt; 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.&lt;/p&gt;&lt;p&gt;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.&lt;/p&gt;&lt;pre&gt;class A {&lt;br /&gt;    A(B b, C c) { /* ... use b and c ... */ }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class B {&lt;br /&gt;    B() { /* ... takes a long time ... */ }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class C {&lt;br /&gt;    C() { /* ... takes a long time ... */ }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class Services {&lt;br /&gt;    A a; B b; C c;&lt;br /&gt;    void init() throws InterruptedException {&lt;br /&gt;        final CountDownLatch ready = new CountDownLatch(2);&lt;br /&gt;        Executor pool = Executors.newCachedThreadPool();&lt;br /&gt;        pool.execute(new Runnable() {&lt;br /&gt;            public void run() { b = new B(); ready.countDown(); }&lt;br /&gt;        })&lt;br /&gt;        pool.execute(new Runnable() {&lt;br /&gt;            public void run() { c = new C(); ready.countDown(); }&lt;br /&gt;        })&lt;br /&gt;        ready.await();&lt;br /&gt;        a = new A(b, c);&lt;br /&gt;        // Now publish a, b, and c safely -- not shown.&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;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.&lt;/p&gt;&lt;p&gt;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 &lt;strong&gt;can&lt;/strong&gt; be constructed in parallel &lt;strong&gt;will&lt;/strong&gt; be.&lt;/p&gt;&lt;p&gt;Here's what the Guice version looks like:&lt;/p&gt;&lt;pre&gt;@ConcurrentSingleton&lt;br /&gt;class A {&lt;br /&gt;    @Inject A(B b, C c) { /* ... use b and c ... */ }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@ConcurrentSingleton&lt;br /&gt;class B {&lt;br /&gt;    @Inject B() { /* ... takes a long time ... */ }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@ConcurrentSingleton&lt;br /&gt;class C {&lt;br /&gt;    @Inject C() { /* ... takes a long time ... */ }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;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.)&lt;/p&gt;&lt;p&gt;&lt;a href="http://pastie.org/1072727"&gt;ConcurrentSingleton&lt;/a&gt; is just a scope annotation. The actual scope implementation is &lt;a href="http://pastie.org/1072729"&gt;ConcurrentSingletonScope&lt;/a&gt;. I have a fleshed-out version of the A, B, C example, &lt;a href="http://pastie.org/1072730"&gt;ConcurrentSingletonExample&lt;/a&gt;, 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.&lt;/p&gt;&lt;p&gt;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.&lt;/p&gt;&lt;p&gt;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.&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="font-size: 15px; font-weight: bold;"&gt;Update 2009-11-30&lt;/span&gt;&lt;br /&gt;I added a call to &lt;code&gt;pool.shutdown()&lt;/code&gt; 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.&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="font-size: 15px; font-weight: bold;"&gt;Update 2010-7-3&lt;/span&gt;&lt;br /&gt;Added explicit notice that the sources are in the public domain.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-1355320691451249419?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/1355320691451249419/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=1355320691451249419' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/1355320691451249419'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/1355320691451249419'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2009/11/concurrently-initialized-singletons-in.html' title='Concurrently initialized singletons in Guice'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33756480.post-4165617986497711182</id><published>2009-10-26T00:49:00.005-04:00</published><updated>2010-10-26T15:05:53.433-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Personal'/><category scheme='http://www.blogger.com/atom/ns#' term='Music and Theatre'/><title type='text'>The Emperor's New Clothes</title><content type='html'>I posted Ray Mason's video of &lt;span style="font-style:italic;"&gt;The Emperor's New Clothes&lt;/span&gt;, 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.&lt;br /&gt;&lt;br /&gt;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?&lt;br /&gt;&lt;br /&gt;I haven't bothered to post to MySpace this time around.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-4165617986497711182?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/4165617986497711182/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=4165617986497711182' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/4165617986497711182'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/4165617986497711182'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2009/10/emperors-new-clothes.html' title='The Emperor&apos;s New Clothes'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33756480.post-3718244726966681373</id><published>2009-09-11T10:10:00.004-04:00</published><updated>2009-09-11T10:39:21.959-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Personal'/><category scheme='http://www.blogger.com/atom/ns#' term='Music and Theatre'/><title type='text'>Joshua Rosenblum's site</title><content type='html'>Josh Rosenblum has a website worth checking out:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://rosenblummusic.com/" target="_blank"&gt;http://rosenblummusic.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The site was designed and implemented by Josh's 13-year-old son, Julian.&lt;br /&gt;&lt;br /&gt;And don't be afraid to go ahead and buy those albums! :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-3718244726966681373?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/3718244726966681373/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=3718244726966681373' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/3718244726966681373'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/3718244726966681373'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2009/09/joshua-rosenblums-site.html' title='Joshua Rosenblum&apos;s site'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33756480.post-1227047967279933661</id><published>2009-05-12T16:55:00.006-04:00</published><updated>2009-12-11T11:20:08.426-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Guice'/><category scheme='http://www.blogger.com/atom/ns#' term='Restlet'/><title type='text'>Dependency injection in Restlet 2.0 with Guice</title><content type='html'>I'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:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class DefaultResource extends ServerResource {&lt;br /&gt;    @Get public String represent() {&lt;br /&gt;        return "Default resource, try /hello/resource or /hello/handler";&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;ServerResource has a no-arg constructor, so you don't need to pass Context, Request, and Response objects to super().&lt;br /&gt;&lt;br /&gt;Nice as this is, I still want to inject my resources using Guice, so I've updated the Restlet-Guice classes from my &lt;a href="http://tembrel.blogspot.com/2008/07/resource-dependency-injection-in.html"&gt; previous post&lt;/a&gt; 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.&lt;br /&gt;&lt;br /&gt;Still no fancy packaging, just a &lt;a href="http://dev.priorartisans.com/tim/restlet-guice/restlet-2.0-guice-src.zip"&gt;zip archive of source&lt;/a&gt; that you can compile against Restlet 2.0 and Guice 1.0 (it would probably work with Guice 2, but I haven't tried).&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Update 2009-Dec-11&lt;/h2&gt;&lt;br /&gt;I've been working on a Guice extension for Restlet as an &lt;a href="http://wiki.restlet.org/developers/257-restlet/284-restlet.html"&gt;incubator project&lt;/a&gt; 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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-1227047967279933661?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/1227047967279933661/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=1227047967279933661' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/1227047967279933661'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/1227047967279933661'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2009/05/dependency-injection-in-restlet-20-with.html' title='Dependency injection in Restlet 2.0 with Guice'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33756480.post-4986963746468147560</id><published>2008-12-15T15:52:00.013-05:00</published><updated>2008-12-16T09:23:36.125-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Music and Theatre'/><title type='text'>Musical numbers from my shows</title><content type='html'>After years of vague promises to cast members to provide a record of the shows that Jeff Sanzel and I have written together for &lt;a href="http://www.theatrethree.com"&gt;Theatre Three&lt;/a&gt; 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 &lt;a href="http://www.youtube.com/user/TembrelPie"&gt;YouTube&lt;/a&gt;, &lt;a href="http://www.facebook.com/video/?id=728160483"&gt;Facebook&lt;/a&gt;, and &lt;a href="http://vids.myspace.com/index.cfm?fuseaction=vids.channel&amp;channelid=55340888"&gt;MySpace&lt;/a&gt; as I finish them.&lt;br /&gt;&lt;br /&gt;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:&lt;ul&gt;&lt;li&gt; The camera is stationary, so any zooming or panning has to be applied after the fact. This makes for blurry closeups. &lt;/li&gt;&lt;br /&gt;&lt;li&gt; The autofocus is often confused by stage lighting changes. &lt;/li&gt;&lt;br /&gt;&lt;li&gt; Each performance is slightly different, so synching lip movements can be tricky. I got it wrong in several instances. &lt;/li&gt;&lt;br /&gt;&lt;li&gt; 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 &lt;i&gt;The Fairy Princess&lt;/i&gt; has good sound.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;But I hope the end results are entertaining, if only for the performers who took part in the productions.&lt;br /&gt;&lt;br /&gt;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 &lt;i&gt;Hansel and Gretel&lt;/i&gt; and &lt;i&gt;The Fairy Princess&lt;/i&gt; (and I hope to do so for &lt;i&gt;The Elves and the Shoemaker&lt;/i&gt;), so it is possible that I could use that material for the soundtrack.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-4986963746468147560?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/4986963746468147560/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=4986963746468147560' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/4986963746468147560'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/4986963746468147560'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2008/12/musical-numbers-from-my-shows.html' title='Musical numbers from my shows'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33756480.post-8972502561216766056</id><published>2008-09-25T09:34:00.004-04:00</published><updated>2008-12-15T15:50:34.271-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Music and Theatre'/><title type='text'>New CD: "Colloquy"</title><content type='html'>I am once more proud to announce the release of a CD that I produced: &lt;span style="font-style:italic;"&gt;&lt;a href="http://www.amazon.com/Colloquy/dp/B001ECM024"&gt;Colloquy&lt;/a&gt;&lt;/span&gt;, an album of music by &lt;a href="http://www.garywilliamfriedman.com/"&gt;Gary William Friedman&lt;/a&gt;. And once more, I am several weeks late in my announcement. Maybe I planned it that way. Yeah, that's it.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Update:&lt;br /&gt;&lt;br /&gt;There's also a &lt;a href="http://www.youtube.com/watch?v=LWC0GifFopQ"&gt;video&lt;/a&gt; about the making of one of the pieces on the album.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-8972502561216766056?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/8972502561216766056/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=8972502561216766056' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/8972502561216766056'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/8972502561216766056'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2008/09/new-cd-colloquy.html' title='New CD: &quot;Colloquy&quot;'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33756480.post-1892142534361424946</id><published>2008-07-24T17:06:00.006-04:00</published><updated>2008-12-15T15:51:29.349-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Music and Theatre'/><title type='text'>New CD: "Before Love Has Gone"</title><content type='html'>I'm proud to announce the release, one month ago, of a new album from &lt;a href="http://www.stevieholland.com"&gt;Stevie Holland&lt;/a&gt;, &lt;span style="font-style:italic;"&gt;Before Love Has Gone&lt;/span&gt;, that I co-produced with &lt;a href="http://www.toddbarkan.com/"&gt;Todd Barkan&lt;/a&gt; and &lt;a href="http://garywilliamfriedman.com/"&gt;Gary William Friedman&lt;/a&gt;. (The actual release date was June 24, but I kept forgetting to blog about it and decided to wait out the full month.)&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Update:&lt;br /&gt;&lt;br /&gt;There's also an &lt;a href="http://www.youtube.com/watch?v=AyZE3xZ2pH8"&gt;EPK&lt;/a&gt; for the album.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-1892142534361424946?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/1892142534361424946/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=1892142534361424946' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/1892142534361424946'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/1892142534361424946'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2008/07/new-cd-before-love-has-gone.html' title='New CD: &quot;Before Love Has Gone&quot;'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33756480.post-8181641757243614856</id><published>2008-07-24T15:56:00.015-04:00</published><updated>2009-10-12T08:40:29.496-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Guice'/><category scheme='http://www.blogger.com/atom/ns#' term='Restlet'/><title type='text'>Resource dependency injection in Restlet via Guice</title><content type='html'>(See &lt;a href="http://tembrel.blogspot.com/2009/05/dependency-injection-in-restlet-20-with.html"&gt;a more recent posting on this subject&lt;/a&gt;.)&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;I &lt;span style="font-weight:bold;"&gt;don't&lt;/span&gt; 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.&lt;br /&gt;&lt;br /&gt;What I &lt;span style="font-weight:bold;"&gt;do&lt;/span&gt; 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:&lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public interface FinderFactory {&lt;br /&gt;    Finder finderFor(Key&amp;lt;? extends Handler&amp;gt; key);&lt;br /&gt;    Finder finderFor(Class&amp;lt;? extends Handler&amp;gt; cls);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;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.)&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    Injector injector = RestletGuice.createInjector(new AbstractModule() {&lt;br /&gt;        public void configure() {&lt;br /&gt;            bind(Handler.class)&lt;br /&gt;                .annotatedWith(HelloWorld.class)&lt;br /&gt;                .to(HelloWorldResource.class);&lt;br /&gt;            bindConstant()&lt;br /&gt;                .annotatedWith(named(HelloWorldResource.HELLO_MSG))&lt;br /&gt;                .to("Hello, Restlet-Guice!");&lt;br /&gt;        }&lt;br /&gt;    });&lt;br /&gt;    FinderFactory factory = injector.getInstance(FinderFactory.class);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    @Inject public HelloWorldResource(@Named(HELLO_MSG) String msg,&lt;br /&gt;                                      Request request,&lt;br /&gt;                                      Response response,&lt;br /&gt;                                      Context context) {&lt;br /&gt;        super(context, request, response);&lt;br /&gt;        this.msg = msg;&lt;br /&gt;        getVariants().add(new Variant(MediaType.TEXT_PLAIN));&lt;br /&gt;    }&lt;br /&gt;    static final String HELLO_MSG = "hello.message";&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This all comes together in the Application class when attaching a Finder for the default routing.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    Finder finder = factory.finderFor(Key.get(Handler.class, HelloWorld.class));&lt;br /&gt;    Router router = new Router(getContext());&lt;br /&gt;    router.attachDefault(finder);&lt;br /&gt;    return router;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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 &lt;code&gt;Guice.createInjector(...)&lt;/code&gt; to get the same effect. &lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Sources:&lt;br /&gt;&lt;a href="http://dev.priorartisans.com/tim/restlet-guice/src/main/java/net/peierls/restlet/util/FinderFactory.java"&gt;FinderFactory.java&lt;/a&gt;&lt;br /&gt;&lt;a href="http://dev.priorartisans.com/tim/restlet-guice/src/main/java/net/peierls/restlet/util/FinderFactoryModule.java"&gt;FinderFactoryModule.java&lt;/a&gt;&lt;br /&gt;&lt;a href="http://dev.priorartisans.com/tim/restlet-guice/src/main/java/net/peierls/restlet/util/RestletGuice.java"&gt;RestletGuice.java&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Example:&lt;br /&gt;&lt;a href="http://dev.priorartisans.com/tim/restlet-guice/src/main/java/net/peierls/restlet/example/FirstStepsApplication.java"&gt;FirstStepsApplication.java&lt;/a&gt;&lt;br /&gt;&lt;a href="http://dev.priorartisans.com/tim/restlet-guice/src/main/java/net/peierls/restlet/example/HelloWorld.java"&gt;HelloWorld.java&lt;/a&gt;&lt;br /&gt;&lt;a href="http://dev.priorartisans.com/tim/restlet-guice/src/main/java/net/peierls/restlet/example/HelloWorldResource.java"&gt;HelloWorldResource.java&lt;/a&gt;&lt;br /&gt;&lt;a href="http://dev.priorartisans.com/tim/restlet-guice/src/main/java/net/peierls/restlet/example/Main.java"&gt;Main.java&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt; Update (August 2008) &lt;/h3&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt; Update (2009-Feb-3) &lt;/h3&gt;&lt;br /&gt;Leigh Klotz has a &lt;a href="http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&amp;dsMessageId=1098001"&gt;workaround&lt;/a&gt; for using Guice Finders with WadlApplication. And I still haven't had time to package any of this more nicely.  (&lt;em&gt;Feb 7:&lt;/em&gt; Jérôme Louvel took Leigh's suggestion and checked it in on the Restlet trunk.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-8181641757243614856?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/8181641757243614856/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=8181641757243614856' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/8181641757243614856'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/8181641757243614856'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2008/07/resource-dependency-injection-in.html' title='Resource dependency injection in Restlet via Guice'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33756480.post-2973612789383104507</id><published>2008-04-22T10:12:00.005-04:00</published><updated>2009-02-23T08:59:13.133-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Personal'/><category scheme='http://www.blogger.com/atom/ns#' term='Music and Theatre'/><title type='text'>Concert at Kosciuszko Hall</title><content type='html'>I attended a lovely concert at Kosciuszko Hall in Manhattan on Monday night. Cellist &lt;a href="http://www.geocities.com/mairid/"&gt;Mairi Dorman-Phaneuf&lt;/a&gt; and composer-pianist &lt;a href="http://www.einsteinsdreamsthemusical.com/cast.html"&gt;Joshua Rosenblum&lt;/a&gt; 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. &lt;br /&gt;&lt;br /&gt;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' &lt;span style="font-style:italic;"&gt;Wie Melodien&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;The concert included the world premiere of Josh Rosenblum's setting for soprano, cello, piano, and contrabass of T. S. Eliot's poem, &lt;span style="font-style:italic;"&gt;The Love Song of J. Alfred Prufrock&lt;/span&gt;. I liked it a lot, and I hope to make a recording of it soon so it can be shared with others.&lt;br /&gt;&lt;br /&gt;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:&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Sundry-Notes-Joshua-Rosenblum/dp/B0011NVBIU/"&gt;Sundry Notes&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Bush-Bad-Joshua-Rosenblum/dp/B000DN5XY2/"&gt;Bush is Bad&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Fermats-Tango-Joanne-Sydney-Lessner/dp/B00005QZMA/"&gt;Fermat's Last Tango&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;There is another Peierls-produced Rosenblum album, &lt;a href="http://www.amazon.com/Impetuosities-Joshua-Rosenblum-Christopher-Thompson/dp/B00008YJED/"&gt;Impetuosities&lt;/a&gt;, but it wasn't on sale at the concert.&lt;br /&gt;&lt;br /&gt;Another world premiere of Josh's music can be heard at the upcoming &lt;a href="http://www.joyce.org/calendar_detail.php?event=157&amp;theater=2"&gt;performance&lt;/a&gt; of the dance company, &lt;a href="http://chasebrockexperience.com"&gt;The Chase Brock Experience&lt;/a&gt;. 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? ... &lt;span style="font-style:italic;"&gt;Cut to the Chase&lt;/span&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-2973612789383104507?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/2973612789383104507/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=2973612789383104507' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/2973612789383104507'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/2973612789383104507'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2008/04/concert-at-kosciuszko-hall.html' title='Concert at Kosciuszko Hall'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33756480.post-6837587164434848393</id><published>2008-02-02T16:51:00.001-05:00</published><updated>2008-05-16T09:22:52.135-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Personal'/><title type='text'>Magic in the City</title><content type='html'>If you're looking to hire a magician for a New York City area children's birthday party, &lt;a href="http://jazzothegreat.com"&gt;Jazzo the Great&lt;/a&gt; comes highly recommended: &lt;br /&gt;&lt;a href="http://jazzothegreat.com" target="_blank"&gt;&lt;br /&gt;  &lt;img src="http://jazzothegreat.com/magic/riffle.gif" alt="Card Riffle" /&gt;&lt;br /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-6837587164434848393?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/6837587164434848393/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=6837587164434848393' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/6837587164434848393'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/6837587164434848393'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2008/02/magic-in-city.html' title='Magic in the City'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33756480.post-8120707988383199577</id><published>2008-01-16T15:05:00.001-05:00</published><updated>2008-05-16T09:09:21.373-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Personal'/><title type='text'>The Red and the Green</title><content type='html'>So &lt;a href="http://www.sciam.com/podcast/episode.cfm?id=7A81E74F-E554-39DF-62E0C6F540A3CDF8"&gt;wine tastes better with an expensive price tag&lt;/a&gt;. And I thought I just had good taste.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-8120707988383199577?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/8120707988383199577/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=8120707988383199577' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/8120707988383199577'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/8120707988383199577'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2008/01/red-and-green.html' title='The Red and the Green'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33756480.post-275571964498825874</id><published>2007-11-29T19:16:00.000-05:00</published><updated>2007-11-29T19:20:11.702-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Personal'/><title type='text'>Wilma-a-a-a-a</title><content type='html'>There are two kinds of people: those who quote the &lt;a href="http://en.wikipedia.org/wiki/Red_dwarf"&gt;Red Dwarf&lt;/a&gt; &lt;a href="http://tvsothertenpercent.tripod.com/reddwarf/backwards.html"&gt;going-to-bed-with-Wilma-Flintstone line&lt;/a&gt; in their signatures, and those who have gotten over it.&lt;br /&gt;&lt;br /&gt;Yes, it's funny. But not &lt;span style="font-weight:bold;"&gt;that&lt;/span&gt; funny.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-275571964498825874?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/275571964498825874/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=275571964498825874' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/275571964498825874'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/275571964498825874'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2007/11/wilma-a-a.html' title='Wilma-a-a-a-a'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33756480.post-5915122813386639965</id><published>2007-11-05T15:18:00.000-05:00</published><updated>2009-10-12T08:40:29.496-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Concurrency'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Restlet'/><title type='text'>Concurrency issues in Restlet</title><content type='html'>&lt;a href="http://restlet.tigris.org/issues/show_bug.cgi?id=368"&gt;Issue #368&lt;/a&gt; in the Restlet issue tracker was originally focused on the Guard class. Since then, I've taken a look at the rest of the &lt;code&gt;org.restlet&lt;/code&gt; package and found that the fields of most classes are &lt;a href="http://tembrel.blogspot.com/2007/10/basic-rules-for-threadsafe-classes.html"&gt;accessed without appropriate synchronization&lt;/a&gt;. &lt;span style="font-style:italic;"&gt;[Update 2008-Feb-6: All of these have been fixed as of Restlet 1.1 M1.]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Most of these problems would disappear if the fields could be final, but that would mean taking away setter-injectability.&lt;br /&gt;&lt;br /&gt;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 &lt;span style="font-style:italic;"&gt;effectively immutable&lt;/span&gt;. 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.&lt;br /&gt;&lt;br /&gt;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 &lt;span style="font-style:italic;"&gt;&lt;a href="http://www.jcip.net"&gt;Java Concurrency in Practice&lt;/a&gt;&lt;/span&gt; co-authors have the opposite preference.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-5915122813386639965?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/5915122813386639965/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=5915122813386639965' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/5915122813386639965'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/5915122813386639965'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2007/11/concurrency-issues-in-restlet.html' title='Concurrency issues in Restlet'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33756480.post-1144917243389054464</id><published>2007-10-13T16:19:00.000-04:00</published><updated>2008-04-24T15:20:26.064-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Personal'/><category scheme='http://www.blogger.com/atom/ns#' term='Music and Theatre'/><title type='text'>Babel</title><content type='html'>Jeffrey Sanzel writes (referring to &lt;a href="http://tembrel.blogspot.com/2007/10/basic-rules-for-threadsafe-classes.html"&gt;this posting&lt;/a&gt;):&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Here are the words I understood on your blog:&lt;br /&gt; &lt;br /&gt;blog&lt;br /&gt;Tim&lt;br /&gt;Peierls (to an extent)&lt;br /&gt;A (in context)&lt;br /&gt;of (in context)&lt;br /&gt;There&lt;br /&gt;All&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-1144917243389054464?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/1144917243389054464/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=1144917243389054464' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/1144917243389054464'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/1144917243389054464'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2007/10/babel.html' title='Babel'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33756480.post-1763382191508563668</id><published>2007-10-09T16:27:00.000-04:00</published><updated>2009-10-12T08:40:29.496-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Concurrency'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Basic rules for @ThreadSafe classes</title><content type='html'>Some rules for classes to be annotated with @ThreadSafe: &lt;ol&gt;&lt;li&gt; All non-final, non-volatile fields (and final references to non-thread-safe state) must be annotated with &lt;tt&gt;@GuardedBy(x)&lt;/tt&gt;, where &lt;tt&gt;x&lt;/tt&gt; is usually &lt;tt&gt;this&lt;/tt&gt;, meaning that &lt;span style="font-weight:bold;"&gt;all&lt;/span&gt; access to the field -- reads &lt;span style="font-weight:bold;"&gt;and&lt;/span&gt; writes -- is performed within a &lt;tt&gt;synchronized (this)&lt;/tt&gt; block or synchronized method. [This is probably the hardest rule for people to accept; it's not intuitive that reads must be performed with a lock held. See &lt;a href="#amplification"&gt;amplification&lt;/a&gt; below.]&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt; If two fields annotated with @GuardedBy participate in the same class invariant, they must be annotated with the same argument to @GuardedBy. [This is trivially satisfied if you only use @GuardedBy("this").]&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt; All compound actions with atomic semantics (e.g., check-then-act and read-modify-write sequences) must be performed completely within a synchronized block or method. [This is what many people incorrectly think is the only reason to use synchronized.]&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt; Do not make calls to code whose synchronization properties you don't know or control from inside a synchronized block or method; prefer open calls (calls made with no locks held). [This is a strategy for deadlock avoidance.]&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt; Prefer final fields. For collection fields, prefer thread-safe collections. (But don't bother using a thread-safe collection if the field needs to be @GuardedBy for some other reason.)&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt; Prefer final atomic variables to volatiles. Volatile fields cannot be modified atomically without a synchronized block.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt; There need be no special relationship between x and y in "@GuardedBy(x) Type y;" as long as &lt;span style="font-weight:bold;"&gt;all&lt;/span&gt; access to y is made while holding x's lock.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt; Don't be too clever: even if your clever reasoning is correct right now, it will be harder in the future for others (and you) to understand and maintain the code that relies on that reasoning.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="amplification"&gt;Amplification&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;p&gt; Brian Goetz suggests that I make this point more strongly: Not only do you need to declare such fields &lt;tt&gt;@GuardedBy(lock)&lt;/tt&gt;, you have to acquire &lt;tt&gt;lock&lt;/tt&gt; &lt;strong&gt;every time&lt;/strong&gt; you access the field in any way. &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-1763382191508563668?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/1763382191508563668/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=1763382191508563668' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/1763382191508563668'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/1763382191508563668'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2007/10/basic-rules-for-threadsafe-classes.html' title='Basic rules for @ThreadSafe classes'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33756480.post-8889012694947263798</id><published>2007-10-09T09:24:00.000-04:00</published><updated>2009-10-12T08:40:29.496-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Concurrency'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Restlet'/><title type='text'>Concurrency discussion in Restlet community</title><content type='html'>I started a &lt;a href="http://thread.gmane.org/gmane.comp.java.restlet/3195"&gt;thread&lt;/a&gt; on concurrency issues in the Restlet framework, and it led to a several people saying nice things about &lt;a href="http://jcip.net"&gt;&lt;span style="font-style:italic;"&gt;Java Concurrency in Practice&lt;/span&gt;&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Jérôme Louvel's &lt;a href="http://restlet.tigris.org/issues/show_bug.cgi?id=368"&gt;responsiveness&lt;/a&gt; to these issues is gratifying. A far cry from the huffiness I provoked when I had the temerity to &lt;a href="http://weblogs.java.net/blog/tomwhite/archive/2006/09/are_your_beans_1.html#c18658"&gt;question&lt;/a&gt; the concurrency guarantees in Spring!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-8889012694947263798?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/8889012694947263798/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=8889012694947263798' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/8889012694947263798'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/8889012694947263798'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2007/10/concurrency-discussion-in-restlet.html' title='Concurrency discussion in Restlet community'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33756480.post-3100327298474306442</id><published>2007-09-16T13:52:00.000-04:00</published><updated>2009-10-12T08:40:29.496-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Concurrency'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Java Concurrency in Practice news</title><content type='html'>I'm told that &lt;a href="http://javaconcurrencyinpractice.com"&gt;&lt;i&gt;Java Concurrency in Practice&lt;/i&gt;&lt;/a&gt; is going into its fifth printing!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-3100327298474306442?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/3100327298474306442/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=3100327298474306442' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/3100327298474306442'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/3100327298474306442'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2007/09/java-concurrency-in-practice-news.html' title='Java Concurrency in Practice news'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33756480.post-6225469643978827814</id><published>2007-09-16T12:59:00.000-04:00</published><updated>2009-10-12T08:40:29.497-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='DWR'/><category scheme='http://www.blogger.com/atom/ns#' term='Guice'/><title type='text'>Custom Matcher and MethodInterceptor for DWR-Guice</title><content type='html'>I wanted a way to intercept calls to public methods of a remoted interface so I could replace my use of &lt;a href="http://dev.priorartisans.com/tim/dwr-guice/apidocs/org/directwebremoting/guice/AbstractDwrModule.html#bindFilter(java.lang.String)"&gt;bindFilter&lt;/a&gt; with &lt;a href="http://google-guice.googlecode.com/svn/trunk/javadoc/com/google/inject/AbstractModule.html#bindInterceptor(com.google.inject.matcher.Matcher,%20com.google.inject.matcher.Matcher,%20org.aopalliance.intercept.MethodInterceptor...)"&gt;bindInterceptor&lt;/a&gt;, as described in &lt;a href="http://tembrel.blogspot.com/2007/09/replacing-ajaxfilter-with.html"&gt;an earlier posting&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;At first I thought I could just use the static methods in Matchers:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;bindInterceptor(&lt;br /&gt;  only(MyService.class), &lt;br /&gt;  any(), &lt;br /&gt;  myInterceptor&lt;br /&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This doesn't intercept anything, because MyService is an interface. What I needed was to intercept calls to a method of a subclass of MyService for which there exists a method of the same name and argument types in MyService.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;bindInterceptor(&lt;br /&gt;  subclassesOf(MyService.class), &lt;br /&gt;  declaredBy(MyService.class),&lt;br /&gt;  myInterceptor&lt;br /&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The subclassesOf matcher is already provided in com.google.inject.matcher.Matchers, but I had to roll my own declaredBy method matcher. Here's the heart of the implementation (cls is a final Class&amp;lt;?&gt; field, initialized from the argument to declaredBy):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public boolean matches(Method method) {&lt;br /&gt;  try {&lt;br /&gt;    // Matches if the method is from a subclass &lt;br /&gt;    // of the given class (or the class itself) &lt;br /&gt;    // and the given class declares a method&lt;br /&gt;    // with the same name and parameter types. &lt;br /&gt;    if (cls.isAssignableFrom(&lt;br /&gt;             method.getDeclaringClass())) {&lt;br /&gt;      // Return value of getDeclaredMethod &lt;br /&gt;      // is ignored. It throws an exception &lt;br /&gt;      // if the method is not found.&lt;br /&gt;      cls.getDeclaredMethod(&lt;br /&gt;        method.getName(), &lt;br /&gt;        method.getParameterTypes());&lt;br /&gt;      return true;&lt;br /&gt;    }&lt;br /&gt;    // fall through&lt;br /&gt;  } catch (NoSuchMethodException e) {&lt;br /&gt;    // fall through&lt;br /&gt;  } catch (SecurityException e) {&lt;br /&gt;    // fall through&lt;br /&gt;  }&lt;br /&gt;  return false;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This still didn't work quite right; the implementation of one method called another public method of the interface, and that call was intercepted even though it wasn't a remote call. To mimic AjaxFilter, I want to able to intercept only the outermost call. I wrote a MethodInterceptor-decorator:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class OutermostCallInterceptor &lt;br /&gt;    implements MethodInterceptor {&lt;br /&gt;  /**&lt;br /&gt;   * Decorates a MethodInterceptor so that only the &lt;br /&gt;   * outermost invocation using that interceptor will &lt;br /&gt;   * be intercepted and nested invocations willbe &lt;br /&gt;   * ignored.&lt;br /&gt;   */ &lt;br /&gt;  public static MethodInterceptor outermostCall(&lt;br /&gt;      MethodInterceptor interceptor) {&lt;br /&gt;    return new OutermostCallInterceptor(interceptor);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  /** Ensure underlying interceptor is injected. */&lt;br /&gt;  @Inject void injectInterceptor(Injector injector) {&lt;br /&gt;    injector.injectMembers(interceptor);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public Object invoke(MethodInvocation invocation) &lt;br /&gt;      throws Throwable {&lt;br /&gt;    int savedCount = count.get();&lt;br /&gt;    count.set(savedCount + 1);&lt;br /&gt;    try {&lt;br /&gt;        if (count.get() &gt; 1) &lt;br /&gt;          return invocation.proceed();&lt;br /&gt;        else &lt;br /&gt;          return interceptor.invoke(invocation);&lt;br /&gt;    } finally {&lt;br /&gt;      count.set(savedCount);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  private OutermostCallInterceptor(&lt;br /&gt;      MethodInterceptor interceptor) {&lt;br /&gt;    this.interceptor = interceptor;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  private final MethodInterceptor interceptor;&lt;br /&gt;&lt;br /&gt;  private final ThreadLocal&lt;Integer&gt; count = &lt;br /&gt;    new ThreadLocal&lt;Integer&gt;() {&lt;br /&gt;      @Override protected Integer initialValue() {&lt;br /&gt;        return 0;&lt;br /&gt;      }&lt;br /&gt;    };&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So now my binding looks like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;bindInterceptor(&lt;br /&gt;  subclassesOf(MyService.class), &lt;br /&gt;  declaredBy(MyService.class),&lt;br /&gt;  outermostCall(myInterceptor)&lt;br /&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;and myInterceptor is injected. It's not as compact as using bindFilter, but I can apply multiple interceptors without having to resort to FluentConfigurator. The use of subclassesOf is probably redundant, since declaredBy checks that the method is from a subclass of MyService, but I think it helps to clarify what's going on.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-6225469643978827814?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/6225469643978827814/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=6225469643978827814' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/6225469643978827814'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/6225469643978827814'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2007/09/matcher-and-methodinterceptor-for-dwr.html' title='Custom Matcher and MethodInterceptor for DWR-Guice'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33756480.post-6391895495492691915</id><published>2007-09-15T23:41:00.000-04:00</published><updated>2009-10-12T08:40:29.497-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='DWR'/><category scheme='http://www.blogger.com/atom/ns#' term='Guice'/><title type='text'>Replacing AjaxFilter with MethodInterceptor</title><content type='html'>&lt;p&gt; I wrote the &lt;a href="http://tembrel.blogspot.com/2007/09/injecting-method-interceptors-in-guice.html"&gt;previous posting&lt;/a&gt; without referring to DWR-Guice integration but in practice I extended org.directwebremoting.guice.AbstractDwrModule, not com.google.inject.AbstractModule. &lt;/p&gt;&lt;p&gt; For DWR-Guice users, the nice thing about injectable method interceptors is that you can use them to replace most uses of AjaxFilter, which is a good thing because the AjaxFilter support in the DWR-Guice stuff is weak (&lt;i&gt;mea culpa&lt;/i&gt;). &lt;/p&gt;&lt;p&gt; I had to write some support utilities to get the right effect, but now I can do something like this:&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;bindInterceptor(&lt;br /&gt; subclassesOf(VulnerableService.class), // class matcher&lt;br /&gt; declaredBy(VulnerableService.class),   // method matcher&lt;br /&gt; // prevent nested interception&lt;br /&gt; outermostCall(new AuthenticationInterceptor()),&lt;br /&gt; outermostCall(new AuthorizationInterceptor())&lt;br /&gt;);&lt;br /&gt;&lt;/pre&gt;and AuthenticationInterceptor is injected, so that it can look like&lt;br /&gt;this:&lt;br /&gt;&lt;pre&gt;class AuthenticationInterceptor &lt;br /&gt;    implements MethodInterceptor {&lt;br /&gt; @Inject Provider&amp;lt;RequestParameters&gt; reqParmsProvider;&lt;br /&gt; @Inject Provider&amp;lt;AuthenticationService&gt; authSvcProvider;&lt;br /&gt; public Object invoke(MethodInvocation invocation) &lt;br /&gt;     throws Throwable {&lt;br /&gt;   RequestParameters reqParms = reqParmsProvider.get();&lt;br /&gt;   AuthenticationService authSvc = authSvcProvider.get();&lt;br /&gt;   if (authSvc.authenticate(reqParms))&lt;br /&gt;     return invocation.proceed();&lt;br /&gt;   else&lt;br /&gt;     throw new AuthenticationException(reqParms);&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;The subclassesOf matcher is part of Guice. The declaredBy matcher and the outermostCall interceptor decorator are custom implementations that I'll describe in &lt;a href="http://tembrel.blogspot.com/2007/09/matcher-and-methodinterceptor-for-dwr.html"&gt;a later posting&lt;/a&gt;. &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-6391895495492691915?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/6391895495492691915/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=6391895495492691915' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/6391895495492691915'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/6391895495492691915'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2007/09/replacing-ajaxfilter-with.html' title='Replacing AjaxFilter with MethodInterceptor'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33756480.post-7276804835690496644</id><published>2007-09-14T23:57:00.001-04:00</published><updated>2009-10-12T08:40:29.497-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Guice'/><title type='text'>Injecting method interceptors in Guice 1.0</title><content type='html'>&lt;p&gt; Guice 1.1 will probably have &lt;a href="http://code.google.com/p/google-guice/issues/detail?id=88"&gt;injected method interceptors&lt;/a&gt;, but until then those of us who need this kind of thing will have to roll our own. &lt;/p&gt;&lt;p&gt;&lt;i&gt;[Update 2009-1-3] Guice 2 has (or will have, depending on how you view its release status) a requestInjection facility.&lt;/i&gt;&lt;/p&gt;The way I've been doing it is similar to &lt;a href="http://groups.google.com/group/google-guice/msg/efd5dabfe74e00e9"&gt;the way Stuart McCulloch suggested&lt;/a&gt;, but more automatic: I extend AbstractModule by&lt;br /&gt;&lt;ol&gt;&lt;li&gt; adding a registerForInjection method that takes a varargs array of objects that should be injected and &lt;/li&gt;&lt;li&gt; overriding bindInterceptor to call registerForInjection(interceptors) before calling the superclass implementation. &lt;/li&gt;&lt;/ol&gt;The implementation of registerForInjection adds the elements of the array argument to a set of objects to be injected. There is a private method, injectRegisteredObjects, marked with @Inject; all it does is call Injector.injectMembers on every element of this set. &lt;p&gt;&lt;/p&gt;&lt;p&gt; To ensure that injectRegisteredObjects is called, I bind the module class to the module instance. Since I want to be able to do this for every instance of the module, I bind with a unique annotation instance each time. The private method ensureSelfInjection does this binding once only for each module instance, so I can safely call it in registerForInjection. &lt;/p&gt;&lt;p&gt; Here's the code: &lt;/p&gt;/**&lt;br /&gt;&lt;pre&gt; * An extension of AbstractModule that provides&lt;br /&gt;* support for member injection of instances&lt;br /&gt;* constructed at bind-time; in particular,&lt;br /&gt;* itself and MethodInterceptors.&lt;br /&gt;*/&lt;br /&gt;public abstract class ExtendedModule extends AbstractModule {&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * Overridden version of bindInterceptor that,&lt;br /&gt;  * in addition to the standard behavior,&lt;br /&gt;  * arranges for field and method injection of&lt;br /&gt;  * each MethodInterceptor in {@code interceptors}.&lt;br /&gt;  */&lt;br /&gt; @Override public void bindInterceptor(Matcher&amp;lt;? super Class&amp;lt;?&amp;gt;&amp;gt; classMatcher,&lt;br /&gt;                                       Matcher&amp;lt;? super Method&amp;gt; methodMatcher,&lt;br /&gt;                                       MethodInterceptor... interceptors) {&lt;br /&gt;   registerForInjection(interceptors);&lt;br /&gt;   super.bindInterceptor(classMatcher, methodMatcher, interceptors);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * Arranges for this module and each of the given&lt;br /&gt;  * objects (if any) to be field and method injected&lt;br /&gt;  * when the Injector is created. It is safe to call&lt;br /&gt;  * this method more than once, and it is safe&lt;br /&gt;  * to call it more than once on the same object(s).&lt;br /&gt;  */&lt;br /&gt; protected &amp;lt;T&amp;gt; void registerForInjection(T... objects) {&lt;br /&gt;   ensureSelfInjection();&lt;br /&gt;   if (objects != null) {&lt;br /&gt;     for (T object : objects) {&lt;br /&gt;       if (object != null) toBeInjected.add(object);&lt;br /&gt;     }&lt;br /&gt;   }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @Inject private void injectRegisteredObjects(Injector injector) {&lt;br /&gt;   for (Object injectee : toBeInjected) {&lt;br /&gt;     injector.injectMembers(injectee);&lt;br /&gt;   }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private void ensureSelfInjection() {&lt;br /&gt;   if (!selfInjectionInitialized) {&lt;br /&gt;     bind(ExtendedModule.class)&lt;br /&gt;       .annotatedWith(getUniqueAnnotation())&lt;br /&gt;       .toInstance(this);&lt;br /&gt;     selfInjectionInitialized = true;&lt;br /&gt;   }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private final Set&amp;lt;Object&amp;gt; toBeInjected = new HashSet&amp;lt;Object&amp;gt;();&lt;br /&gt;  &lt;br /&gt; private boolean selfInjectionInitialized = false;  &lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * Hack to ensure unique Keys for binding different&lt;br /&gt;  * instances of ExtendedModule. The prefix is chosen&lt;br /&gt;  * to reduce the chances of a conflict with some other&lt;br /&gt;  * use of @Named. A better solution would be to invent&lt;br /&gt;  * an Annotation for just this purpose.&lt;br /&gt;  */&lt;br /&gt; private static Annotation getUniqueAnnotation() {&lt;br /&gt;   return named("ExtendedModule-" + count.incrementAndGet());&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private static final AtomicInteger count = new AtomicInteger();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt; There's a &lt;a href="http://tembrel.blogspot.com/2007/09/replacing-ajaxfilter-with.html"&gt;follow-up posting&lt;/a&gt; on DWR-Guice applications. &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-7276804835690496644?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/7276804835690496644/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=7276804835690496644' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/7276804835690496644'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/7276804835690496644'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2007/09/injecting-method-interceptors-in-guice.html' title='Injecting method interceptors in Guice 1.0'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33756480.post-5125401086045576123</id><published>2007-07-06T20:20:00.000-04:00</published><updated>2008-04-24T15:20:26.067-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Music and Theatre'/><title type='text'>Children's show opening</title><content type='html'>&lt;i&gt;The Fairy Princess&lt;/i&gt;, a children's show that Jeffrey E. Sanzel and I wrote, opened today at &lt;a href="http://theatrethree.com"&gt;Theatre Three&lt;/a&gt; in Port Jefferson. It runs Fridays and Saturdays at 11am throughout July.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-5125401086045576123?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/5125401086045576123/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=5125401086045576123' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/5125401086045576123'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/5125401086045576123'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2007/07/childrens-show-opening.html' title='Children&apos;s show opening'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33756480.post-1813920766996921538</id><published>2007-07-05T07:21:00.001-04:00</published><updated>2008-04-25T13:17:17.039-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Personal'/><category scheme='http://www.blogger.com/atom/ns#' term='Music and Theatre'/><title type='text'>Fifth of July</title><content type='html'>It would have been more appropriate to post this yesterday, I suppose: &lt;br /&gt;&lt;br /&gt;&lt;a href="http://thisisamericathesong.blogspot.com/"&gt;Michele Oliver&lt;/a&gt; blogged about the song "&lt;a href="http://thisisamericathesong.blogspot.com/2007/06/this-is-america.html"&gt;This is America&lt;/a&gt;", on which Ilene and I can be heard as part of the backing chorus near the end of the song. It was recorded in 2001, partly in response to the 9/11 attacks.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-1813920766996921538?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/1813920766996921538/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=1813920766996921538' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/1813920766996921538'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/1813920766996921538'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2007/07/fifth-of-july.html' title='Fifth of July'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33756480.post-758093660355973909</id><published>2007-04-12T17:53:00.000-04:00</published><updated>2009-10-12T08:40:29.497-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Guice'/><title type='text'>A Guice utility for binding to legacy classes</title><content type='html'>&lt;p&gt; You're going along, happily Guicing your world, when you run into a snag. There's a class &lt;span style="font-family:courier new;"&gt;Legacy&lt;/span&gt; that you'd like to be able to bind things to, but you can't edit the source to add the &lt;span style="font-family:courier new;"&gt;@Inject&lt;/span&gt; annotations. It looks like this:&lt;/p&gt;&lt;pre&gt;&lt;br /&gt;public class Legacy implements SomeInterface {&lt;br /&gt; public Legacy(LegacyDependency dep, String str) {&lt;br /&gt;   ...&lt;br /&gt; }&lt;br /&gt; public void initialize(LegacyConfig cfg) {&lt;br /&gt;   ...&lt;br /&gt; }&lt;br /&gt; ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;And you wish it looked like this:&lt;/p&gt;&lt;pre&gt;&lt;br /&gt;public class Legacy implements SomeInterface {&lt;br /&gt; &lt;span style="font-weight:bold;"&gt;@Inject&lt;/span&gt; public Legacy(LegacyDependency dep,&lt;br /&gt;                       &lt;span style="font-weight:bold;"&gt;@MyAnnotation&lt;/span&gt; String str) {&lt;br /&gt;   ...&lt;br /&gt; }&lt;br /&gt; &lt;span style="font-weight:bold;"&gt;@Inject&lt;/span&gt; public void initialize(LegacyConfig cfg) {&lt;br /&gt;   ...&lt;br /&gt; }&lt;br /&gt; ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;You're used to Guice by now, so right away you think, "No problem, I'll use a &lt;span style="font-family:courier new;"&gt;Provider&lt;/span&gt;!" &lt;/p&gt; &lt;pre&gt;&lt;br /&gt;public class LegacyProvider&lt;br /&gt;     implements Provider&amp;lt;Legacy&amp;gt; {&lt;br /&gt;&lt;br /&gt; public Legacy get() {&lt;br /&gt;   Legacy result = new Legacy(dep, str);&lt;br /&gt;   result.initialize(cfg);&lt;br /&gt;   return result;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @Inject LegacyDependency dep;&lt;br /&gt; @Inject @MyAnnotation String str;&lt;br /&gt; @Inject LegacyConfig cfg;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt; protected void configure() {&lt;br /&gt;   bind(SomeInterface.class)&lt;br /&gt;     .toProvider(LegacyProvider.class)&lt;br /&gt;     .in(WEB_APPLICATION_SCOPE);&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt; &lt;p&gt; So you've written a &lt;span style="font-family:courier new;"&gt;Provider&amp;lt;Legacy&amp;gt;&lt;/span&gt;, and it works. But now you have this extra class to maintain. It's not complicated, in fact it's quite trivial. It seems like something you shouldn't have had to write. You'd rather write something like this: &lt;/p&gt; &lt;pre&gt;&lt;br /&gt; bind(SomeInterface.class)&lt;br /&gt;   .toProvider(&lt;br /&gt;&lt;br /&gt;     fromConstructor(Legacy.class,&lt;br /&gt;       Key.get(LegacyDependency.class),&lt;br /&gt;       Key.get(String.class, MyAnnotation.class))&lt;br /&gt;&lt;br /&gt;     .injecting("initialize",&lt;br /&gt;       Key.get(LegacyConfig.class))&lt;br /&gt;&lt;br /&gt;     )&lt;br /&gt;&lt;br /&gt;   .in(WEB_APPLICATION_SCOPE);&lt;br /&gt;&lt;/pre&gt; &lt;p&gt; If this looks like something you want, check out my &lt;a href="http://dev.priorartisans.com/tim/dwr-guice/xref/org/directwebremoting/guice/BindUtil.html"&gt;implementation&lt;/a&gt; in the DWR-Guice integration sources. The &lt;a href="http://dev.priorartisans.com/tim/dwr-guice/apidocs/org/directwebremoting/guice/BindUtil.html"&gt;javadocs&lt;/a&gt; are there, too, but they aren't complete. It doesn't have anything to do with DWR, but it seems like a nice convenience to provide. &lt;/p&gt;&lt;p&gt; There are also several flavors of factory-method-based providers, so you don't have to write a special provider just to call a factory method. &lt;/p&gt;&lt;p&gt; I wrote it because even though I've been able to jettison a lot of baggage as I migrate from Spring to Guice, there are still Spring things I want to keep using, like &lt;code&gt;JavaMailSender&lt;/code&gt;. I don't want to have to write provider implementations for each one.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-758093660355973909?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/758093660355973909/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=758093660355973909' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/758093660355973909'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/758093660355973909'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2007/04/guice-utility-for-binding-to-legacy.html' title='A Guice utility for binding to legacy classes'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33756480.post-8259044859598579319</id><published>2007-04-05T08:55:00.001-04:00</published><updated>2009-10-12T08:40:29.497-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='DWR'/><category scheme='http://www.blogger.com/atom/ns#' term='Guice'/><title type='text'>Guice support in DWR</title><content type='html'>&lt;a href="http://code.google.com/p/google-guice/"&gt;Guice&lt;/a&gt; is the hot new dependency injection framework from Bob Lee and others at Google. &lt;a href="http://directwebremoting.org/"&gt;DWR&lt;/a&gt; is a system for remoting Java server-side objects as JavaScript client-side objects in a way that is natural on both the client and server sides.&lt;br /&gt;&lt;br /&gt;I'd been using DWR with Spring to wire together all the components of the &lt;a href="http://www.seatyourself.biz/demo"&gt;Seat Yourself on-line ticket sales web application&lt;/a&gt; for almost a year and I was pretty happy with the combination. Then a few weeks ago, just as I was considering how to make the webapp more easily configurable, to support rapid administration and self-configuration of many customers, Josh Bloch suggested I take a look at Guice, and I suddenly realized just how fragile and unmaintainable was all that XML I had written for DWR and Spring.&lt;br /&gt;&lt;br /&gt;Of course I could use Guice without integrating it with DWR, but one of the things that had always bothered me about DWR (and many other tools, not just DWR) was that everything -- remoted objects, data transfer objects, extension classes -- has to be concrete and public, with a public parameterless constructor, and everything works through setter injection, which makes things &lt;a href="http://weblogs.java.net/blog/tomwhite/archive/2006/09/are_your_beans_1.html"&gt;difficult&lt;/a&gt;. I want to work in terms of interfaces, with implementation classes that have final fields for injected state.&lt;br /&gt;&lt;br /&gt;Guice looked like a way to have it all: easy remoting with type-safe (pure Java) configuration. I wrote a &lt;a href="http://dev.priorartisans.com/tim/dwr-guice/index.html"&gt;Guice integration package for DWR&lt;/a&gt;, and Joe Walker signed me on as a DWR contributor so I can help maintain it as part of the DWR distribution. The &lt;a href="http://dev.priorartisans.com/tim/dwr-guice/apidocs/org/directwebremoting/guice/package-summary.html"&gt;package Javadoc&lt;/a&gt; describes how to use it along with a simple example.&lt;br /&gt;&lt;br /&gt;I'm still in the early stages of applying it to the Seat Yourself web sales application, but already the power of Guice has made things simpler. Each customer (where a customer is ticket-selling entity, like a theater) is associated with a &lt;span style="font-style: italic;"&gt;domain&lt;/span&gt; where all their data -- seat charts, performance information, pricing information, patrons and their reservations, and holds on seats  -- is maintained. When a user visits the web store to buy tickets, the link contains a domain name, e.g., "t3" for &lt;a href="http://www.theatrethree.com/index.htm"&gt;Theatre Three&lt;/a&gt;. Before Guice support, I had devised a complicated system using reflection and proxying to route the user request to the appropriate service object. It was so involved that I had trouble explaining it to my partners, both smart people. Not being able to explain something is a bad code smell.&lt;br /&gt;&lt;br /&gt;With Guice-injected remoted objects, I can define a new scope, &lt;span style="font-style: italic;"&gt;domain scope&lt;/span&gt;, where the details of providing the appropriate domain-specific service object are neatly encapsulated and managed by Guice. All I have to do is write something like this in my binding code:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;bindRemotedAs("Tix", WebstoreService.class) // interface&lt;br /&gt;  .to(WebstoreServiceImpl.class)            // impl&lt;br /&gt;  .in(DomainScopes.DOMAIN);                 // scope&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;where the interface looks like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public interface WebstoreService {&lt;br /&gt;  PerformanceAvailability getPerformanceAvailability();&lt;br /&gt;  ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Only the methods of &lt;span style="font-family:courier new;"&gt;WebstoreService&lt;/span&gt; are exposed to the world, even though the implementation class might have other public methods. With the Guice support, I don't need to specify which methods to expose. As usual with DWR, on the JavaScript side I can write things like:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Tix.getPerformanceAvailability({&lt;br /&gt;  callback : function(availability) {&lt;br /&gt;    notifyPerformanceAvailabilityReceived(availability)&lt;br /&gt;  },&lt;br /&gt;  exceptionHandler : ...&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Because Guice has Spring integration, I can migrate my existing Spring-based code smoothly. Because it has JNDI integration, I can rewrite the code that manages the domain-specific configuration to use whatever LDAP back-end I like, instead of having to maintain an assortment of XML files and registry settings. We've already had problems with syntax errors in the XML configuration files, so this will save us a lot of heartache.&lt;br /&gt;&lt;br /&gt;Guice also has support for AOP Alliance method interceptors, which means that on most of the occasions when I would feel most tempted to use AspectJ, I can stick to pure Java. Not that I have anything against AspectJ, but it's a different language and one more thing to worry about. I want to save it for the occasions when I &lt;span style="font-weight: bold;"&gt;really&lt;/span&gt; need it (as was the case for another submodule of our project).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-8259044859598579319?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/8259044859598579319/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=8259044859598579319' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/8259044859598579319'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/8259044859598579319'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2007/04/guice-support-in-dwr.html' title='Guice support in DWR'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33756480.post-1823797844225351515</id><published>2007-01-10T22:24:00.001-05:00</published><updated>2008-08-01T17:29:35.176-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Personal'/><category scheme='http://www.blogger.com/atom/ns#' term='Music and Theatre'/><title type='text'>Blurb in Yale Alumni Magazine</title><content type='html'>The class notes section of the current issue of the &lt;a href="http://www.yalealumnimagazine.com/"&gt;Yale Alumni Magazine&lt;/a&gt; includes some notes I submitted in the fall.&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;br /&gt;Tim Peierls&lt;/span&gt; (JE) (tim@peierls.net) writes that 2006 was exceptionally busy, with his hand in a wide range of diverse ventures: "I helped produce fellow JEer &lt;span style="font-weight:bold;"&gt;Josh Rosenblum&lt;/span&gt;'s musical show, &lt;span style="font-style:italic;"&gt;&lt;a href="http://bushisbadthemusical.com"&gt;Bush is Bad&lt;/a&gt;&lt;/span&gt;; the title says it all. I co-wrote a book, &lt;span style="font-style:italic;"&gt;&lt;a href="http://jcip.net"&gt;Java Concurrency in Practice&lt;/a&gt;&lt;/span&gt; (Addison-Wesley). If the title makes sense to you, then you need the book; if not, then ... not. I co-produced (with Gary William Friedman) an album by jazz vocalist Stevie Holland, &lt;span style="font-style:italic;"&gt;&lt;a href="http://stevieholland.com"&gt;More Than Words Can Say&lt;/a&gt;&lt;/span&gt;. And I developed an online ticket sales application that went into production in November. See &lt;a href="http://www.seatyourself.biz"&gt;www.SeatYourself.biz&lt;/a&gt; for details."&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-1823797844225351515?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/1823797844225351515/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=1823797844225351515' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/1823797844225351515'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/1823797844225351515'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2007/01/blurb-in-yale-alumni-magazine.html' title='Blurb in Yale Alumni Magazine'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33756480.post-1651887473065406688</id><published>2006-12-07T16:18:00.000-05:00</published><updated>2007-09-15T00:08:30.071-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Personal'/><title type='text'>Rescued from Nokia</title><content type='html'>I had been unable/unwilling to download the many photos I had accumulated on my old Nokia phone. Today, however, I put the Treo head-to-head (well, head-to-side) with the Nokia, and I transferred them all over IR to the Treo, then down to the PC, then up to my public gallery with Picasa.&lt;br /&gt;&lt;br /&gt;For example, this was my phone's background for a long time: &lt;a href="http://picasaweb.google.com/tpeierls/RescuedFromNokia/photo#5005893825225194866"&gt;&lt;img src="http://lh4.google.com/image/tpeierls/RXiB6WPefXI/AAAAAAAAASk/fIXM-GJ-U5E/s288/Image%2825%29.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The full album:&lt;br /&gt;&lt;div style="text-align:center;width:194px;font-family:arial,sans-serif;font-size:83%"&gt;&lt;div style="height:194px;background:url(http://picasaweb.google.com/f/img/transparent_album_background.gif) no-repeat left"&gt;&lt;a href="http://picasaweb.google.com/tpeierls/RescuedFromNokia"&gt;&lt;img src="http://lh4.google.com/image/tpeierls/RXiB3mPefHE/AAAAAAAAAVg/XP0Sm2M_C_E/s160-c/RescuedFromNokia.jpg" width="160" height="160" style="border:none;padding:0px;margin-top:16px;"&gt;&lt;/a&gt;&lt;/div&gt;&lt;a href="http://picasaweb.google.com/tpeierls/RescuedFromNokia"&gt;&lt;div style="color:#4D4D4D;font-weight:bold;text-decoration:none;"&gt;Rescued from Nokia&lt;/div&gt;&lt;/a&gt;&lt;div style="color:#808080"&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-1651887473065406688?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/1651887473065406688/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=1651887473065406688' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/1651887473065406688'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/1651887473065406688'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2006/12/rescued-from-nokia.html' title='Rescued from Nokia'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33756480.post-6659184507842421531</id><published>2006-12-04T07:14:00.000-05:00</published><updated>2008-04-24T15:20:26.070-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Music and Theatre'/><title type='text'>Grinch opening</title><content type='html'>I posted about &lt;a href="http://vox.boxpop.biz/2006/12/03/opening-night-at-the-grinch/"&gt;opening night at the new Grinch musical&lt;/a&gt; on the BoxPop site.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;[update 2007-Sep-15]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;That link might be down for good, so here's what I posted:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;The new Broadway production of How the Grinch Stole Christmas opened on November 8, my birthday. My friend Josh Rosenblum is the musical director for the show. As a birthday present he got my family in on opening night, including passes to the opening night party across the street at Madame Tussaud’s wax museum.&lt;br /&gt;&lt;br /&gt;The show runs about 75 minutes, with no intermission. It was mostly not my cup of tea, but both of my kids were riveted and said they would like to see it again. In addition to providing music direction, Josh wrote some of the incidental music and did the vocal arrangements; there were several lovely moments of multipart singing, which is what I go for. There was also one very funny line that I’m told was an ad lib during rehearsals; I won’t give it away, but I’ll mention that it happens just before Cindy Lou Who’s big number.&lt;br /&gt;&lt;br /&gt;The party at Madame Tussaud’s was huge. I had never been to a wax museum before, so I had what I gather is the usual reaction of mistaking wax figures for real people and vice versa. I would have liked to stay longer, but we discovered that Tessa, our oldest, is afraid of wax figures, so we had to hustle through quickly and miss a lot. &lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-6659184507842421531?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/6659184507842421531/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=6659184507842421531' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/6659184507842421531'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/6659184507842421531'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2006/12/i-posted-about-opening-night-at-new.html' title='Grinch opening'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33756480.post-115721267419534988</id><published>2006-09-02T11:56:00.000-04:00</published><updated>2007-09-15T00:08:38.203-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Personal'/><title type='text'>Inspired by Natto blog</title><content type='html'>I created this blog because it seemed like the easiest way to post a comment on &lt;a href="http://www.thenattoproject.com/"&gt;The Natto Project&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33756480-115721267419534988?l=tembrel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tembrel.blogspot.com/feeds/115721267419534988/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33756480&amp;postID=115721267419534988' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/115721267419534988'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33756480/posts/default/115721267419534988'/><link rel='alternate' type='text/html' href='http://tembrel.blogspot.com/2006/09/inspired-by-natto-blog.html' title='Inspired by Natto blog'/><author><name>Tim Peierls</name><uri>http://www.blogger.com/profile/12360655614437868477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry></feed>
