<?xml version='1.0' encoding='UTF-8'?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/'><id>tag:blogger.com,1999:blog-8675640</id><updated>2008-07-04T07:58:40.913-07:00</updated><title type='text'>Public Object</title><link rel='alternate' type='text/html' href='http://publicobject.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default?start-index=26&amp;max-results=25'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default'/><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://publicobject.com/publicobject/atom.xml'/><author><name>swankjesse</name><uri>http://www.blogger.com/profile/04905794974441087900</uri><email>noreply@blogger.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>219</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8675640.post-8048078303413863200</id><published>2008-06-30T18:49:00.000-07:00</published><updated>2008-06-30T19:25:20.681-07:00</updated><title type='text'>Strict vs. Forgiving APIs</title><content type='html'>Suppose it's the early 1990's and you're James Gosling implementing &lt;code&gt;String.substring(int, int)&lt;/code&gt; for the first time. What should happen when the index arguments are out-of-range? Should these tests pass? Or throw?&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;  public void testSubstring() {&lt;br /&gt;    assertEquals("class", "superclass".substring(5, 32));&lt;br /&gt;    assertEquals("super", "superclass".substring(-2, 5));&lt;br /&gt;    assertEquals("", "superclass".substring(20, 24));&lt;br /&gt;    assertEquals("superclass", "superclass".substring(10, 0));&lt;br /&gt;  }&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Forgiving APIs&lt;/h3&gt;&lt;br /&gt;In a forgiving API, these tests pass. The implementation would recognize the out-of-range indices and correct for them. Benefits of forgiving APIs:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Fault-tolerant.&lt;/strong&gt; An off-by-one mistake won't bring a production system to its knees.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Easier to code against.&lt;/strong&gt; If you don't know what to use for a given argument, just pass &lt;code&gt;null&lt;/code&gt; and the implementation will do something reasonable.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Strict APIs&lt;/h3&gt;&lt;br /&gt;In a strict APIs, the out-of-range arguments to &lt;code&gt;substring&lt;/code&gt; are forbidden and the method throws an &lt;code&gt;IllegalArgumentException&lt;/code&gt;. Benefits of strict APIs:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Fail-fast.&lt;/strong&gt; An off-by-one mistake will be caught in unit tests, if they exist.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Easier to maintain.&lt;/strong&gt; By limiting the number of valid inputs, there's less behaviour to maintain and test.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;More Predictable.&lt;/strong&gt; Mapping invalid inputs to behaviour is an artform. In the example, should &lt;code&gt;substring(10, 0)&lt;/code&gt; return the empty string? Or "superclass"? What would the caller expect?&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;For maintainability, I almost always prefer strict APIs. I like to think of the classes in my code as the gears in a fine Swiss watch. Everything fits together tightly, with firm constraints on both the inputs and the outputs. I can refactor with confidence because the system simply won't work if I've introduced problems into it. With a forgiving API, I could introduce bugs and not find out about them until much later.</content><link rel='alternate' type='text/html' href='http://publicobject.com/2008/06/strict-vs-forgiving-apis.html' title='Strict vs. Forgiving APIs'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8675640&amp;postID=8048078303413863200' title='4 Comments'/><link rel='replies' type='application/atom+xml' href='http://publicobject.com/publicobject/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/8048078303413863200'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/8048078303413863200'/><author><name>swankjesse</name><uri>http://www.blogger.com/profile/04905794974441087900</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8675640.post-1209946180331059090</id><published>2008-06-23T22:47:00.000-07:00</published><updated>2008-06-24T00:39:42.589-07:00</updated><title type='text'>What's a Hierarchical Injector?</title><content type='html'>Our application has two implementations for one interface. &lt;code&gt;EnergySource&lt;/code&gt; is implemented by both &lt;code&gt;Plutonium&lt;/code&gt; and &lt;code&gt;LightningBolt&lt;/code&gt;:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;class DeLorean {&lt;br /&gt;  @Inject TimeCircuits timeCircuits;&lt;br /&gt;  @Inject FluxCapacitor fluxCapacitor;&lt;br /&gt;  @Inject EnergySource energySource;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;interface FluxCapacitor {&lt;br /&gt;  boolean isFluxing();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@Singleton&lt;br /&gt;class RealFluxCapacitor implements FluxCapacitor {&lt;br /&gt;  @Inject TimeCircuits timeCircuits;&lt;br /&gt;  boolean isFluxing;&lt;br /&gt;&lt;br /&gt;  public boolean isFluxing() {&lt;br /&gt;    return isFluxing;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class TimeCircuits {&lt;br /&gt;  Date whereYouveBeen;&lt;br /&gt;  Date whereYouAre;&lt;br /&gt;  Date whereYourGoing;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;interface EnergySource {&lt;br /&gt;  void generateOnePointTwentyOneGigawatts();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class Plutonium implements EnergySource { ... }&lt;br /&gt;&lt;br /&gt;class LightningBolt implements EnergySource { ... }&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;And to allow for sequels, we assume other implementations of &lt;code&gt;EnergySource&lt;/code&gt; are possible. We'd like to create an &lt;code&gt;Injector&lt;/code&gt; immediately and create a Plutonium-powered DeLorean. Shortly thereafter, we'd like to re-use that same &lt;code&gt;Injector&lt;/code&gt;, but with a lightning bolt for energy.&lt;br /&gt;&lt;blockquote align="center"&gt;&lt;img src="/uploaded_images/plutonium.png"&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Option one: Factory classes&lt;/h3&gt;&lt;br /&gt;We can solve this problem by introducing a &lt;code&gt;DeLorean.Factory&lt;/code&gt; interface that accepts an &lt;code&gt;EnergySource&lt;/code&gt; as its only parameter:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;class DeLorean {&lt;br /&gt;  private final TimeCircuits timeCircuits;&lt;br /&gt;  private final FluxCapacitor fluxCapacitor;&lt;br /&gt;  private final EnergySource energySource;&lt;br /&gt;&lt;br /&gt;  DeLorean(TimeCircuits timeCircuits, &lt;br /&gt;      FluxCapacitor fluxCapacitor,&lt;br /&gt;      EnergySource energySource) {&lt;br /&gt;    this.timeCircuits = timeCircuits;&lt;br /&gt;    this.fluxCapacitor = fluxCapacitor;&lt;br /&gt;    this.energySource = energySource;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  static class Factory {&lt;br /&gt;    @Inject TimeCircuits timeCircuits;&lt;br /&gt;    @Inject FluxCapacitor fluxCapacitor;&lt;br /&gt;      &lt;br /&gt;    DeLorean create(EnergySource energySource) {&lt;br /&gt;      return new DeLorean(timeCircuits, fluxCapacitor, energySource);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This works for our &lt;i&gt;specific&lt;/i&gt; problem, but in general it's quite awkward:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;It requires a gross amount of boilerplate code.&lt;li&gt;It discourages refactoring of the &lt;code&gt;DeLorean&lt;/code&gt; class. &lt;li&gt;It increases the complexity of getting an &lt;code&gt;EnergySource&lt;/code&gt;.&lt;li&gt;It doesn't work unless &lt;code&gt;EnergySource&lt;/code&gt; is a &lt;i&gt;direct&lt;/i&gt; dependency of the &lt;code&gt;DeLorean&lt;/code&gt; class. Otherwise you need to create lots of little factories that cascade. &lt;li&gt;And &lt;code&gt;EnergySource&lt;/code&gt; is no longer &lt;i&gt;in-the-club&lt;/i&gt;—it doesn't participate in Guice's injection, AOP, scoping, etc.&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Option two: AssistedInject&lt;/h3&gt;&lt;br /&gt;&lt;a href="http://publicobject.com/2007/06/assistedinject-easier-way-to-help-guice.html"&gt;AssistedInject&lt;/a&gt; is a Guice extension that's intended to reduce the boilerplate of option one. Instead of a factory class, we write a factory interface plus annotations:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;class DeLorean {&lt;br /&gt;  TimeCircuits timeCircuits;&lt;br /&gt;  FluxCapacitor fluxCapacitor;&lt;br /&gt;  EnergySource energySource;&lt;br /&gt;&lt;br /&gt;  @AssistedInject&lt;br /&gt;  DeLorean(TimeCircuits timeCircuits, &lt;br /&gt;      FluxCapacitor fluxCapacitor, &lt;br /&gt;      @Assisted EnergySource energySource) {&lt;br /&gt;    this.timeCircuits = timeCircuits;&lt;br /&gt;    this.fluxCapacitor = fluxCapacitor;&lt;br /&gt;    this.energySource = energySource;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  interface Factory {&lt;br /&gt;    DeLorean create(EnergySource energySource);&lt;br /&gt;  }&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This fixes some problems. But the core issue still remains: getting an instance of &lt;code&gt;EnergySource&lt;/code&gt; is difficult. Unlike regular Guice (&lt;code&gt;@Inject&lt;/code&gt; is the new &lt;code&gt;new&lt;/code&gt;), you need to change all callers if you add a dependency on &lt;code&gt;EnergySource&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Option three: Hierarchical Injectors&lt;/h3&gt;&lt;br /&gt;The premise is simple. &lt;code&gt;@Inject&lt;/code&gt; anything, even stuff you don't know at injector-creation time. So our &lt;code&gt;DeLorean&lt;/code&gt; class would look exactly as it would if &lt;code&gt;EnergySource&lt;/code&gt; was constant:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;class DeLorean {&lt;br /&gt;  TimeCircuits timeCircuits;&lt;br /&gt;  FluxCapacitor fluxCapacitor;&lt;br /&gt;  EnergySource energySource;&lt;br /&gt;&lt;br /&gt;  @Inject&lt;br /&gt;  DeLorean(TimeCircuits timeCircuits,&lt;br /&gt;      FluxCapacitor fluxCapacitor,&lt;br /&gt;      EnergySource energySource) {&lt;br /&gt;    this.timeCircuits = timeCircuits;&lt;br /&gt;    this.fluxCapacitor = fluxCapacitor;&lt;br /&gt;    this.energySource = energySource;&lt;br /&gt;  }&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;To use it, we start with an &lt;code&gt;Injector&lt;/code&gt; that had bindings for everything &lt;i&gt;except&lt;/i&gt; for &lt;code&gt;EnergySource&lt;/code&gt;. Next, we create a second injector that extends the first, and binds either &lt;code&gt;Plutonium&lt;/code&gt; or &lt;code&gt;LightningBolt&lt;/code&gt;. This second injector fills in its missing binding. &lt;br /&gt;&lt;br /&gt;The injectors share singletons, so we don't have to worry about having multiple &lt;code&gt;TimeCircuits&lt;/code&gt;. Static analysis is applied to both injectors as a whole, where complete information is known. And all objects are &lt;i&gt;in-the-club&lt;/i&gt; and get Guice value-adds like injection, scoping and AOP.&lt;br /&gt;&lt;br /&gt;This is the solution to the mystical &lt;a href="http://groups.google.com/group/google-guice/browse_frm/thread/600bc14714d356c9/2822fc80816cd04d?#2822fc80816cd04d"&gt;Robot Legs problem&lt;/a&gt;, wherein we have a &lt;code&gt;RobotLeg&lt;/code&gt; class, that needs be injected with either a &lt;code&gt;LeftFoot&lt;/code&gt; or a &lt;code&gt;RightFoot&lt;/code&gt;, depending on where the leg will ultimately be used.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Criticism of Hierarchical Injectors&lt;/h3&gt;&lt;br /&gt;&lt;strong&gt;They suggest competing bindings.&lt;/strong&gt; One &lt;i&gt;parent&lt;/i&gt; injector could have relations with multiple &lt;i&gt;child&lt;/i&gt; injectors. In our example, the parent injector binds &lt;code&gt;DeLorean&lt;/code&gt; and &lt;code&gt;TimeCircuits&lt;/code&gt;, and each child binds a different &lt;code&gt;EnergySource&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;They require abstract Injectors.&lt;/strong&gt; The parent injector in our example wouldn't be able to create an instance of &lt;code&gt;DeLorean&lt;/code&gt;, since it doesn't have all of the prerequisite bindings. This is just weird.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;They're complex.&lt;/strong&gt; Guice was born out of making code simpler. Does the conceptual weight of hierarchical injectors justify their inclusion?&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Going forward&lt;/h3&gt;&lt;br /&gt;Today's Guice includes a simplified implementation of hierarchical injectors written by Dan Halem. It doesn't cover the interesting (but complex) case where the parent injector cannot fulfill all of its bindings. I'm studying the use cases, trying to come up with a balance between ease-of-use and power.&lt;br /&gt;&lt;br /&gt;For example, one idea is to require users to explicitly call-out bindings that child injectors will provide:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;  public void configure() {&lt;br /&gt;    bind(EnergySource.class).throughChildInjector();&lt;br /&gt;  }&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;I'd also like to do something similar to AssistedInject's factory interfaces. This way the second injector would be created, used and discarded transparently, so the user never needs to see it. From the user's perspective, this would just be like AssistedInject, but the assisted parameters could be injected anywhere.&lt;br /&gt;&lt;br /&gt;If you have suggested use-cases or ideas, I'd love to hear 'em.</content><link rel='alternate' type='text/html' href='http://publicobject.com/2008/06/whats-hierarchical-injector.html' title='What&apos;s a Hierarchical Injector?'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8675640&amp;postID=1209946180331059090' title='1 Comments'/><link rel='replies' type='application/atom+xml' href='http://publicobject.com/publicobject/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/1209946180331059090'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/1209946180331059090'/><author><name>swankjesse</name><uri>http://www.blogger.com/profile/04905794974441087900</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8675640.post-6690264725903957111</id><published>2008-06-23T09:48:00.000-07:00</published><updated>2008-06-23T10:19:03.599-07:00</updated><title type='text'>Wanted: Guice Injector Graphing</title><content type='html'>One of the nice new features of Guice 2.0 is the new introspection API. It's the equivalent of &lt;code&gt;java.lang.reflect&lt;/code&gt; for Guice - it lets you inspect your application at runtime. Our goal is to make it easy to write rich tools for Guice. A natural use case is visualizing an application. The right graph can reveal the structure of your application. I've opened a feature request for this, &lt;a href="http://code.google.com/p/google-guice/issues/detail?id=213"&gt;Issue 213&lt;/a&gt;. I created a proof-of-concept to drum-up excitement for this idea.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Example Graph: Application Code&lt;/h3&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;class DeLorean {&lt;br /&gt;  @Inject TimeCircuits timeCircuits;&lt;br /&gt;  @Inject FluxCapacitor fluxCapacitor;&lt;br /&gt;  @Inject EnergySource energySource;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class FluxCapacitor {&lt;br /&gt;  @Inject TimeCircuits timeCircuits;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class TimeCircuits {&lt;br /&gt;  Date whereYouveBeen;&lt;br /&gt;  Date whereYouAre;&lt;br /&gt;  Date whereYourGoing;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;interface EnergySource {&lt;br /&gt;  String generateOnePointTwentyOneGigawatts();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class Plutonium implements EnergySource {&lt;br /&gt;  public String generateOnePointTwentyOneGigawatts() {&lt;br /&gt;    return "newk-you-ler";&lt;br /&gt;  }&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt; Example Graph: Guice Configuration&lt;/h3&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;    Injector injector = Guice.createInjector(new AbstractModule() {&lt;br /&gt;      protected void configure() {&lt;br /&gt;        bind(EnergySource.class).to(Plutonium.class);&lt;br /&gt;        bind(FluxCapacitor.class);&lt;br /&gt;        bind(DeLorean.class);&lt;br /&gt;      }&lt;br /&gt;    });&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;.dot File&lt;/h3&gt;&lt;br /&gt;My &lt;code&gt;Grapher&lt;/code&gt; code takes the above Injector and outputs a &lt;code&gt;.dot&lt;/code&gt; file that describes a graph:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;digraph injector {&lt;br /&gt;  "FluxCapacitor" -&gt; "FluxCapacitor.&lt;init&gt;()" [arrowhead=onormal];&lt;br /&gt;  "FluxCapacitor" -&gt; "TimeCircuits" [label=timeCircuits]&lt;br /&gt;  "DeLorean" -&gt; "DeLorean.&lt;init&gt;()" [arrowhead=onormal];&lt;br /&gt;  "DeLorean" -&gt; "TimeCircuits" [label=timeCircuits]&lt;br /&gt;  "DeLorean" -&gt; "FluxCapacitor" [label=fluxCapacitor]&lt;br /&gt;  "DeLorean" -&gt; "EnergySource" [label=energySource]&lt;br /&gt;  "EnergySource" -&gt; "Plutonium" [arrowhead=onormal];&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The Rendered Graph&lt;/h3&gt;&lt;br /&gt;Finally, &lt;a href="http://www.graphviz.org/"&gt;Graphviz&lt;/a&gt; renders the &lt;code&gt;.dot&lt;/code&gt; file to a pretty picture:&lt;br /&gt;&lt;blockquote align="center"&gt;&lt;a href="http://publicobject.com/uploaded_images/Picture-3-726367.png"&gt;&lt;img  src="/uploaded_images/Picture-3-726360.png" /&gt;&lt;/a&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;This graph is a good start, but there's a long way to go. Unfortunately, I don't have the bandwidth to take this project to completion and am seeking a contributor. If you're interested, post a note on &lt;a href="http://code.google.com/p/google-guice/issues/detail?id=213"&gt;the issue&lt;/a&gt;. Coding is its own reward!</content><link rel='alternate' type='text/html' href='http://publicobject.com/2008/06/wanted-guice-injector-graphing.html' title='Wanted: Guice Injector Graphing'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8675640&amp;postID=6690264725903957111' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://publicobject.com/publicobject/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/6690264725903957111'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/6690264725903957111'/><author><name>swankjesse</name><uri>http://www.blogger.com/profile/04905794974441087900</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8675640.post-923703536111537903</id><published>2008-06-01T13:24:00.000-07:00</published><updated>2008-06-01T14:00:21.604-07:00</updated><title type='text'>Integer.class and int.class as Guice Keys</title><content type='html'>Shortly after &lt;a href="http://groups.google.com/group/google-guice-dev/browse_frm/thread/2fd453aecc6c3590"&gt;fixing arrays&lt;/a&gt;, I've found another &lt;a href="http://publicobject.com/2008/05/bug-pattern-multiple-ways-to-represent.html"&gt;multiple representations&lt;/a&gt; bug. This problem is probably familiar - I'm confusing primitive types (like &lt;code&gt;int&lt;/code&gt;) with wrapper types (like &lt;code&gt;Integer&lt;/code&gt;).&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;It's one binding&lt;/h3&gt;&lt;br /&gt;The critical question: should these tests pass?&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;    assertEquals(Key.get(int.class), Key.get(Integer.class));&lt;br /&gt;    assertEquals(TypeLiteral.get(int.class), TypeLiteral.get(Integer.class));&lt;/code&gt;&lt;/pre&gt;Currently these are non-equal, so Guice has special cases so that they both work. But some special cases are missing! Consider issue &lt;a href="http://code.google.com/p/google-guice/issues/detail?id=116"&gt;116&lt;/a&gt;:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;    Injector injector = Guice.createInjector(new AbstractModule() {&lt;br /&gt;      protected void configure() {&lt;br /&gt;        bind(injector.class).toInstance(1984);&lt;br /&gt;      }&lt;br /&gt;    });&lt;br /&gt;    assertEquals(1984, (int) injector.getInstance(int.class)); /* passes */&lt;br /&gt;    assertEquals(1984, (int) injector.getInstance(Integer.class)); /* passes */&lt;br /&gt;    assertEquals(1984, (int) injector.getInstance(Key.get(int.class)));  /* passes */&lt;br /&gt;    assertEquals(1984, (int) injector.getInstance(Key.get(Integer.class)));  /* passes */&lt;br /&gt;    assertNotNull(injector.getBinding(Key.get(int.class)));  /* passes */&lt;br /&gt;    assertNotNull(injector.getBinding(Key.get(Integer.class))); &lt;strong&gt;/* fails! */&lt;/strong&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt;Should Key be fixed?&lt;/h3&gt;&lt;br /&gt;&lt;strong&gt;Yes.&lt;/strong&gt; I think I'll change &lt;code&gt;Key&lt;/code&gt; so that it always uses &lt;code&gt;Integer.class&lt;/code&gt;, regardless of whether it was created with &lt;code&gt;int.class&lt;/code&gt; or &lt;code&gt;Integer.class&lt;/code&gt;. Otherwise, this stuff is just too prone to bugs. For example, our new Binder SPI can return &lt;i&gt;Provider&amp;lt;int&amp;gt;&lt;/i&gt;, even though that's not a valid type.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Should TypeLiteral be fixed?&lt;/h3&gt;&lt;br /&gt;&lt;strong&gt;Probably not.&lt;/strong&gt; I'm leaning towards leaving it as-is. Consider an interface with these methods:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;    public boolean remove(Integer value)&lt;br /&gt;    public Integer remove(int index);&lt;/code&gt;&lt;/pre&gt;If I change &lt;code&gt;TypeLiteral&lt;/code&gt;, then the "remove" method is ambiguous when I know the &lt;code&gt;TypeLiteral&lt;/code&gt; of the parameter type. But as a side effect of being inconsistent with &lt;code&gt;Key&lt;/code&gt;, this test will always fail:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;  TypeLiteral&amp;lt;Integer&amp;gt; primitive = TypeLiteral.get(int.class);&lt;br /&gt;  TypeLiteral&amp;lt;Integer&amp;gt; wrapper = new TypeLiteral&amp;lt;Integer&amp;gt;() {};&lt;br /&gt;  assertEquals(Key.get(primitive), Key.get(wrapper));&lt;br /&gt;  assertEquals(primitive, wrapper);&lt;/code&gt;&lt;/pre&gt;I think it's a fair compromise.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Fixing the right thing&lt;/h3&gt;&lt;br /&gt;By making my changes to &lt;code&gt;Key&lt;/code&gt; and &lt;code&gt;TypeLiteral&lt;/code&gt;, I can make Guice behave consistently throughout all of its APIs. I won't have to worry about users who bind both &lt;code&gt;int.class&lt;/code&gt; and &lt;code&gt;Integer.class&lt;/code&gt;. And I should be able to rip out some special cases both Guice and its extensions. &lt;br /&gt;&lt;br /&gt;If there's a &lt;a href="http://code.google.com/p/google-guice/issues/list"&gt;Guice issue&lt;/a&gt; that's you'd like fixed, this is a great time to get your feelings heard. I'm spending a lot of time on the issues list, trying to decide what will make the cut for 2.0.</content><link rel='alternate' type='text/html' href='http://publicobject.com/2008/06/integerclass-and-intclass-as-guice-keys.html' title='Integer.class and int.class as Guice Keys'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8675640&amp;postID=923703536111537903' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://publicobject.com/publicobject/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/923703536111537903'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/923703536111537903'/><author><name>swankjesse</name><uri>http://www.blogger.com/profile/04905794974441087900</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8675640.post-2639311360300069295</id><published>2008-05-30T01:23:00.000-07:00</published><updated>2008-06-01T01:44:25.521-07:00</updated><title type='text'>Wanted: javax.interceptor extension for Guice</title><content type='html'>I'm feverishly preparing Guice for the 2.0 release later this summer, and tonight I scanned through our &lt;a href="http://code.google.com/p/google-guice/issues/list"&gt;issues list&lt;/a&gt;. There's a whole bunch of good features that I won't get to before our release. So I'm looking for Guice users to help out with development!&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Introducing javax.interceptor&lt;/h3&gt;&lt;br /&gt;&lt;a href="http://java.sun.com/javaee/5/docs/api/javax/interceptor/package-summary.html"&gt;javax.interceptor&lt;/a&gt; is a fairly-simple method interception package for modern Enterprise Java stacks. These &lt;a href="http://edocs.bea.com/wls/docs100/ejb30/examples.html"&gt;examples&lt;/a&gt; show how it works. Create a class with an &lt;code&gt;@Interceptors&lt;/code&gt; annotation:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;@Interceptors(AuditInterceptor.class)&lt;br /&gt;public class AccountBean implements Account {&lt;br /&gt;  private int balance = 0;&lt;br /&gt;&lt;br /&gt;  public void deposit(int amount) {&lt;br /&gt;    balance += amount;&lt;br /&gt;  }&lt;br /&gt;  public void withdraw(int amount) {&lt;br /&gt;    balance -= amount;&lt;br /&gt;  }&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;Then create the interceptor:&lt;pre class="prettyprint"&gt;&lt;code&gt;public class AuditInterceptor {&lt;br /&gt;  @AroundInvoke&lt;br /&gt;  public Object audit(InvocationContext invocationContext) throws Exception {&lt;br /&gt;    System.out.println("Invoking method: " + invocationContext.getMethod());&lt;br /&gt;    return invocationContext.proceed();&lt;br /&gt;  }&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;If everything works as intended, the interceptor's &lt;code&gt;audit()&lt;/code&gt; method will intercept all calls to &lt;code&gt;deposit()&lt;/code&gt; and &lt;code&gt;withdraw()&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Guice's MethodInterceptor&lt;/h3&gt;&lt;br /&gt;Guice has another API for this, &lt;a href="http://aopalliance.sourceforge.net/doc/org/aopalliance/intercept/MethodInterceptor.html"&gt;MethodInterceptor&lt;/a&gt;. Guice uses &lt;a href="http://google-guice.googlecode.com/svn/trunk/javadoc/com/google/inject/matcher/Matchers.html"&gt;Matchers&lt;/a&gt; to support arbitrary selection of interceptable methods. &lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Wanted: an Extension for javax.interceptor&lt;/h3&gt;&lt;br /&gt;I believe this feature could be implemented as an extension to Guice. The extension would certainly require some &lt;a href="http://publicobject.com/2008/05/elite-guice-3-private-bindings.html"&gt;clever tricks&lt;/a&gt;, but it should not require changes to the Guice internals. Here's what I guess the implementation could look like:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;public class JavaxInterceptorModule extends AbstractModule {&lt;br /&gt;  public void configure() {&lt;br /&gt;    JavaxInterceptor interceptor = new JavaxInterceptor();&lt;br /&gt;    injectMembers(interceptor);&lt;br /&gt;    bindInterceptor(Matchers,any(), new InterceptMethodsMatcher(), interceptor);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  static class JavaxInterceptor {&lt;br /&gt;    /**&lt;br /&gt;     * Loop over all the injector's bindings, looking for @Interceptor. &lt;br /&gt;     * Then verify that the interceptor classes are either injectable (ie.&lt;br /&gt;     * they have bindings), or they have a no-arg constructor. This&lt;br /&gt;     * isn't strictly necessary, but it allows us to fail faster, which is&lt;br /&gt;      * always a Guicy thing to do.&lt;br /&gt;     */&lt;br /&gt;    @Inject void initialize(Injector injector) { ... }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Validate that the target method is intercepted. We need to&lt;br /&gt;     * consider just-in-time bindings that might not have been&lt;br /&gt;     * checked during initialize(). We also need to check for the&lt;br /&gt;     * ExcludeClassInterceptors etc. annotations.&lt;br /&gt;     *&lt;br /&gt;     * &amp;lt;p&amp;gt;Instantiate all of the injectors for this method, then&lt;br /&gt;     * run 'em. We'll need our own implementation of &lt;a href="http://java.sun.com/javaee/5/docs/api/javax/interceptor/InvocationContext.html"&gt;InvocationContext&lt;/a&gt; &lt;br /&gt;     * to pass to the interceptors.&lt;br /&gt;     */&lt;br /&gt;    Object invoke(MethodInvocation invocation) { ... }&lt;br /&gt;  }&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Of course it's not this simple. The implementation needs be tested to be consistent with the Java EE implementations. It needs to have reasonable error handing. And there's nuances related to inheritance etc. It also needs thorough unit tests.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Recruiting Contributors&lt;/h3&gt;&lt;br /&gt;Does writing this code sound fun to you? If it does, we'd love your help. Post your interest on &lt;a href="http://code.google.com/p/google-guice/issues/detail?id=61"&gt;the bug&lt;/a&gt;! You'll need to &lt;a href="http://code.google.com/p/google-guice/source/checkout"&gt;checkout&lt;/a&gt; the Guice code, write the code and tests, and upload a patch. I'll code review the patch (a fairly involved process) and we'll iterate until it's perfect.&lt;br /&gt;&lt;br /&gt;In return, you'll get to see your &lt;code&gt;@author&lt;/code&gt; line in the Guice source code. You'll probably learn a lot about AOP, Guice and reflection. It's resume padding. And of course, coding is its own reward.</content><link rel='alternate' type='text/html' href='http://publicobject.com/2008/05/wanted-javaxinterceptor-extension-for.html' title='Wanted: javax.interceptor extension for Guice'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8675640&amp;postID=2639311360300069295' title='3 Comments'/><link rel='replies' type='application/atom+xml' href='http://publicobject.com/publicobject/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/2639311360300069295'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/2639311360300069295'/><author><name>swankjesse</name><uri>http://www.blogger.com/profile/04905794974441087900</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8675640.post-2208462706495329614</id><published>2008-05-28T02:28:00.001-07:00</published><updated>2008-05-28T03:31:40.996-07:00</updated><title type='text'>Bug pattern: multiple ways to represent the same data</title><content type='html'>There's a class of bugs that come up when one logical datatypes has representations in multiple classes. The best example of this is &lt;code&gt;1&lt;/code&gt; vs. &lt;code&gt;1L&lt;/code&gt;. Both ones represent the same data. But &lt;code&gt;new Integer(1)&lt;/code&gt; is not equal to &lt;code&gt;new Long(1)&lt;/code&gt; according to the corresponding equals() methods.&lt;br /&gt;&lt;br /&gt;Calling &lt;code&gt;contains(1)&lt;/code&gt; on a &lt;code&gt;List&amp;lt;Long&amp;gt;&lt;/code&gt; compiles just fine, it just won't ever return true. Similarly for &lt;code&gt;Map.get()&lt;/code&gt; and &lt;code&gt;Set.contains()&lt;/code&gt;. Anything that depends on &lt;code&gt;equals()&lt;/code&gt; is broken if you mix different types to express 'one'.&lt;br /&gt;&lt;br /&gt;The problem is that each defines an equals method that is local to its class. This is a fair design - but as a consequence these types should not be mixed.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;A short catalog of tricky types&lt;/h3&gt;&lt;br /&gt;...that can cause you pain if you mix them. These types can all represent the same logical value. But if you mix them, you will certainly get burned:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;"0" : Byte, Short, Integer, Long&lt;/li&gt;&lt;li&gt;"0.0" : Float, Double&lt;/li&gt;&lt;li&gt;"Jan 1, 1970 12:00.00am UTC" : Date, long, Calendar&lt;/li&gt;&lt;li&gt;"http://publicobject.com" : URI, URL&lt;/li&gt;&lt;li&gt;"integer type" : int.class, Integer.class&lt;/li&gt;&lt;li&gt;"ABC" : StringBuffer, StringBuilder, CharSequence, String&lt;/li&gt;&lt;li&gt;"natural order" : Comparators.naturalOrder(), null&lt;/li&gt;&lt;li&gt;"String[].class" : GenericArrayType, Class (both of which implement Type)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;A shorter catalog of good types&lt;/h3&gt;&lt;br /&gt;Fortunately, in a few places the JDK has interfaces that dictate how &lt;code&gt;equals&lt;/code&gt; and &lt;code&gt;hashCode&lt;/code&gt; must be implemented. As a consequence, you can freely intermix these types without consequence:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Sets: HashSet, LinkedHashSet, TreeSet&lt;/li&gt;&lt;li&gt;Maps: ConcurrentHashMap, HashMap, Collections.emptyMap()&lt;/li&gt;&lt;li&gt;Lists: ArrayList, LinkedList, Vector, Arrays.asList&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Defining this behaviour for interfaces is somewhat difficult - use these classes as a guide. All implementations must implement the spec exactly or behaviour will be unreliable.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Recommendations&lt;/h3&gt;&lt;br /&gt;Avoid creating classes that allow one logical datatype to be represented by different classes. If you must, consider writing an interface to specify equals and hashCode at that level.&lt;br /&gt;&lt;br /&gt;Choose a preferred, canonical form for your data. For example, if you consider 'null' and 'empty string' to be equal, choose one form and stick to it. Throw IllegalArgumentExceptions to callers that use the wrong one. If you're using collections, always use the canonical type for inserts and lookups.&lt;br /&gt;&lt;br /&gt;Use an smart IDE like &lt;a href="http://www.jetbrains.com/idea/"&gt;IntelliJ IDEA&lt;/a&gt;. It'll warn you when you mix types.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;An Aside...&lt;/h3&gt;&lt;br /&gt;It turns out that Guice 1.0 suffered an ugly bug because of this problem. You can represent arrays in two different ways using Java 5's Types API. Either as an instance of &lt;code&gt;Class&lt;/code&gt; or as an instance of &lt;code&gt;GenericArrayType&lt;/code&gt;. The two are equivalent but not equals(). As a consequence, some injections would incorrectly fail with 'missing bindings' exceptions.</content><link rel='alternate' type='text/html' href='http://publicobject.com/2008/05/bug-pattern-multiple-ways-to-represent.html' title='Bug pattern: multiple ways to represent the same data'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8675640&amp;postID=2208462706495329614' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://publicobject.com/publicobject/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/2208462706495329614'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/2208462706495329614'/><author><name>swankjesse</name><uri>http://www.blogger.com/profile/04905794974441087900</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8675640.post-535659783888615307</id><published>2008-05-28T02:01:00.001-07:00</published><updated>2008-05-28T02:05:52.757-07:00</updated><title type='text'>Guice talk, tomorrow morning at Google I/O</title><content type='html'>&lt;a href="http://crazybob.org"&gt;Bob&lt;/a&gt; and I are giving a talk at Google's developer conference tomorrow. From the &lt;a href="http://code.google.com/events/io/sessions.html"&gt;session summary&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt;Wed 11:15am - 12:15pm&lt;br /&gt;Bob Lee, Jesse Wilson&lt;br /&gt;&lt;br /&gt;Guice (pronounced 'juice') is a Jolt award-winnning, lightweight dependency injection framework for Java 5 and above. Put simply, Guice alleviates the need for factories and the use of new in your Java code. Think of Guice's @Inject as the new new. You will still need to write factories in some cases, but your code will not depend directly on them. Your code will be easier to change, unit test and reuse in other contexts.&lt;/blockquote&gt;</content><link rel='alternate' type='text/html' href='http://publicobject.com/2008/05/guice-talk-tomorrow-morning-at-google.html' title='Guice talk, tomorrow morning at Google I/O'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8675640&amp;postID=535659783888615307' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://publicobject.com/publicobject/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/535659783888615307'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/535659783888615307'/><author><name>swankjesse</name><uri>http://www.blogger.com/profile/04905794974441087900</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8675640.post-3254004990311661413</id><published>2008-05-22T22:46:00.000-07:00</published><updated>2008-05-22T23:31:55.650-07:00</updated><title type='text'>Calling a method that always throws</title><content type='html'>Kasper &lt;a href="http://firstclassthoughts.co.uk/java/java_type_system_missing_throws_methods.html"&gt;complains&lt;/a&gt; that it's hard to call methods that always throw. In particular, code like this won't compile because &lt;code&gt;findGetter&lt;/code&gt; is missing a return statement:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;  public Method findGetter() throws CsvException {&lt;br /&gt;    try {&lt;br /&gt;      return type.getMethod("get" &lt;br /&gt;        + fieldName.substring(0, 1).toUpperCase() &lt;br /&gt;        + fieldName.substring(1));&lt;br /&gt;    } catch(SecurityException e) {&lt;br /&gt;      noSuchGetter(e);&lt;br /&gt;    } catch (NoSuchMethodException e) {&lt;br /&gt;      noSuchGetter(e);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public void noSuchGetter(Exception cause) throws CsvException {&lt;br /&gt;    String message = String.format("Unable to lookup getter" &lt;br /&gt;        + " for field %s on %s", fieldName, type.getName());&lt;br /&gt;    throw new CsvException(message, cause);&lt;br /&gt;  }&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The problem is that &lt;code&gt;noSuchGetter&lt;/code&gt; always throws, but javac doesn't consider that when building this code. Making that method &lt;code&gt;private&lt;/code&gt; or &lt;code&gt;final&lt;/code&gt; doesn't help -- javac does not look at the body of a method when deciding whether the callers are valid. &lt;br /&gt;&lt;br /&gt;Adding &lt;code&gt;return null;&lt;/code&gt; to the end of this method appeases the compiler, but it sure isn't pretty:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;  public Method findGetter() throws CsvException {&lt;br /&gt;    try {&lt;br /&gt;      return type.getMethod("get" &lt;br /&gt;        + fieldName.substring(0, 1).toUpperCase() &lt;br /&gt;        + fieldName.substring(1));&lt;br /&gt;    } catch(SecurityException e) {&lt;br /&gt;      noSuchGetter(e);&lt;br /&gt;    } catch (NoSuchMethodException e) {&lt;br /&gt;      noSuchGetter(e);&lt;br /&gt;    }&lt;br /&gt;    &lt;strong&gt;return null; /* never executes! (this method never returns null.) */&lt;/strong&gt;&lt;br /&gt;  }&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;As Kasper explains, this workaround sucks! In particular, it suggests to the code reader that he should check for null when calling this method. We need to add a big ugly comment to flag what's going on. Another workaround is to throw &lt;code&gt;AssertionError&lt;/code&gt;s on unreachable lines. This is an improvement but we still have dead code in our program. This line won't ever execute, adding noise to &lt;a href="http://emma.sourceforge.net/"&gt;code coverage&lt;/a&gt; reports.&lt;br /&gt;&lt;br /&gt;Fortunately, there's a clever fix. Declare that &lt;code&gt;noSuchGetter&lt;/code&gt; returns a &lt;code&gt;RuntimeException&lt;/code&gt; and prefix call to it with &lt;code&gt;throw&lt;/code&gt;:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;  public Method findGetter() throws CsvException {&lt;br /&gt;    try {&lt;br /&gt;      return type.getMethod("get" &lt;br /&gt;        + fieldName.substring(0, 1).toUpperCase() &lt;br /&gt;        + fieldName.substring(1));&lt;br /&gt;    } catch(SecurityException e) {&lt;br /&gt;      &lt;strong&gt;throw&lt;/strong&gt; noSuchGetter(e);&lt;br /&gt;    } catch (NoSuchMethodException e) {&lt;br /&gt;      &lt;strong&gt;throw&lt;/strong&gt; noSuchGetter(e);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public &lt;strong&gt;CsvException&lt;/strong&gt; noSuchGetter(Exception cause) &lt;br /&gt;      throws CsvException {&lt;br /&gt;    String message = String.format("Unable to lookup getter" &lt;br /&gt;        + " for field %s on %s", fieldName, type.getName());&lt;br /&gt;    throw new CsvException(message, cause);&lt;br /&gt;  }&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Now the code reader can see that the &lt;code&gt;noSuchGetter&lt;/code&gt; calls always throw without reading that method's body. And the compiler will complain if you add any code after that call. We can optionally tweak this so &lt;code&gt;noSuchGetter&lt;/code&gt; returns &lt;code&gt;CsvException&lt;/code&gt; rather than throwing it. &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Methods that always throw should return what they throw.&lt;/strong&gt; If the method always throws a &lt;code&gt;RuntimeException&lt;/code&gt;, we'd return that type.</content><link rel='alternate' type='text/html' href='http://publicobject.com/2008/05/calling-method-that-always-throws.html' title='Calling a method that always throws'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8675640&amp;postID=3254004990311661413' title='11 Comments'/><link rel='replies' type='application/atom+xml' href='http://publicobject.com/publicobject/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/3254004990311661413'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/3254004990311661413'/><author><name>swankjesse</name><uri>http://www.blogger.com/profile/04905794974441087900</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8675640.post-9006181373593067875</id><published>2008-05-17T19:45:00.000-07:00</published><updated>2008-05-17T20:46:25.284-07:00</updated><title type='text'>Overriding Bindings in Guice</title><content type='html'>In our functional tests, we prefer to launch an application that closely resembles the production one. This means using the production modules in a proper staging environment. Even with automating scripts, setting up the environment is time consuming and tedious - it requires database install and configuration, permissions, SSL certificates, and remote services to be running and available:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;public class ProductionModule extends AbstractModule {&lt;br /&gt;  protected void configure() {&lt;br /&gt;    bind(LoginService.class).to(RemoteLoginService.class);&lt;br /&gt;    bind(DataStore.class).to(MySqlDatabase.class);&lt;br /&gt;    bind(BillerConnection.class).to(SecureBillerConnection.class);&lt;br /&gt;    bind(LoggingEngine.class).to(DistributedLoggingEngine.class);&lt;br /&gt;  }&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Since proper functional tests are so labour intensive, we take shortcuts! We can make a decent approximation of production by replacing some production services with lightweight fakes. For example, all of our functional tests require a login server to authenticate users. But for most tests login isn't interesting and this is just a wasted effort. We'd rather just fake login for unrelated functional tests.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Modular Modules&lt;/h3&gt;&lt;br /&gt;The best solution to this problem is to split the login stuff into its own module:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;public class ProductionLoginModule extends AbstractModule {&lt;br /&gt;  protected void configure() {&lt;br /&gt;    bind(LoginService.class).to(RemoteLoginService.class);&lt;br /&gt;  }&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;In the functional test server we can use a &lt;code&gt;FakeLoginModule&lt;/code&gt; rather than the &lt;code&gt;ProductionLoginModule&lt;/code&gt;. It provides the same bindings, but its entirely in-memory and configuration free. This approach is simple, manageable and maintainable. It's the best way to mix production and test code.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Overrides via Inheritance&lt;/h3&gt;&lt;br /&gt;There's also a quick-and-dirty approach to creating test versions of servers. Extract each offending binding to its own method,  and override that method in a subclass:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;public class ProductionModule extends AbstractModule {&lt;br /&gt;  protected void configure() {&lt;br /&gt;    &lt;strong&gt;bindLoginService();&lt;/strong&gt;&lt;br /&gt;    bind(DataStore.class).to(MySqlDatabase.class);&lt;br /&gt;    bind(BillerConnection.class).to(SecureBillerConnection.class);&lt;br /&gt;    bind(LoggingEngine.class).to(DistributedLoggingEngine.class);&lt;br /&gt;  }&lt;br /&gt;  protected void bindLoginService() {&lt;br /&gt;    bind(LoginService.class).to(RemoteLoginService.class);&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class TestModule extends ProductionModule {&lt;br /&gt;  @Override protected void bindLoginService() {&lt;br /&gt;    bind(LoginService.class).to(FakeLoginService.class);&lt;br /&gt;  }&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This does this trick, but it's not elegant. We end up with different subclasses for each combination of fake bindings. It's fragile and makes for more work to divide the module later.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;New: overrideModule&lt;/h3&gt;&lt;br /&gt;Sam Berlin has contributed a feature to Guice that provides a simple mechanism to replace bindings. To use it, we create a module with binding overrides:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;public class OverridesModule extends AbstractModule {&lt;br /&gt;  @Override protected void configure() {&lt;br /&gt;    bind(LoginService.class).to(FakeLoginService.class);&lt;br /&gt;  }&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;We can combine our original, unmodified &lt;code&gt;ProductionModule&lt;/code&gt; with the overrides to create a third module:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;    Module functionalTestModule &lt;br /&gt;        = Guice.overrideModule(new ProductionModule(), new OverridesModule());&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;In this example, we get the &lt;code&gt;DataStore&lt;/code&gt;, &lt;code&gt;BillerConnection&lt;/code&gt; and &lt;code&gt;LoggingEngine&lt;/code&gt; bindings from &lt;code&gt;ProductionModule&lt;/code&gt;, but the &lt;code&gt;FakeLoginService&lt;/code&gt; from &lt;code&gt;OverridesModule&lt;/code&gt;. The bindings in the overriding module replace bindings of the same key from the production module.&lt;br /&gt;&lt;br /&gt;It's not as clean as modular modules, but it is more convenient. In particular, this approach doesn't require changes to the production module - great if that's provided by another team or a third party. It's also handy for testing the module itself!&lt;br /&gt;&lt;br /&gt;This code is in SVN now if you're interested. It uses the new &lt;a href="http://publicobject.com/2008/02/guice-commands.html"&gt;commands API&lt;/a&gt; to get a lot done in a &lt;a href="http://code.google.com/p/google-guice/source/diff?r=486&amp;format=side&amp;path=/trunk/src/com/google/inject/Guice.java"&gt;small amount of code&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Fair Warning:&lt;/strong&gt; I've been blogging about a lot of new Guice APIs lately. &lt;strong&gt;These APIs aren't final.&lt;/strong&gt; If you depend on unreleased APIs from Guice svn, be aware that those APIs will probably change for 2.0.</content><link rel='alternate' type='text/html' href='http://publicobject.com/2008/05/overriding-bindings-in-guice.html' title='Overriding Bindings in Guice'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8675640&amp;postID=9006181373593067875' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://publicobject.com/publicobject/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/9006181373593067875'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/9006181373593067875'/><author><name>swankjesse</name><uri>http://www.blogger.com/profile/04905794974441087900</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8675640.post-7050895477055979654</id><published>2008-05-16T08:36:00.000-07:00</published><updated>2008-05-16T09:21:00.744-07:00</updated><title type='text'>MapBinder checked in!</title><content type='html'>Building out the &lt;a href="http://publicobject.com/2008/05/guice-multibindings-extension-checked.html"&gt;Multibindings&lt;/a&gt; extension, David P. Baker has written a new class that simplifies Map binding. &lt;code&gt;MapBinder&lt;/code&gt; uses an API that's consistent with &lt;code&gt;Multibinder&lt;/code&gt;:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;public class SnacksModule extends AbstractModule {&lt;br /&gt;  protected void configure() {&lt;br /&gt;    MapBinder&amp;lt;String, Snack&amp;gt; mapBinder&lt;br /&gt;        = MapBinder.newMapBinder(binder(), String.class, Snack.class);&lt;br /&gt;    mapBinder.addBinding("twix").toInstance(new Twix());&lt;br /&gt;    mapBinder.addBinding("snickers").toProvider(SnickersProvider.class);&lt;br /&gt;    mapBinder.addBinding("skittles").to(Skittles.class);&lt;br /&gt;  }&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt;Like Multibinder...&lt;/h3&gt;&lt;br /&gt;Keys must be non-null and unique. Values must be non-null. Values get resolved at injection-time, so they can be scoped. Bindings from different modules will be aggregated, which makes it usable for an application registry.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Unlike Multibinder...&lt;/h3&gt;&lt;br /&gt;For the example above, an extra binding is made for &lt;code&gt;Map&amp;lt;String, Provider&amp;lt;Snack&amp;gt;&amp;gt;&lt;/code&gt;. This makes it so that if values are expensive to provide, you can get just the ones you need. &lt;br /&gt;&lt;br /&gt;This API is available in Guice svn right now. &lt;strong&gt;The API is subject to change&lt;/strong&gt; before version 2. I suspect we'll probably rename &lt;code&gt;Multibinder&lt;/code&gt; to either &lt;code&gt;SetBinder&lt;/code&gt; or &lt;code&gt;MultiBinder&lt;/code&gt;. Any preferences?</content><link rel='alternate' type='text/html' href='http://publicobject.com/2008/05/mapbinder-checked-in.html' title='MapBinder checked in!'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8675640&amp;postID=7050895477055979654' title='3 Comments'/><link rel='replies' type='application/atom+xml' href='http://publicobject.com/publicobject/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/7050895477055979654'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/7050895477055979654'/><author><name>swankjesse</name><uri>http://www.blogger.com/profile/04905794974441087900</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8675640.post-5741474344149528317</id><published>2008-05-11T02:12:00.000-07:00</published><updated>2008-05-11T02:55:54.946-07:00</updated><title type='text'>Elite Guice 3: Private Bindings</title><content type='html'>In the &lt;a href="http://publicobject.com/2008/05/elite-guice-1-initialize-your-extension.html"&gt;first&lt;/a&gt;  and &lt;a href="http://publicobject.com/2008/05/elite-guice-2-binding-de-duplication.html"&gt;second&lt;/a&gt; parts of this series, I discussed hooks for extending Guice. In this post I introduce private bindings.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Don't emulate Guice&lt;/h3&gt;&lt;br /&gt;The key to a good extension is tight integration with Guice. In particular, the extension shouldn't copy functionality from Guice; doing so can lead to subtle differences between the extension and Guice itself.  The assisted inject extension reimplements constructor injection and that causes problems:&lt;ul&gt;&lt;li&gt;Standard Guice can inject private constructors, but I forgot to do configure this in assistedinject.&lt;/li&gt;&lt;li&gt;AOP doesn't work for assistedinject-created objects&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;These differences aren't dealbreakers, but they do make the extension harder to use, and they violate the principal of least surprise. A better assistedinject would have used Guice's constructor injection.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The Injector is just a bunch of bindings&lt;/h3&gt;&lt;br /&gt;In the &lt;a href="http://publicobject.com/2008/05/guice-multibindings-extension-checked.html"&gt;Multibindings&lt;/a&gt; extension, we secretly create a binding for each element in the set. These bindings are implementation details of the extension, but they need to be bound in the shared injector.&lt;br /&gt;&lt;br /&gt;We have to somehow create the bindings without a chance of conflicting with user-supplied bindings. If &lt;code&gt;Multibinder&lt;/code&gt; and the user both bound the same key, injector creation would fail. &lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Private Annotations to the rescue&lt;/h3&gt;&lt;br /&gt;The fix is to create a binding annotation type with a narrow scope, such as package scope. Other code won't have access to this  annotation, and therefore we can be confident that only our extension can create bindings with this annotation.&lt;br /&gt;&lt;br /&gt;In the Multibindings extension, there's a custom annotation called &lt;code&gt;@Element&lt;/code&gt; that's secretly applied to all elements. Each annotation instance is given a unique ID to ensure that the hosting keys are distinct. Unless they're using a tool that interrogates the Injector, the users of &lt;code&gt;Multibinder&lt;/code&gt; never see these bindings. They're created internally and used internally. But they allow all of Guice's features to work naturally on the bound elements. &lt;br /&gt;&lt;br /&gt;Implementing the annotation type is code-intensive, but there's &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/annotation/Annotation.html"&gt;thorough instructions&lt;/a&gt; that describe how equals, hashCode and even toString() should be implemented.&lt;br /&gt;&lt;br /&gt;This technique is also used in &lt;a href="http://code.google.com/p/google-guice/source/browse/trunk/extensions/commands/src/com/google/inject/commands/intercepting/InterceptingInjectorBuilder.java?r=405"&gt; InterceptingInjectorBuilder&lt;/a&gt;, in order to let &lt;a href="http://code.google.com/p/guiceberry/source/browse/trunk/src/com/google/inject/testing/guiceberry/InjectionController.java"&gt;InjectionController&lt;/a&gt; work its magic.</content><link rel='alternate' type='text/html' href='http://publicobject.com/2008/05/elite-guice-3-private-bindings.html' title='Elite Guice 3: Private Bindings'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8675640&amp;postID=5741474344149528317' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://publicobject.com/publicobject/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/5741474344149528317'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/5741474344149528317'/><author><name>swankjesse</name><uri>http://www.blogger.com/profile/04905794974441087900</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8675640.post-1771274275896798542</id><published>2008-05-07T08:37:00.000-07:00</published><updated>2008-05-07T08:56:04.367-07:00</updated><title type='text'>Why no Multibindings for Lists or Arrays?</title><content type='html'>The Multibindings code I &lt;a href="http://publicobject.com/2008/05/guice-multibindings-extension-checked.html"&gt;checked in&lt;/a&gt; last week has been well received. There's even a &lt;a href="http://users.telenet.be/robbiev/multibind/"&gt;screencast&lt;/a&gt; introducing the new code.&lt;br /&gt;&lt;br /&gt;But there are missing features. We're still figuring out exactly what's the right balance of functionality and simplicity. One particular omission is the lack of support for Lists and arrays.&lt;br /&gt;&lt;br /&gt;This is intentional. The deal breaker with Lists and arrays is that they imply an explicit order of their elements. But Multibinder has no idea how to order the elements. It could try to keep elements of the same module in the same order they were bound, but all bets are off when the bindings come from multiple modules. And it would be &lt;i&gt;very annoying&lt;/i&gt; if reordering your modules changed the behaviour of your program.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;But if you really want a List...&lt;/h3&gt;&lt;br /&gt;Its not to hard to make a List&amp;lt;String&amp;gt; binding using the Set&amp;lt;String&amp;gt; binding that &lt;code&gt;Multibinder&lt;/code&gt; gives you.&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;    bind(new TypeLiteral&amp;lt;List&amp;lt;String&amp;gt;&amp;gt;() {})&lt;br /&gt;      .to(new Provider&amp;lt;List&amp;lt;String&amp;gt;&amp;gt;() {&lt;br /&gt;            @Inject Provider&amp;lt;Set&amp;lt;String&amp;gt;&amp;gt; setProvider;&lt;br /&gt;&lt;br /&gt;            public List&amp;lt;String&amp;gt; get() {&lt;br /&gt;              /* if we wanted to, we could sort the list somehow */&lt;br /&gt;              return Collections.unmodifiableList(&lt;br /&gt;                 new ArrayList&amp;lt;String&amp;gt;(setProvider.get());&lt;br /&gt;            }&lt;br /&gt;          });&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Using this technique, you could also bind &lt;code&gt;Map&amp;lt;K, V&amp;gt;&lt;/code&gt; if you've got a binding to &lt;code&gt;Set&amp;lt;Map.Entry&amp;lt;K, V&amp;gt;&amp;gt;&lt;/code&gt;. We're thinking about adding built-in support for Maps, but this will work until we do.</content><link rel='alternate' type='text/html' href='http://publicobject.com/2008/05/why-no-multibindings-for-lists-or.html' title='Why no Multibindings for Lists or Arrays?'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8675640&amp;postID=1771274275896798542' title='1 Comments'/><link rel='replies' type='application/atom+xml' href='http://publicobject.com/publicobject/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/1771274275896798542'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/1771274275896798542'/><author><name>swankjesse</name><uri>http://www.blogger.com/profile/04905794974441087900</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8675640.post-7903399651503210423</id><published>2008-05-04T19:05:00.000-07:00</published><updated>2008-05-04T19:47:47.977-07:00</updated><title type='text'>Elite Guice 2: Binding de-duplication</title><content type='html'>In &lt;a href="http://publicobject.com/2008/05/elite-guice-1-initialize-your-extension.html"&gt;part one&lt;/a&gt;, I showed how to initialize a Guice extension using the &lt;code&gt;@Inject&lt;/code&gt; tag on a method. In this post I'm going to demonstrate a Guice for deduplicating bindings.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;What is binding duplication?&lt;/h3&gt;&lt;br /&gt;One of the features of the &lt;a href="http://publicobject.com/2008/05/guice-multibindings-extension-checked.html"&gt;Multibindings Extension&lt;/a&gt; is that there's no central coordination. Each module contributes its own bindings, and they all get amalgamated into a single collection. Suppose you have these modules:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;public class CandybarModule extends AbstractModule {&lt;br /&gt;  protected void configure() {&lt;br /&gt;    Multibinder&amp;lt;Snack&amp;gt; multibinder = Multibinder.newSetBinder(binder(), Snack.class);&lt;br /&gt;    multibinder.addBinding().toInstance(new Twix());&lt;br /&gt;    multibinder.addBinding().toProvider(SnickersProvider.class);&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;public class ChipsModule extends AbstractModule {&lt;br /&gt;  protected void configure() {&lt;br /&gt;    Multibinder&amp;lt;Snack&amp;gt; multibinder = Multibinder.newSetBinder(binder(), Snack.class);&lt;br /&gt;    multibinder.addBinding().to(Pringles.class);&lt;br /&gt;    multibinder.addBinding().toInstance(new Doritos());&lt;br /&gt;  }&lt;br /&gt;} &lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Out of this API, our &lt;code&gt;Multibinder&lt;/code&gt; implementation needs to bind &lt;code&gt;Set&amp;lt;Snack&amp;gt;&lt;/code&gt; exactly once. This is tricky! For example, suppose our &lt;code&gt;newSetBinder&lt;/code&gt; method was implemented like this:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;  public static &amp;lt;T&amp;gt; Multibinder&amp;lt;T&amp;gt; newSetBinder(Binder binder, Type type) {&lt;br /&gt;    binder.bind(getSetKey(type)).toProvider(getSetProvider(type));&lt;br /&gt;    return new Multibinder(type);&lt;br /&gt;  }&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This won't work. We call &lt;code&gt;newSetProvider&lt;/code&gt; from both the &lt;code&gt;CandybarModule&lt;/code&gt; and the &lt;code&gt;ChipsModule&lt;/code&gt;, and Guice complains because we're binding &lt;code&gt;Set&amp;lt;Snack&amp;gt;&lt;/code&gt; twice. This is binding duplication.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;If Guice had an duplicate-binding API&lt;/h3&gt;&lt;br /&gt;Guice doesn't have this API, but what we kind of find ourselves wanting is a way to query the binder for its bindings thus-far:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;  public static &amp;lt;T&amp;gt; Multibinder&amp;lt;T&amp;gt; newSetBinder(Binder binder, Type type) {&lt;br /&gt;    if (!binder.getBindings().containsKey(getSetKey(type))) {&lt;br /&gt;      binder.bind(getSetKey(type)).toProvider(getSetProvider(type));&lt;br /&gt;    }&lt;br /&gt;    return new Multibinder(type);&lt;br /&gt;  }&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This would work, but in general it's a pretty terrible idea. It makes it easy to write fragile modules - modules that depend on the order they are installed in. And it also changes the module from being static configuration (good!) to a dynamic-runtime configuration (bad!). So we're glad this API doesn't exist.&lt;br /&gt;&lt;br /&gt;But in this one case, we really wish we could prevent our binding from  being performed twice.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Modules as value objects&lt;/h3&gt;&lt;br /&gt;The solution to this problem is a bit surprising, but I think it's quite elegant. Guice conveniently allows the same &lt;i&gt;module&lt;/i&gt; to be installed twice. This is necessary so that both your &lt;code&gt;PizzaServletsModule&lt;/code&gt; and your &lt;code&gt;PizzaDatabaseModule&lt;/code&gt; can install your &lt;code&gt;PizzaDomainModule&lt;/code&gt;. &lt;br /&gt;&lt;br /&gt;Rather than binding the &lt;code&gt;Set&amp;lt;Snack&amp;gt;&lt;/code&gt; directly on the binder, we create special &lt;code&gt;Module&lt;/code&gt; class whose only job is to create that binding. And then we give that module a proper &lt;code&gt;equals()&lt;/code&gt; and &lt;code&gt;hashCode()&lt;/code&gt; methods, so that any two instances that bind the same type are equal.&lt;br /&gt;&lt;br /&gt;Our final code looks like this:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;  public static &amp;lt;T&amp;gt; Multibinder&amp;lt;T&amp;gt; newSetBinder(Binder binder, Type type) {&lt;br /&gt;    binder.install(new MultibindingModule(getSetType(), getProviderType()));&lt;br /&gt;    return new Multibinder(type);&lt;br /&gt;  }&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The &lt;code&gt;Module&lt;/code&gt; trick allows us to decentralize the binding. And that means less configuration code, and that means less code. Hooray for Guice.</content><link rel='alternate' type='text/html' href='http://publicobject.com/2008/05/elite-guice-2-binding-de-duplication.html' title='Elite Guice 2: Binding de-duplication'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8675640&amp;postID=7903399651503210423' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://publicobject.com/publicobject/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/7903399651503210423'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/7903399651503210423'/><author><name>swankjesse</name><uri>http://www.blogger.com/profile/04905794974441087900</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8675640.post-7186286460023931564</id><published>2008-05-01T07:59:00.000-07:00</published><updated>2008-05-01T08:52:02.589-07:00</updated><title type='text'>Elite Guice 1: Initialize your extension</title><content type='html'>I recently wrote some fairly, um, &lt;i&gt;extreme&lt;/i&gt; code for the Guice &lt;a href="http://publicobject.com/2008/05/guice-multibindings-extension-checked.html"&gt;Mutibindings&lt;/a&gt; extension. That code makes use of several tricks that you might find useful in your own Guice extensions. In this series I'm going to show-and-tell the various clever code tricks from &lt;a href="http://code.google.com/p/google-guice/source/browse/trunk/extensions/multibindings/src/com/google/inject/multibindings/Multibinder.java"&gt;Multibinder.java&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Initialize an extension&lt;/h3&gt;&lt;br /&gt;Guice doesn't have a plug-in API and it probably never will. But if it did, it would probably provide a mechanism for you to initialize your plugin:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;public interface GuicePlugin {&lt;br /&gt;  void initialize(Injector injector) throws ConfigurationException;&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This interface doesn't exist. But that's fine, because Guice does something better - it injects members into every bound instance and provider instance at injector-creation time. And where there is injection, there is initialization. There's two steps to getting Guice to call your initialize method:&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Bind an instance, or a provider instance.&lt;/strong&gt;&lt;br /&gt;Usually your extension is going to bind something anyway. Multibinder binds its &lt;code&gt;Set&lt;/code&gt;, AssistedInject binds its &lt;code&gt;Factory&lt;/code&gt;, ThrowingProviders binds its &lt;code&gt;ThrowingProvider&lt;/code&gt;. If you have absolutely nothing to bind, create a class and bind an instance of that.&lt;p&gt;You must bind either an instance, a provider instance, or an eager singleton. These are the only things that get injected at injector-creation time.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Create a &lt;code&gt;@Inject&lt;/code&gt; initialize() method on the bound instance.&lt;/strong&gt;&lt;br /&gt;This method gets called at injector-creation time. This is that important stage after all modules have been executed but before the Injector has been returned to its creator. Your initialize method can take any injectable objects as parameters - usually the Injector is a useful choice, since it allows your extension to review its complete set of bindings.&lt;p&gt;The method can also throw exceptions to indicate that it's improperly configured. Guice 1.0 has a bug where sometimes these exceptions don't halt injection. But recent snapshots have fixed this problem and you can now reliably use exceptions to fail if your extension is misconfigured. AssistedInject uses this feature to fail if your assisted constructor cannot be injected.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;h3&gt;Example&lt;/h3&gt;&lt;br /&gt;In &lt;code&gt;Multibinder.java&lt;/code&gt;, we bind a provider instance for the set:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;    public void configure(Binder binder) {&lt;br /&gt;      ...&lt;br /&gt;      binder.bind(setKey).toProvider(setProviderInstance);&lt;br /&gt;    }&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;That provider has our initialize() method. In this case, the initialize method loops through all of the injector's bindings, collecting providers for the elements of the collection:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;    /**&lt;br /&gt;     * Invoked by Guice at Injector-creation time to prepare providers for each&lt;br /&gt;     * element in this set. At this time the set's size is known, but its&lt;br /&gt;     * contents are only evaluated when get() is invoked.&lt;br /&gt;     */&lt;br /&gt;    @Inject void initialize(Injector injector) {&lt;br /&gt;      providers = new ArrayList&amp;lt;Provider&amp;lt;T&amp;gt;&amp;gt;();&lt;br /&gt;      for (Map.Entry&amp;lt;Key, Binding&amp;gt; entry : injector.getBindings().entrySet()) {&lt;br /&gt;        if (keyMatches(entry.getKey())) {&lt;br /&gt;          Binding&amp;lt;T&amp;gt; binding = (Binding&amp;lt;T&amp;gt;) entry.getValue();&lt;br /&gt;          providers.add(binding.getProvider());&lt;br /&gt;        }&lt;br /&gt;      }&lt;br /&gt;    }&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Hooray, our extension is initialized. In future posts I intend to discuss duplicate binding, private bindings, and perhaps annotation nesting.</content><link rel='alternate' type='text/html' href='http://publicobject.com/2008/05/elite-guice-1-initialize-your-extension.html' title='Elite Guice 1: Initialize your extension'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8675640&amp;postID=7186286460023931564' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://publicobject.com/publicobject/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/7186286460023931564'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/7186286460023931564'/><author><name>swankjesse</name><uri>http://www.blogger.com/profile/04905794974441087900</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8675640.post-2207362477321422810</id><published>2008-05-01T07:40:00.000-07:00</published><updated>2008-05-01T07:50:57.926-07:00</updated><title type='text'>Guice Multibindings extension checked in!</title><content type='html'>As previously alluded to, I've started work on the &lt;a href="http://code.google.com/p/google-guice/issues/detail?id=37"&gt;Multibindings&lt;/a&gt; API. I've checked in the initial implementation, and I'm pretty excited about it. You can grab it from &lt;a href="http://code.google.com/p/google-guice/source/browse/trunk/extensions/multibindings"&gt;svn&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;This feature is ideal for lightweight plugin-type architectures, where  you've got multiple modules each contributing Servlets, Actions, Filters, Components or even just names. &lt;br /&gt;&lt;br /&gt;The Multibinder Javadoc:&lt;br /&gt;&lt;br /&gt;An API to bind multiple values separately, only to later inject them as a complete collection. Multibinder is intended for use in your application's module:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;public class SnacksModule extends AbstractModule {&lt;br /&gt;  protected void configure() {&lt;br /&gt;    Multibinder&amp;lt;Snack&amp;gt; multibinder&lt;br /&gt;        = Multibinder.newSetBinder(binder(), Snack.class);&lt;br /&gt;    multibinder.addBinding().toInstance(new Twix());&lt;br /&gt;    multibinder.addBinding().toProvider(SnickersProvider.class);&lt;br /&gt;    multibinder.addBinding().to(Skittles.class);&lt;br /&gt;  }&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;With this binding, a &lt;code&gt;Set&amp;lt;Snack&amp;gt;&lt;/code&gt; can now be injected:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;class SnackMachine {&lt;br /&gt;  @Inject&lt;br /&gt;  public SnackMachine(Set&amp;lt;Snack&amp;gt; snacks) { ... }&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Create multibindings from different modules is supported. For example, it is okay to have both &lt;code&gt;CandyModule&lt;/code&gt; and &lt;code&gt;ChipsModule&lt;/code&gt; to both create their own &lt;code&gt;Multibinder&amp;lt;Snack&amp;gt;&lt;/code&gt;, and to each contribute bindings to the set of snacks. When that set is injected, it will contain elements from both modules.&lt;br /&gt;&lt;br /&gt;Elements are resolved at set injection time. If an element is bound to a provider, that provider's get method will be called each time the set is injected (unless the binding is also scoped).&lt;br /&gt;&lt;br /&gt;Annotations are be used to create different sets of the same element type. Each distinct annotation gets its own independent collection of elements.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Elements must be distinct.&lt;/strong&gt; If multiple bound elements have the same value, set injection will fail.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Elements must be non-null.&lt;/strong&gt; If any set element is null, set injection will fail.</content><link rel='alternate' type='text/html' href='http://publicobject.com/2008/05/guice-multibindings-extension-checked.html' title='Guice Multibindings extension checked in!'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8675640&amp;postID=2207362477321422810' title='3 Comments'/><link rel='replies' type='application/atom+xml' href='http://publicobject.com/publicobject/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/2207362477321422810'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/2207362477321422810'/><author><name>swankjesse</name><uri>http://www.blogger.com/profile/04905794974441087900</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8675640.post-6336696475055772697</id><published>2008-04-29T23:33:00.000-07:00</published><updated>2008-04-30T00:08:20.673-07:00</updated><title type='text'>Future Guice: Providers that throw unchecked exceptions</title><content type='html'>As &lt;a href="http://publicobject.com/2008/04/future-guice-injecting-inner-classes.html"&gt;previously mentioned&lt;/a&gt;, I'm cataloging Guice's changes since 1.0.&lt;br /&gt;&lt;br /&gt;Suppose you have a provider that throws an unchecked exception:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;class PhaseOfTheMoonProvider implements Provider&amp;lt;PhaseOfTheMoon&amp;gt; {&lt;br /&gt;  @Inject Observatory observatory;&lt;br /&gt;&lt;br /&gt;  public PhaseOfTheMoon get() {&lt;br /&gt;    if (observatory.isNighttime()) {&lt;br /&gt;      return observatory.getCurrentPhase();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    throw new IllegalStateException("Can't see the moon unless it's nighttime.");&lt;br /&gt;  }&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;For the most part, unchecked exceptions are useful for validating pre- and postconditions. But a problem arises when code attempts to catch the specific exception thrown by a provider. Suppose this is our calling code:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;  @Inject Provider&amp;lt;PhaseOfTheMoon&amp;gt; phaseOfTheMoonProvider;&lt;br /&gt;&lt;br /&gt;  public boolean isFullMoon() {&lt;br /&gt;    try {&lt;br /&gt;      PhaseOfTheMoon phaseOfTheMoon = phaseOfTheMoonProvider.get();&lt;br /&gt;      return phaseOfTheMoon == PhaseOfTheMoon.FULL;&lt;br /&gt;    } catch (IllegalStateException e) {&lt;br /&gt;      return false;&lt;br /&gt;    }&lt;br /&gt;  }&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This code works, but it's prone to regress as the provider code is maintained. For example, if the provider code is changed to throw &lt;code&gt;NoMoonlightException&lt;/code&gt;, our application breaks without any notice from the compiler. And should other unchecked exceptions be thrown, the only way to reliably handle them is to suffix all provider access with an ugly &lt;code&gt;catch (RuntimeException e)&lt;/code&gt; block.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Enter ProvisionException&lt;/h3&gt;&lt;br /&gt;To simplify this situation, recent snapshots of Guice make &lt;code&gt;ProvisionException&lt;/code&gt; public, and guarantee that that will be the only exception type thrown by injected providers. Client code only needs to catch &lt;code&gt;ProvisionException&lt;/code&gt; in order to recover from a failed provider. &lt;br /&gt;&lt;br /&gt;To implement this, Guice wraps user-supplied providers and performs exception-chaining to rethrow arbitrary exceptions as &lt;code&gt;ProvisionException&lt;/code&gt;. It embeds contextual information in the provision exception, which simplifies diagnosing problems with indirectly-injected values.&lt;br /&gt;&lt;br /&gt;The new client code can catch &lt;code&gt;ProvisionException&lt;/code&gt; instead. This code will continue to work, even if the &lt;code&gt;Provider&amp;lt;PhaseOfTheMoonProvider&amp;gt;&lt;/code&gt; changes its thrown types:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;  public boolean isFullMoon() {&lt;br /&gt;    try {&lt;br /&gt;      PhaseOfTheMoon phaseOfTheMoon = phaseOfTheMoonProvider.get();&lt;br /&gt;      return phaseOfTheMoon == PhaseOfTheMoon.FULL;&lt;br /&gt;    } catch (ProvisionException e) {&lt;br /&gt;      return false;&lt;br /&gt;    }&lt;br /&gt;  }&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This is the Guice change that I'm most anxious about. It's makes a nontrivial change in Guice's behaviour in an area that is least likely to have test coverage - the exceptional case. How good are your unit tests?&lt;br /&gt;&lt;br /&gt;&lt;font size="-1"&gt;&lt;i&gt;&lt;strong&gt;PS&lt;/strong&gt; - for checked exceptions, look at the &lt;a href="http://code.google.com/p/google-guice/source/browse/trunk/extensions/throwingproviders/src/com/google/inject/throwingproviders/ThrowingProviderBinder.java"&gt;throwing providers extension&lt;/a&gt;.&lt;/i&gt;&lt;/font&gt;</content><link rel='alternate' type='text/html' href='http://publicobject.com/2008/04/future-guice-providers-that-throw.html' title='Future Guice: Providers that throw unchecked exceptions'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8675640&amp;postID=6336696475055772697' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://publicobject.com/publicobject/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/6336696475055772697'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/6336696475055772697'/><author><name>swankjesse</name><uri>http://www.blogger.com/profile/04905794974441087900</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8675640.post-6117050682939613616</id><published>2008-04-29T14:29:00.000-07:00</published><updated>2008-04-29T14:45:41.438-07:00</updated><title type='text'>Glazed Lists talk at JavaOne: Friday at 2:50pm</title><content type='html'>Details on this year's &lt;a href="/glazedlists/"&gt;Glazed Lists&lt;/a&gt; tech session:&lt;br /&gt;&lt;blockquote&gt;&lt;strong&gt;Simply Sweet Applications with Glazed Lists&lt;/strong&gt;&lt;br /&gt;Ken Orr, The MathWorks&lt;br /&gt;Session TS-6047&lt;br /&gt;Friday May 9 at 14:50, Hall E 135&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;From &lt;a href="https://www28.cplan.com/cc191/session_details.jsp?isid=296047&amp;ilocation_id=191-1&amp;ilanguage=english"&gt;Ken's Abstract&lt;/a&gt;,&lt;br /&gt;&lt;blockquote&gt;Glazed Lists fosters data-centric design, which promotes decoupling of components and increases the testability of your code. This lets developers envision their data infrastructure as a data fabric, which is a fantastic abstraction. List pipelining is where the real power of Glazed Lists shines.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;I've committed to hang around Google's booth on Tuesday. I'll be there from 11:30 to 12:30, plus 1:30 to 2:30 if you'd like to drop by and say hi.</content><link rel='alternate' type='text/html' href='http://publicobject.com/2008/04/glazed-lists-talk-at-javaone-friday-at.html' title='Glazed Lists talk at JavaOne: Friday at 2:50pm'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8675640&amp;postID=6117050682939613616' title='3 Comments'/><link rel='replies' type='application/atom+xml' href='http://publicobject.com/publicobject/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/6117050682939613616'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/6117050682939613616'/><author><name>swankjesse</name><uri>http://www.blogger.com/profile/04905794974441087900</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8675640.post-8557805414602961580</id><published>2008-04-29T10:25:00.000-07:00</published><updated>2008-04-29T11:02:22.972-07:00</updated><title type='text'>Guice Multibinder API proposal</title><content type='html'>Multibindings is an idea to allow multiple independent modules to contribute elements to a collection. There's &lt;a href="http://code.google.com/p/google-guice/issues/detail?id=37"&gt;lots&lt;/a&gt; of proposed APIs to add multibindings to Guice. &lt;br /&gt;&lt;br /&gt;Unlike almost all of the existing proposals, this strategy can be used to add multibindings as an extension to Guice. Therefore we don't increase the complexity of the existing Binder API in the much more common non-multibinding case. The API:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;public class Multibinder&amp;lt;T&amp;gt; {&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   * Returns a new multibinder that collects instances of {@code type} in a list.&lt;br /&gt;   */&lt;br /&gt;  static &amp;lt;T&amp;gt; Multibinder&amp;lt;T&amp;gt; newListBinder(Binder binder, Class&amp;lt;T&amp;gt; type);  &lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   * Returns a new multibinder that collects instances of {@code type} in a set.&lt;br /&gt;   */&lt;br /&gt;  static &amp;lt;T&amp;gt; Multibinder&amp;lt;T&amp;gt; newSetBinder(Binder binder, Class&amp;lt;T&amp;gt; type);  &lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   * Build a new element in the bound collection.&lt;br /&gt;   */&lt;br /&gt;  AnnotatedBindingBuilder&amp;lt;T&amp;gt; addBinding();&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;... and here's what the client code would look like:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;  public static void testMultibinder() {&lt;br /&gt;    AbstractModule stanCartmanKennyModule = new AbstractModule() {&lt;br /&gt;      protected void configure() {&lt;br /&gt;        Multibinder&amp;lt;String&amp;gt; stringBinder&lt;br /&gt;            = Multibinder.newSetBinder(binder(), String.class);&lt;br /&gt;&lt;br /&gt;        stringBinder.addBinding().toInstance("Stan");&lt;br /&gt;        stringBinder.addBinding().annotatedWith(Names.named("Fatass")).toInstance("Cartman");&lt;br /&gt;        stringBinder.addBinding().toProvider(new Provider&amp;lt;String&amp;gt;() {&lt;br /&gt;          public String get() {&lt;br /&gt;            return "Kenny";&lt;br /&gt;          }&lt;br /&gt;        });&lt;br /&gt;      }&lt;br /&gt;    };&lt;br /&gt;&lt;br /&gt;    AbstractModule kyleModule = new AbstractModule() {&lt;br /&gt;      protected void configure() {&lt;br /&gt;        Multibinder.newSetBinder(binder(), String.class)&lt;br /&gt;            .addBinding().toInstance("Kyle");&lt;br /&gt;      }&lt;br /&gt;    };&lt;br /&gt;&lt;br /&gt;    Injector injector = Guice.createInjector(stanCartmanKennyModule, kyleModule);&lt;br /&gt;&lt;br /&gt;    Set&amp;lt;String&amp;gt; boys = injector.getInstance(Key.get(new TypeLiteral&amp;lt;Set&amp;lt;String&amp;gt;&amp;gt;() {}));&lt;br /&gt;    assertEquals(Sets.newHashSet("Stan", "Cartman", "Kenny", "Kyle"), boys);&lt;br /&gt;    assertEquals("Cartman", Key.get(String.class, Names.named("Fatass"));&lt;br /&gt;  }&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Note that I've simplified the code above by omitting some details (annotating the collections, binding collections of parameterized types). &lt;br /&gt;&lt;br /&gt;I think this API is both compact and convenient. What's your favourite &lt;a href="http://code.google.com/p/google-guice/issues/detail?id=37"&gt;multibinding API&lt;/a&gt;?</content><link rel='alternate' type='text/html' href='http://publicobject.com/2008/04/guice-multibinder-api-proposal.html' title='Guice Multibinder API proposal'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8675640&amp;postID=8557805414602961580' title='1 Comments'/><link rel='replies' type='application/atom+xml' href='http://publicobject.com/publicobject/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/8557805414602961580'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/8557805414602961580'/><author><name>swankjesse</name><uri>http://www.blogger.com/profile/04905794974441087900</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8675640.post-1666994304992176674</id><published>2008-04-29T01:05:00.000-07:00</published><updated>2008-04-29T01:31:55.820-07:00</updated><title type='text'>Future Guice: injecting inner classes</title><content type='html'>As &lt;a href="http://publicobject.com/2008/04/future-guice-more-aggressive-error.html"&gt;previously mentioned&lt;/a&gt;, I'm cataloging the differences in Guice since 1.0.&lt;br /&gt;&lt;br /&gt;This test passes in Guice 1.0, but how it does so is surprising:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;public class InjectTest extends TestCase {&lt;br /&gt;  public void testFoo() {&lt;br /&gt;    Foo foo = Guice.createInjector().getInstance(InnerFoo.class)&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  class InnerFoo implements Foo {&lt;br /&gt;    @Inject InnerFoo() {}&lt;br /&gt;  }&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The problem is that the &lt;code&gt;InnerFoo&lt;/code&gt; inner class is not marked &lt;code&gt;static&lt;/code&gt;. Therefore each instance of &lt;code&gt;InnerFoo&lt;/code&gt; has an implicit, invisible reference to its containing class, &lt;code&gt; InjectTest&lt;/code&gt;. When it creates an instance of &lt;code&gt;InnerFoo&lt;/code&gt;, Guice 1.0 will also build a new &lt;code&gt;InjectTest&lt;/code&gt;, using its default constructor. &lt;strong&gt;This is weird!&lt;/strong&gt; The outer-class instance is only reachable via the implicit reference, which is awkward and unexpected.&lt;br /&gt;&lt;br /&gt;The latest snapshots of Guice refuse to construct non-static inner classes. This will help to find bugs! And for the rare situation where non-static is desired, Providers can be used. Plus they make the choice of containing instance explicit.</content><link rel='alternate' type='text/html' href='http://publicobject.com/2008/04/future-guice-injecting-inner-classes.html' title='Future Guice: injecting inner classes'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8675640&amp;postID=1666994304992176674' title='1 Comments'/><link rel='replies' type='application/atom+xml' href='http://publicobject.com/publicobject/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/1666994304992176674'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/1666994304992176674'/><author><name>swankjesse</name><uri>http://www.blogger.com/profile/04905794974441087900</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8675640.post-8047078871544240948</id><published>2008-04-25T14:30:00.000-07:00</published><updated>2008-04-25T15:00:22.564-07:00</updated><title type='text'>Future Guice: More aggressive error detection</title><content type='html'>For the past month, I've been cataloging the various changes since Bob &amp; Kevin released version 1.0 back in March 2007. For a 1.0, it's held up remarkably well. We've been using it on my team without many problems and we've quite enjoyed it.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Good News!&lt;/h3&gt;&lt;br /&gt;Guice has improved since 1.0. There's new features, bugfixes, performance improvements and tools for Guice users to enjoy. &lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Bad News&lt;/h3&gt;&lt;br /&gt;The latest snapshosts of Guice are not 100% backwards-compatible with version 1.0. For example, Guice had a bug where it quietly ignored some bindings that it couldn't fulfill. This test case gives a false-positive result: it succeeds even though there's no binding for interface &lt;code&gt;A&lt;/code&gt;:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;  public void testBindProvidersOrder() {&lt;br /&gt;    Injector injector = Guice.createInjector(new AbstractModule() {&lt;br /&gt;      protected void configure() {&lt;br /&gt;        bind(String.class).toProvider(new Provider&amp;lt;String&amp;gt;() {&lt;br /&gt;          @Inject A a;&lt;br /&gt;&lt;br /&gt;          public String get() {&lt;br /&gt;            return "hello world";&lt;br /&gt;          }&lt;br /&gt;        });&lt;br /&gt;      }&lt;br /&gt;    });&lt;br /&gt;&lt;br /&gt;    assertEquals("hello world", injector.getInstance(String.class));&lt;br /&gt;  }&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Today's Guice is better - when this test runs it prints an error at Injector-creation time:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;com.google.inject.CreationException: Guice configuration errors:&lt;br /&gt;&lt;br /&gt;1) Error at com.google.inject.BinderOrderTest$1$1.a(BinderOrderTest.java:31):&lt;br /&gt; Binding to com.google.inject.BinderOrderTest$A not found. No bindings to that type were found.&lt;br /&gt;&lt;br /&gt;1 error[s]&lt;br /&gt; at com.google.inject.InjectorBuilder$ConfigurationErrorHandler.blowUpIfErrorsExist(InjectorBuilder.java:281)&lt;br /&gt; at com.google.inject.InjectorBuilder.validate(InjectorBuilder.java:181)&lt;br /&gt; at com.google.inject.Guice.createInjector(Guice.java:59)&lt;br /&gt; at com.google.inject.BinderOrderTest.testBindProvidersOrder(BinderOrderTest.java:26)&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This particular problem is easy to recognize and fix. It's a net win, even though it breaks backwards-compatibility. There's more similar changes, and I intend to post about them in the coming weeks...</content><link rel='alternate' type='text/html' href='http://publicobject.com/2008/04/future-guice-more-aggressive-error.html' title='Future Guice: More aggressive error detection'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8675640&amp;postID=8047078871544240948' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://publicobject.com/publicobject/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/8047078871544240948'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/8047078871544240948'/><author><name>swankjesse</name><uri>http://www.blogger.com/profile/04905794974441087900</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8675640.post-5706465387514148973</id><published>2008-04-16T19:13:00.000-07:00</published><updated>2008-04-16T19:14:59.891-07:00</updated><title type='text'>Quine Programs in Java</title><content type='html'>Michael K&amp;ouml;lling &lt;a href="http://www.bluej.org/mrt/?p=47"&gt;blogged&lt;/a&gt; about &lt;a href="http://en.wikipedia.org/wiki/Quine_(computing)"&gt;Quines&lt;/a&gt; - programs that print themselves. Here's my best effort in Java (prettyprinted for readability):&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;class A {&lt;br /&gt;  static {&lt;br /&gt;    String a="class A{static{String a=%s%s%1$s;System.out.printf(a,'%1$s',a);}}";&lt;br /&gt;    System.out.printf(a,'"',a);&lt;br /&gt;  }&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Can you beat 122 characters?</content><link rel='alternate' type='text/html' href='http://publicobject.com/2008/04/quine-programs-in-java_16.html' title='Quine Programs in Java'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8675640&amp;postID=5706465387514148973' title='6 Comments'/><link rel='replies' type='application/atom+xml' href='http://publicobject.com/publicobject/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/5706465387514148973'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/5706465387514148973'/><author><name>swankjesse</name><uri>http://www.blogger.com/profile/04905794974441087900</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8675640.post-4897018073445923650</id><published>2008-04-06T17:05:00.000-07:00</published><updated>2008-04-06T17:20:46.003-07:00</updated><title type='text'>Amazon MP3 works good</title><content type='html'>I just bought the new Panic At The Disco album on &lt;a href="http://www.amazon.com/Pretty-Odd/dp/B0015T7Q98"&gt;Amazon MP3&lt;/a&gt;. It was easy! And I don't have the DRM-guilt that I usually get whenever I buy stuff from iTunes. The price is right, the quality is high, and I don't have to do the &lt;i&gt;Deregister Computer&lt;/i&gt; bullshit if I change my laptop. Hooray!&lt;br /&gt;&lt;br /&gt;I don't think I'll be going back to the iTunes store for music.</content><link rel='alternate' type='text/html' href='http://publicobject.com/2008/04/amazon-mp3-works-good.html' title='Amazon MP3 works good'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8675640&amp;postID=4897018073445923650' title='1 Comments'/><link rel='replies' type='application/atom+xml' href='http://publicobject.com/publicobject/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/4897018073445923650'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/4897018073445923650'/><author><name>swankjesse</name><uri>http://www.blogger.com/profile/04905794974441087900</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8675640.post-4058740770660916598</id><published>2008-04-04T17:54:00.000-07:00</published><updated>2008-04-04T18:08:01.984-07:00</updated><title type='text'>Don't do this: Share names</title><content type='html'>The following program is valid Java, even though the &lt;code&gt;Runnable&lt;/code&gt; on line 1 is a completely different symbol than &lt;code&gt;Runnable&lt;/code&gt; on line 3:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;public class Refrigerator implements Runnable {&lt;br /&gt;  public void run() {&lt;br /&gt;    new Runnable().freeze();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public class Runnable {&lt;br /&gt;    void freeze() {&lt;br /&gt;      System.out.println("cold and refreshing");&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public static void main(String[] args) {&lt;br /&gt;    new Thread(new Refrigerator()).start();&lt;br /&gt;  }&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;I'm not quite sure if this is &lt;a href="http://java.sun.com/docs/books/jls/third_edition/html/names.html#6.3.1"&gt;shadowing&lt;/a&gt;, &lt;a href="http://java.sun.com/docs/books/jls/third_edition/html/names.html#6.3.2"&gt;obscuring&lt;/a&gt; or &lt;a href="http://java.sun.com/docs/books/jls/third_edition/html/classes.html#40898"&gt;hiding&lt;/a&gt;, but it's certainly not good. Writing a compiler must be pretty difficult!</content><link rel='alternate' type='text/html' href='http://publicobject.com/2008/04/dont-do-this-share-names.html' title='Don&apos;t do this: Share names'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8675640&amp;postID=4058740770660916598' title='2 Comments'/><link rel='replies' type='application/atom+xml' href='http://publicobject.com/publicobject/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/4058740770660916598'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/4058740770660916598'/><author><name>swankjesse</name><uri>http://www.blogger.com/profile/04905794974441087900</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8675640.post-7843437613101043678</id><published>2008-03-24T21:04:00.000-07:00</published><updated>2008-03-24T21:22:57.569-07:00</updated><title type='text'>Discovering the platform profile from Java</title><content type='html'>What's the simplest way to get CPU speed, amount of RAM, OS version, and other hardware details from the running JVM? I'm putting together a yet-to-be-announced tool that will include hardware specs in its reporting. &lt;br /&gt;&lt;br /&gt;So far, I've been able to get the hardware profile on Mac OS X using &lt;code&gt;sysctl&lt;/code&gt; and on Linux using &lt;code&gt;/proc/cpuinfo&lt;/code&gt; and &lt;code&gt;/proc/meminfo&lt;/code&gt;:&lt;br /&gt;&lt;blockquote&gt;java.version: 1.5.0_13&lt;br /&gt;java.vm.name: Java HotSpot(TM) Client VM&lt;br /&gt;os.arch: i386&lt;br /&gt;os.name: Mac OS X&lt;br /&gt;os.version: 10.5.1&lt;br /&gt;user.name: jessewilson&lt;br /&gt;host.name: jessewilson-macbookpro-2.local&lt;br /&gt;os.kernel.version: 9.1.0&lt;br /&gt;host.model: MacBookPro1,1&lt;br /&gt;host.cpus: 2&lt;br /&gt;host.cpu.speeds: 2000000000&lt;br /&gt;host.cpu.arch: i386&lt;br /&gt;host.cpu.bits.physical: 32&lt;br /&gt;host.cpu.names: Genuine Intel(R) CPU            1500  @ 2.00GHz&lt;br /&gt;host.cpu.caches.l2: 2097152&lt;br /&gt;host.memory.physical: 2147483648&lt;/blockquote&gt;&lt;br /&gt;This comes from a quick-n-dirty Java app, &lt;a href="http://publicobject.com/HostInfo.java"&gt;HostInfo.java&lt;/a&gt;. Curious - anyone know of a simpler approach? Or a more reliable API? I'm not interested in JNI or nontrivial applications, since they complicate deployment.&lt;br /&gt;&lt;br /&gt;Still to do - figure out what's necessary to discover this information on the Windows platform...</content><link rel='alternate' type='text/html' href='http://publicobject.com/2008/03/discovering-platform-profile-from-java.html' title='Discovering the platform profile from Java'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8675640&amp;postID=7843437613101043678' title='5 Comments'/><link rel='replies' type='application/atom+xml' href='http://publicobject.com/publicobject/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/7843437613101043678'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/7843437613101043678'/><author><name>swankjesse</name><uri>http://www.blogger.com/profile/04905794974441087900</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8675640.post-4818280144731951748</id><published>2008-03-21T18:57:00.000-07:00</published><updated>2008-03-21T19:57:17.074-07:00</updated><title type='text'>Coding in the small with Google Collections: ImmutableSet</title><content type='html'>Part 15 in a &lt;a href="http://publicobject.com/2007/09/series-recap-coding-in-small-with.html"&gt;Series&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://code.google.com/p/google-collections/"&gt;Google Collections&lt;/a&gt; project has released an &lt;a href="http://groups.google.com/group/google-collections-dev/browse_frm/thread/70941f4a99347990/a582c573a1dcf64d?tvc=1#a582c573a1dcf64d"&gt;impressive&lt;/a&gt; new collection of features. &lt;br /&gt;&lt;br /&gt;The new release has prompted me to continue this series. My favourite feature of the new release is &lt;a href="http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/ImmutableSet.html"&gt;ImmutableSet&lt;/a&gt;. It's a top-level implementation of &lt;code&gt;Set&lt;/code&gt; that's full of features - this class alone justifies adding the entire &lt;code&gt;.jar&lt;/code&gt; to your application's libraries folder...&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;For static constants&lt;/h3&gt;&lt;br /&gt;&lt;strong&gt;Before&lt;/strong&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;  public static final Set&amp;lt;Integer&amp;gt; LUCKY_NUMBERS;&lt;br /&gt;  static {&lt;br /&gt;    Set&amp;lt;Integer&amp;gt; luckyNumbersMutable = new HashSet&amp;lt;Integer&amp;gt;();&lt;br /&gt;    luckyNumbersMutable.add(4);&lt;br /&gt;    luckyNumbersMutable.add(8);&lt;br /&gt;    luckyNumbersMutable.add(15);&lt;br /&gt;    luckyNumbersMutable.add(16);&lt;br /&gt;    luckyNumbersMutable.add(23);&lt;br /&gt;    luckyNumbersMutable.add(42);&lt;br /&gt;    LUCKY_NUMBERS = Collections.unmodifiableSet(luckyNumbersMutable);&lt;br /&gt;  }&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;strong&gt;After:&lt;/strong&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;  public static final ImmutableSet&amp;lt;Integer&amp;gt; LUCKY_NUMBERS &lt;br /&gt;      = ImmutableSet.of(4, 8, 15, 16, 23, 42);&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;For defensive copies&lt;/h3&gt;&lt;br /&gt;&lt;strong&gt;Before:&lt;/strong&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;  private final Set&amp;lt;Integer&amp;gt; luckyNumbers;&lt;br /&gt;  &lt;br /&gt;  public Hatch(Set&amp;lt;Integer&amp;gt; luckyNumbers) {&lt;br /&gt;    this.luckyNumbers = Collections.unmodifiableSet(new HashSet&amp;lt;Integer&amp;gt;(luckyNumbers));&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  public Set&amp;lt;Integer&amp;gt; getLuckyNumbers() {&lt;br /&gt;    return luckyNumbers;&lt;br /&gt;  }&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;strong&gt;After:&lt;/strong&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;  private final ImmutableSet&amp;lt;Integer&amp;gt; luckyNumbers;&lt;br /&gt;&lt;br /&gt;  public Foo(Set&amp;lt;Integer&amp;gt; luckyNumbers) {&lt;br /&gt;    this.luckyNumbers = ImmutableSet.copyOf(luckyNumbers);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public ImmutableSet&amp;lt;Integer&amp;gt; getLuckyNumbers() {&lt;br /&gt;    return luckyNumbers;&lt;br /&gt;  }&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;For more defensive copies&lt;/h3&gt;&lt;br /&gt;&lt;code&gt;ImmutableSet.copyOf&lt;/code&gt; has been heavily optimized when the argument is itself an ImmutableSet. It turns out that this method can &lt;i&gt;no-op&lt;/i&gt; if the argument is itself an &lt;code&gt;ImmutableSet&lt;/code&gt;, since copying immutable objects is redundant. The more you use &lt;code&gt;ImmutableSet&lt;/code&gt;, the cheaper it is to do defensive copies!&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;For predictable insertion order&lt;/h3&gt;&lt;br /&gt;ImmutableSet's elements iterate in the same order that they're added in. That means there's less &lt;i&gt;unpredictable&lt;/i&gt; behaviour in your application's business logic. There's no need to worry about tests that pass on one JVM and fail with another because of &lt;code&gt;HashSet&lt;/code&gt;'s unspecified iteration order.&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;    ImmutableSet&amp;lt;Integer&amp;gt; numbers = ImmutableSet.of(8, 6, 7, 5, 3, 0, 9);&lt;br /&gt;    assertEquals("[8, 6, 7, 5, 3, 0, 9]", numbers.toString());&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;For self-documenting APIs&lt;/h3&gt;&lt;br /&gt;&lt;strong&gt;Before:&lt;/strong&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;  /**&lt;br /&gt;   * Returns numbers most likely to be selected in upcoming lottery drawings.&lt;br /&gt;   * &lt;br /&gt;   * @return an &lt;strong&gt;immutable&lt;/strong&gt;, non-empty set&lt;br /&gt;   */&lt;br /&gt;  public Set&amp;lt;Integer&amp;gt; getLuckyNumbers();&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;strong&gt;After:&lt;/strong&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;  /**&lt;br /&gt;   * Returns numbers most likely to be selected in upcoming lottery drawings.&lt;br /&gt;   * &lt;br /&gt;   * @return a non-empty set&lt;br /&gt;   */&lt;br /&gt;  public &lt;strong&gt;Immutable&lt;/strong&gt;Set&amp;lt;Integer&amp;gt; getLuckyNumbers();&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;For less memory allocation&lt;/h3&gt;&lt;br /&gt;ImmutableSet allocates fewer objects and smaller objects than either &lt;code&gt;HashSet&lt;/code&gt; or &lt;code&gt;LinkedHashSet&lt;/code&gt;. This makes your program's heap smaller. There's also less work for your garbage collector.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;For non-null data&lt;/h3&gt;&lt;br /&gt;ImmutableSet does not permit null elements. This is almost always what you want, and helps to detect bugs early:&lt;br /&gt;&lt;strong&gt;Before:&lt;/strong&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;  public Hatch(Set&amp;lt;Integer&amp;gt; numbers) {&lt;br /&gt;    for (Integer number : numbers) {&lt;br /&gt;      if (number == null) {&lt;br /&gt;        throw new NullPointerException();&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    this.numbers = Collections.unmodifiableSet(new LinkedHashSet&amp;lt;Integer&amp;gt;(numbers));&lt;br /&gt;  }&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;strong&gt;After:&lt;/strong&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;  public Hatch(Set&amp;lt;Integer&amp;gt; numbers) {&lt;br /&gt;    this.numbers = ImmutableSet.copyOf(numbers);&lt;br /&gt;  }&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;ImmutableSet is my new default collection, replacing &lt;code&gt;ArrayList&lt;/code&gt;. It's that good. And as a special treat, when I do need a List, Google Collections also includes &lt;a href="http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/ImmutableList.html"&gt;ImmutableList&lt;/a&gt;.</content><link rel='alternate' type='text/html' href='http://publicobject.com/2008/03/coding-in-small-with-google-collections.html' title='Coding in the small with Google Collections: ImmutableSet'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8675640&amp;postID=4818280144731951748' title='3 Comments'/><link rel='replies' type='application/atom+xml' href='http://publicobject.com/publicobject/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/4818280144731951748'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8675640/posts/default/4818280144731951748'/><author><name>swankjesse</name><uri>http://www.blogger.com/profile/04905794974441087900</uri><email>noreply@blogger.com</email></author></entry></feed>