Atom Feed SITE FEED   ADD TO GOOGLE READER

Properties would work nicely with First-class methods

First-class methods (FCM) is a compelling proposal to enhance the Java language so that methods, fields and constructors can have full type-safety.

In today's Java, we write this:
Method getter = Action.class.getDeclaredMethod("isEnabled", new Class[] { });
Method setter = Action.class.getDeclaredMethod("setEnabled", new Class[] { boolean.class });
boolean fooEnabled = getter.invoke(fooAction, new Object[] { });
setter.invoke(barAction, new Object[] { false });
This code is unnecessarily verbose. The caller needs to catch a NoSuchMethodException because the String method names are not compile-time checked.

FCM fixes these problems! The above code becomes this:
Method getter = Action#isEnabled()
Method setter = Action#setEnabled(boolean)
boolean fooEnabled = getter.invoke(fooAction, new Object[] { });
setter.invoke(barAction, new Object[] { false });
The method instances themselves can even be expressed safely, which adds even more type-safety:
#(boolean(Action)) getter = Action#isEnabled();
#(void(Action,boolean)) setter = Action#setEnabled(boolean);
boolean fooEnabled = getter.invoke(fooAction);
setter.invoke(barAction, false);
Naturally this is very powerful! The syntax is unfamiliar but adjusted to generics and we could adjust to FCM.

Applications to Properties
FCM makes a very concise and typesafe syntax for Properties possible - just specify the getters and setters:
Property<Action,Boolean> property = new MethodsProperty(
Action#isEnabled(), Action#setEnabled(boolean))
boolean fooEnabled = property.get(fooAction);
property.set(barAction, false);
By implementing JSR-295 beans binding with a Property interface, we're making it possible for the project to leverage future Java language enhancements.

Modelling Properties in Java

We're having a properties discussion over on the beansbinding (JSR-295) mailing list. Here's a recent revision of the API:
/**
* Models the relationship between two related types, such as
* the address of a customer or the size of a List.
*
* <p>A property is not bound to a particular base object - rather it
* is shared by all instances of a class.
*
* @param <B> the base object type, such as Customer
* @param <V> the value type, such as an Address or String
*/
public interface Property<B,V> {
/**
* Returns the value of this property on the specified object.
* @throws PropertyNotReadableException
*/
V get(B baseObject);

/**
* Returns the value of this property on the specified object,
* or the specified default if this property cannot be resolved.
*/
V get(B baseObject, V defaultValue);

/**
* Sets the value of this property on baseObject to newValue.
* @return the previous value of the property
* @throws PropertyNotWritableException
*/
V set(B baseObject, V newValue);

Class<B> getBaseObjectType();
Class<V> getValueType();

/**
* Returns a brief description of this property such as
* "address" or "size".
*/
String toString();
}

Naturally for binding, properties can be observable:
/**
* Mixin for properties that can notify observers when
* they change.
*/
public interface ObservableProperty<B,V> extends Property<B,V> {
/**
* Register the specified listener to receive notification when
* this property is changed.
*/
void addPropertyChangeListener(B baseObject, PropertyChangeListener listener);

/**
* Deregister the specified listener from receiving notification
* when this property is changed.
*/
void removePropertyChangeListener(B baseObject, PropertyChangeListener listener);
}

There's still many unresolved issues:
  • Should properties be type-specific or instance-specific? If they're type-specific, properties need an instance to be passed to the get() method (as above). Instance-specific properties are bound to a particular baseObject which does not need to be passed in.
  • Should Property be an interface or an abstract class?
  • What's a better name for baseObject, the thing that has the property?

    If you have any ideas, please join the discussion!
  • Thoughts on Java as the configuration language for Guice

    Google Guice uses plain old Java code as the configuration code. For example, here's the code that sets up my fictional pizza store management application:
    public class PizzaOrdering implements Module {
    public void configure(Binder binder) {
    // tell Guice that whenever the code needs an implementation of
    // my CallInOrderHandler interface, the WebCallInOrderHandler
    // shall be used
    binder.bind(CallInOrderHandler.class).to(WebCallInOrderHandler.class);

    // tell Guice that whenever the code needs an OrderEditor, they
    // should be provided with the same WebOrderEditor for the duration
    // of their current phone call
    binder.bind(OrderEditor.class)
    .to(WebOrderEditor.class)
    .in(PhoneCallScope.class)
    }
    }

    To make it more enterprisey, a highly paid consultant could probably create an XML language to represent the same thing:
    <binding key="com.publicobject.pizza.CallInOrderHandler" 
    target="com.publicobject.pizza.ui.WebCallInOrderHandler">
    <binding key="com.publicobject.pizza.OrderEditor"
    target="com.publicobject.pizza.ui.WebOrderEditor"
    scope="com.publicobject.pizza.request.PhoneCallScope">

    There's are plenty of arguments for and against XML for configuration. I prefer to use Java code because it's compile-time checked and the syntax is concise. But recently I've found a new and interesting problem with this approach,
    The only way for tools to read the configuration is to execute it.
    Consider this module:
    public class PizzaDelivery implements Module {
    public void configure(Binder binder) {
    String strategy = System.getProperty("DeliveryDriverQueueingStrategy");
    if ("FirstInFirstOut".equals(strategy)) {
    binder.bind(DeliveryDriverQueueingStrategy.class)
    .to(FifoDeliveryDriverQueueingStrategy.class);
    } else if ("FirstInLastOut".equals(strategy)) {
    binder.bind(DeliveryDriverQueueingStrategy.class)
    .to(FiloDeliveryDriverQueueingStrategy.class);
    } else {
    logger.warn("No queueing strategy!");
    }

    This is way more flexible than XML. But it's also less approachable by tools because it cannot be analyzed statically. Without executing PizzaDelivery (with the proper environment!), the tool cannot answer "what is DeliveryDriverQueueingStrategy bound to?", or even "Is DeliveryDriverQueueingStrategy bound?"

    Is this limitation fatal? Certainly not. Most of the Modules I've seen contain trivial control flow and can easily be analyzed by tools. In rare cases, the configuration can be recorded as the module is executed, either alone or as part of a running application.

    How can we make our Guice code tool-friendly?
  • Try to keep your Modules simple and free of control flow.
  • Avoid bind(Service.class).toInstance(new ServiceImpl()), which is less toolable than bind(Service.class).to(ServiceImpl.class). It also means that ServiceImpl doesn't need to be constructed if ever the Module is executed by a tool.
  • AssistedInject, an easier way to help the Guice Injector build objects

    Frequently on my team we have a class that gets some of its constructor parameters from the Guice Injector and others from the caller:
    public class RealPayment implements Payment {
    public RealPayment(
    CreditService creditService, // from the Injector
    AuthService authService, // from the Injector
    Date startDate, // from the instance's creator
    Money amount); // from the instance's creator
    }
    ...
    }

    The standard solution to this problem is to write a factory that helps Guice build the objects:
    public interface PaymentFactory {
    public Payment create(Date startDate, Money amount);
    }

    public class RealPaymentFactory implements PaymentFactory {
    private final Provider<CreditService> creditServiceProvider;
    private final Provider<AuthService> authServiceProvider;
    public PaymentFactory(Provider<CreditService> creditServiceProvider,
    Provider<AuthService> authServiceProvider) {
    this.creditServiceProvider = creditServiceProvider;
    this.authServiceProvider = authServiceProvider;
    }
    public Payment create(Date startDate, Money amount) {
    return new RealPayment(creditServiceProvider.get(),
    authServiceProvider.get(), startDate, amount);
    }
    }

    Then in our module:
       bind(PaymentFactory.class).to(RealPaymentFactory.class);

    We think it's annoying to have to write the boilerplate factory class each time we're in this situation. It's also annoying to have to update the factories whenever our implementation class' dependencies change.

    This motivated Jerome Mourits and I to write a Guice extension called AssistedInject. It generates the implementation of our Factory class automatically. To use it, we annotate the implementation class' constructor and the fields that aren't known by the Injector:
    public class RealPayment implements Payment {
    @AssistedInject
    public RealPayment(
    CreditService creditService,
    AuthService authService,
    @Assisted Date startDate,
    @Assisted Money amount);
    }
    ...
    }

    Then we reflectively create a Provider<Factory> in the Guice module:
    bind(PaymentFactory.class).toProvider(
    FactoryProvider.newFactory(PaymentFactory.class, RealPayment.class));

    Our FactoryProvider class maps the create() method's parameters to the corresponding @Assisted parameters in the implementation class' constructor. For the other constructor arguments, it asks the regular Injector to provide values.

    With the FactoryProvider class, we can easily to create classes that need extra arguments at construction time:

    1. Annotate the constructor and assisted parameters on the implementation class (such as RealPayment.java)
    2. Create a Factory interface with a create() method that takes only the assisted parameters. Make sure they're in the same order as in the constructor
    3. Bind that FactoryInterface to our FactoryProvider interface.


    The code is available as an open source Guice extension:
  • Source with Jar
  • Javadocs
  • Why dreamhost.com rules for domain hosting

    I pay a cheap annual fee - $97/year - to host publicobject.com, swank.ca and some others at Dreamhost. Today I went to publicobject.com and the site was down.

    I checked the usual suspects:
  • did I let my domain registration expire?
  • is DNS set up correctly by my registrar?
  • is DNS set up correctly by dreamhost?
  • is my local network connection flaky?

    These turned out all to be working, so I tried some more stuff - SSHing and FTPing to the site. Both of these worked. I assumed that the Apache HTTPD server must have crashed or something, so I decided to give up and ask tech support for a fix.

    Dreamhost has an thorough, easy-to-navigate tech support site. It uses a rich Ajaxey form to request help and it gives suggestions for common problems based on how you fill in the form. The suggestions they gave were spot on - did my domain registration expire? does FTP work? etc. Access to a Real Person via email is easy and I quickly submitted the form a description of the problem.

    Within an hour, my site was back up and I received an email describing what had gone wrong. The message described that someone else on my shared server somehow crashed our common Apache server. I'm not mad - Dreamhost gives its users liberal access to the underlying services, and so with this great flexibility it's possible to crash a server.

    But I am highly impressed with how quick the problem was resolved, and how knowledgeable their tech support is. I've bought cheap webhosting from lots of places and there's occasional problems with all of them. The thing that makes Dreamhost great is their people. When problems do happen, it's fantastic to have smart people on call, taking care of me.

    PS - although this is an unsolicited testimonial, I do participate in the Dreamhost referral program. If you need webhosting, sign up with Dreamhost. If you the promo code JESSE, you save $87 and I get $10 off my annual fees. Or use the code PUBLICOBJECT to save the full $97.
  • Java language tweak: protected switch

    I have an enumerated type, and it's possible that I'll be adding more values in the future.
    public enum Office {
    CALGARY, REGINA, TORONTO, BERLIN;
    }


    Somewhere in the code, I switch on this type:
    public CurrencyCode getCurrencyForPayingEmployees(Office office) {
    switch(office) {
    case CALGARY:
    case REGINA:
    case TORONTO:
    return CurrencyCode.CAD;
    case BERLIN:
    return CurrencyCode.EUR;
    }
    }


    Unfortunately, this doesn't compile. Javac will tell me that the method doesn't always return, because it doesn't know that I've covered all applicable cases. I appease the compiler by adding this line at the end of the method:
        default:
    throw new AssertionError();


    Now whenever I add a new office I have to scour through the code to find the switch statements and add the appropriate behaviour. I get no compiler help from this, so if I miss one, I'll end up getting AssertionErrors in test or production.

    The classical solution for this is the visitor pattern, but it's somewhat verbose and doesn't work very well if when I don't control the enum that I'm switching on.

    What if Java had a 'protected' switch statement that protected me from forgetting an element? The syntax would be similar:
    public CurrencyCode getCurrencyForPayingEmployees(Office office) {
    protected switch(office) {
    case CALGARY:
    case REGINA:
    case TORONTO:
    return CurrencyCode.CAD;
    case BERLIN:
    return CurrencyCode.EUR;
    }
    }


    But there are a few differences:
  • the compiler enforces that every type is covered, and shows a compiler warning if a particular enum element is not present.
  • if we return from all cases, we don't need an extra 'return' statement at the bottom to handle the nonexistent other case.

    If ever I have the time, I'll see if I can hack javac and contribute this to KSL.