Showing posts with label properties. Show all posts
Showing posts with label properties. Show all posts

Monday, 26 September 2016

Code generating beans - mutable and immutable

Java has long suffered from the pain of beans. To declare a simple data class takes far too much code. At JavaOne 2016, I talked about code generation options - see the slides.

Code generation of mutable and immutable beans

The Java ecosystem is massive. So many libraries releasd as open source and beyond, which naturally leads to the question as to how those libraries communicate. And it is the basic concept of beans that is the essential glue, despite the ancient specification. How do ORMs (Hibernate etc.), Serialization (Jackson etc.) and Bean Mappers (Dozer etc.) communicate? Via getters and setters.

The essential features of beans have moved beyond the JavaBeans spec, and are sometimes referred to as POJOs. The features are:

  • Mutable
  • No-args constructor
  • Getters and Setters
  • equals() / hashCode() / toString()

But writing these manually is slow, tedious and error-prone. Code generation should be able to help us here.

But should we be using mutable beans in 2016? No, no, no!

It is time to be writing immutable data structure (immutable beans). But the only practical way to do so is code generation, especially if you want to have builders.

In my talk at JavaOne 2016, I considered various code generation approaches:

IDE code generation

This is fine as far as it goes, but while the code is likely to be correct immediately after generation, there is still no guarantee that the generated code will stay correct as the class is maintained over time.

AutoValue, Immutables and VALJOGen

These three projects - AutoValue, Immutables, VALJOGen - use annotation processors to generate code during compilation. The idea is simple - the developer writes an abstract class or interface, and the tool code generates the implementation at compile time. However, these tool all focus on immutable beans, not mutable (Immutables can generate a modifiable bean, but it doesn't match the JavaBeans spec, so many tools will reject it).

On the up side, there is no chance to mess up the equals / hashCode / toString. While the tools all allow the methods to be manually written if necessary, most of the time, the default is what you want. It is also great not to have to implement the immutable builder class manually.

On the down side, you as the developer have to write abstract methods, not fields. A method is a few more keystrokes than a field, and the Javadoc requires an @return line too. With AutoValue, this is particularly painful, as you have to write the outline of the builder class. With Immutables, there is no need for this.

Of the three projects, AutoValue provides a straightforward simple tool that works, and where the implementation class is hidden (package scoped). Immutables provides a full-featured tool, with many options and ways to generate. By default, the implementation class is publicly visible and used by callers, but there are ways to make it package-scoped (with more code written by you). VALJOGen allows full customisation of the generation template. There is no doubt that Immutables is the most comprehensive of the three projects.

All three annotation processing tools must be setup before use. In general, adding the tool to Maven will do most of the work (Maven support is good). For Eclipse and IntelliJ, these instructions are comprehensive.

Lombok

The Lombok project also uses annotations to control code generation. However, instead of acting as an annotation processor, it hacks into the internal APIs of Eclipse and the Java compiler.

This approach allows code to be generated within the same class, avoiding the need for developers to work with an abstract class or interface. This means that instead of writing abstract methods, the developer writes fields, which is a more natural thing to do.

The key question with Lombok is not what it generates, but the way it generates it. If you are willing to accept the hacky approach, IDE limitations, and the inability to debug into the generated code, then it is a neat enough solution.

For Eclipse, Lombok must be installed, which is fairly painless as there is a GUI. Other tools require other installation approaches, see this page.

Joda-Beans

The Joda-Beans project takes a third approach to code generation. It is a source code regenerator, creating code within the same source file, identified by "autogenerated start/end" comments.

Developers write fields, not abstract methods which is simpler and less code. They also generate code into the same class, which can be final if desired.

One key benefit of generating all the code to the same class is that the code is entirely valid when checked out. There is no need to install a plugin or configure your IDE in any way.

Unlike the other choices, Joda-Beans also provides functionality at runtime. It aims to add C# style properties to Java. What this means in practice is that you can easily treat a bean as a set of properties, loop over the properties and create instances using a standardized builder. These features are the ideal building block for serialization frameworks, and Joda-Beans provides XML, JSON and binary serialization that operates using the properties, generally without reflection. The trade off here is that Joda-Beans is a runtime dependency, so it is only the best option if you use the additional properties feature.

The Joda-Beans regenerator can be run from Maven using a plugin. If you use the standard Eclipse Maven support, then simply saving the file in Eclipse will regenerate it. There is also a Gradle plugin.

Comparing

Most of the projects have some appeal.

  • AutoValue is a simple annotation processor that hides the implementation class, but requires more code to trigger it.
  • Immutables is a flexible and comprehensive annotation processor that can be used in many ways.
  • Lombok requires the least coding by the developer, but the trade-off is the implementation via internal APIs.
  • Joda-Beans is different in that it has a runtime dependency adding C# style properties to Java, allowing code to reliably loop over beans.

My preference is Joda-Beans (which I wrote), because I like the fact that the generated code is in the same source file, so callers see a normal final class, not an interface or abstract class. It also means that it compiles immediately in an IDE that has not been configured when checked out from source control. But Joda-Beans should really only be used if you understand the value of the properties support it provides.

If I was to pick another tool, I would use Immutables. It is comprehensive, and providing you invest the time to choose the best way to generate beans for your needs, it should have everything you need.

Finally, it is important that readers have a chance to look at the code written and the code generated. To do this, I have created the compare-beangen GitHub project. This project contains source code for all the tools above and more, demonstrating what you have to write.

To make best use of the project, check it out and import it into your IDE. That way, you will experience what code generation means, and how practical it is to work with it. (For example, see what happens when you rename a field/method/class. Does the code generator cope?)

Summary

It is time to start writing and using immutable beans instead of mutable ones. The Strata open source market risk project (my day job) has no mutable beans, so it is perfectly possible to do. But to use immutable beans, you are going to need a code generator, as they are too painful to use otherwise.

This blog has summarised five code generators, and provided a nice GitHub project for you to do you own comparisons.

Monday, 8 December 2014

What might a Beans v2.0 spec contain?

What features should be in scope and out of scope for a Beans specification v2.0?

Note: I am an independent blogger, not an Oracle employee, and as such this blog is my opinion. Oracle owns the JavaBeans trademark and controls what actually happens to the specification.

Update 2015-01-03: New home page for the Beans v2.0 effort now available!

JavaBeans v1.0

My last blog examined the contents of the current JavaBeans (TM) specification. The key feature elements can be summarized as follows:

  • Properties - accessed using getter and setter methods
  • Events - change events for properties
  • Methods - all public methods
  • BeanInfo - permits customization of properties, events and methods
  • Beans - a utility class to access the features
  • Property editor - a mechanism to edit properties, including conversion to and from a string format
  • GUI support - allows a bean to be manipulated visually

These features were a good fit for 1997, given that the original goal was to be a component system, interoperating with other similar systems like COM/DCOM. These features are no longer what we need, so any Beans v2.0 is naturally going to look a lot different.

Beans v2.0 - Data abstraction

The key goal of a Beans v2.0 spec is to define an abstraction over the data in an object.

When such an abstraction exists, frameworks and libraries become far simpler to write and interact with. For example, a serialization framework at its most basic level simply needs to iterate over all the beans and properties in an object graph in order to perform its task.

In addition to frameworks, many ad-hoc coding tasks become simpler because it is much easier to walk over the object graph of beans and properties. For example, to find all instances of a particular type within an object graph starting from an arbitrary bean.

The data abstraction needs to be fully round-trip. The spec must allow for data to be read from a bean into another format. But it must also provide the tools to allow the original bean to be recreated from the data previously read.

Beans v2.0 - Mutable vs Immutable

The JavaBean v1.0 specification implicitly defines mutable objects. It requires all beans to have a no-args constructor, thus the only way for the properties to get populated is through the use of setters. This mutability is one of the key complaints that people have about JavaBeans, and often Java itself by association.

Any Beans v2.0 specification must support immutable objects.

Immutable classes are now a common design approach to systems and are increasingly popular. Supporting them is thus vital to encompass the range of data objects in use today.

Any Beans v2.0 specification must also still support mutable objects. While there are those that turn their nose up at any mutability, it is still a perfectly valid choice for an application. The decision between mutable and immutable data objects is a trade-off. The Beans v2.0 spec needs to support both options.

The implications of supporting immutable is that an alternative to a no-args constructor and public setters will be needed to support construction. This is likely to be a "bean builder" of some kind.

Beans v2.0 - Beans and Properties

The term "bean" is often associated with a specific Java class, such as Person. The term "property" is often associated with a single field on the class, such as surname or forename.

Any Beans v2.0 spec must not have a reflection-based view of beans and properties.

Firstly, a property is not the same as a field (instance variable). Fields hold the state of an object, but not necessarily in the form that the object wishes to expose (it might be stored in an optimised format for example). As such, it must be possible for a bean to control the set of properties that it publishes.

Secondly, it can be desirable to a bean with a dynamic set of properties. This might consist of a bean with a fixed set of base properties and an extensible map of additional ones, or a bean which is entirely dynamic, much closer to the data model of many dynamic languages.

The implications of this is that there is not a one-to-one mapping between a bean and a Class, nor is there a one-to-one mapping between a property and a java.lang.reflect.Field.

The JavaBeans v1.0 spec treats indexed properties in a special way. I can see no reason to do that in Beans v2.0, particularly given the range of collection types now in use.

Beans v2.0 - Getters and Setters

The current JavaBeans v1.0 spec requires there to be a physical java.lang.reflect.Method instance for both the getter and setter. What Beans v2.0 needs to provide is an abstraction away from this, as it provides many more options.

Any Beans v2.0 spec must not require data access via a java.lang.reflect.Method.

Moving away from direct exposure of reflection raises the level of abstraction. It permits alternative object designs to be exposed as beans.

For example, consider a bean that has no public getters and setters. With the Beans v2.0 abstraction, this could still expose its data as properties, providing interoperation with frameworks, but encapsulating the data for most programmatic uses. This tackles another big criticism of JavaBeans, which is that they cause state to be exposed rather than hidden.

Another example is the HashMap based bean. In this case a Method does not exist for each property, just a single get by name. Being able to expose this as a bean provides the desired dynamic behaviour.

The implications of this are simply that the Beans v2.0 spec abstraction will simply be long the lines of the Map interface get and put.

Beans v2.0 - Annotations

The current JavaBeans v1.0 spec predates annotations in Java. But annotations are now key to many programming practices in Java.

Any Beans v2.0 spec must provide access to property and bean annotations.

Annotations are represented by implementations of the Annotation interface. It so happens that the Annotation interface is not part of reflection. It is possible to implement an annotation yourself (apart from a compiler warning).

What is needed is for the Beans v2.0 spec abstraction to provide access to the set of annotations on the bean, and the set of annotations on each property without going via reflection. With this step, and the ones above, many direct uses of reflection will completely disappear, with the Beans v2.0 abstraction being good enough.

Beans v2.0 - Events

The current JavaBeans v1.0 spec considers events to be first class parts of the abstraction.

There is no good reason to include events in the Beans v2.0 spec.

The current JavaBeans v1.0 spec is GUI focussed, and as such events were an essential element. But the Beans v2.0 spec outlined here focuses on a different goal, abstracting over the data in the object. Round-tripping data from a bean to another format and back to a bean does not require events or a GUI.

There will be those reaching for the comments box right now, demanding that events must be included. But think carefully and you should realise that you don't need to.

None of what is proposed here for Beans v2.0 takes away what works today with JavaBeans v1.0. GUI developers can still carry on using the same getters, setters and events that they do today, including bound and constrained properties. The java.beans package will continue to exist and continue to be available. In addition, JavaFX is the way forward for Java GUIs, and it has its own approach to properties.

Beans v2.0 - Conversion to/from String

The current JavaBeans v1.0 spec includes PropertyEditor. One of the use cases of the class, notably in Spring framework, is to convert a simple object (typically a VALJO) to and from a String. For example, this includes Integer, Enum, Class and Currency.

Any Beans v2.0 spec must tackle conversion to/from a String for simple types.

The most common use case for the Beans v2.0 spec will be to iterate over the object graph and process it in some way, such as to write out a JSON or XML message. In order for this to be practical, all objects in the object graph need to be either a bean, or a simple type convertible to a string. As such, simple type string conversion is very much needed to round out the spec.

The Joda-Convert project contains a simple set of interfaces and classes to tackle this problem, and I imagine any Beans v2.0 spec solution would be similar.

Beans v2.0 - But what does a bean actually look like?

Part of the goal of Beans v2.0 is to allow for different kinds of bean. Immutable as well as mutable. Private getters and setters as well as public. Dynamic map-based structures as well as field-based ones.

Any Beans v2.0 spec should not overly restrict how beans are implemented.

We know that Oracle has no current plans for properties at the language level. As such, it also makes little sense for Beans v2.0 spec to specify a single approach for how classes should be designed. Instead, the spec aims to allow classes that are designed in different ways to all agree on a common way to interact with frameworks and libraries that does not require getters, setters and a no-args constructor.

The Joda-Beans, Lombok, Immutables and Auto projects (and many others) all provide different ways to create beans without writing manual code. All could be adapted to work with the proposed Beans v2.0 spec, as could frameworks like Jackson, Hibernate, Dozer and Groovy (to name but a few).

The simple answer is that the bean could look just like it does today with getters and setters. The real answer is that the bean may look any way it likes so long as it can expose its data via the Beans v2.0 API.

Summary

The current JavaBeans v1.0 spec is very old and not that useful for the kinds of applications we build today. This blog has outlined my opinion on what direction a Beans v2.0 spec should take:

  • Focussed on data abstraction
  • Support for Mutable and Immutable beans
  • Fully abstracted from reflection
  • No requirement for getters and setters
  • No requirement for a no-args constructor
  • Support for dynamically extensible properties
  • Access to bean and property annotations
  • Conversion of simple types to and from a String
  • No support for events

Feel free to comment on the high-level scope outlined above. In particular, if you develop a project that uses the JavaBeans spec (directly or indirectly), please comment to say whether the proposed spec is likely to be sufficient to cover your use cases.

I've also started work on a prototype of the code necessary to support the spec. So also feel free to raise pull requests or join the mailing list / group.

Friday, 28 November 2014

The JavaBeans specification

Have you ever read the JavaBean (TM) specification? It really is from another era!

The JavaBean specification

The JavaBean specification, version 1.01, was the last specification that defined the approach to the common bean pattern used in many Java applications. Most developers have never read it, but if you want a history lesson, its a good read.

The spec dates from 1997, JDK 1.1 and Sun Microsystems, a scary 17 years ago. Serialization and Reflection are new technologies, and CORBA is a big deal.

The introduction starts with:

The goal of the JavaBeans APIs is to define a software component model for Java, so that third party ISVs can create and ship Java components that can be composed together into applications by end users.

It goes on to describe the key goal of being able to interact with the OpenDoc, COM/DCOM/ActiveX and LiveConnect object models, so JavaBeans can be embedded inside Word documents and Excel spreadsheets (via a "transparant bridge"). An early example is the desire to support "menubar merging", combining the menu from a JavaBean with that of the host application.

So, what is a JavaBean?:

A Java Bean is a reusable software component that can be manipulated visually in a builder tool.

The explanation goes on to consider builder tools as web page builders, visual application builders, GUI layout builders, or document editors (like a Word document). Beans may have a GUI, or be invisible, however GUI is clearly the main focus. Note that GUI beans are required to subclass java.awt.Component.

The unifying features of a bean are:

  • Introspection - so tools can analyse a bean
  • Customization - so tools can alter a bean
  • Events - AWT style event handing
  • Methods - the set of methods the bean declares as being callable
  • Properties - the set of get/set properties
  • Persistence - long term storage, primarily by serialization

Beans are expected to run in a container, and that container is expected to provide certain behaviour around persistence and gluing beans together. Notably, a connection from one bean to another can either be composition (where the bean is expected to serialize the composed bean) or a "pointer to an external bean", where it is expected that the container will recreate it.

The multi-threading section is very simplistic:

It is the responsibility of each java bean developer to make sure that their bean behaves properly under multi-threaded access. For simple beans this can generally be handled by simply making all the methods “synchronized”.

Another interesting section indicates a future plan to add a "view" layer, where multiple beans can be composed together into a view. To enable this, two methods Beans.instantiate() and Beans.getInstanceOf() are supposed to be used. Casts and instanceof checks are forbidden.

The most classic part of the spec is the scenarios section:

Buying the tools.
1.a) The user buys and installs the WombatBuilder Java application builder.
1.b) The user buys some JavaBeans components from Al’s Discount Component Store. They get a win32 floppy containing the beans in a JAR file. This includes a “Button” component and a “DatabaseViewer” component.
1.c) The user inserts the floppy into the machine and uses the WombatBuilder...

Floppy disks! Well this is 1997...

The section does highlight that bean customization is expected to make available a mechanism of serializing beans as source code, via the PropertyEditor.getJavaInitializationString() method. Standard Java object serialization is a mandatory technique, while the source code route is optional.

Event handling is familiar enough, using java.util.EventListener and java.util.EventObject (think mouse listeners for example). Beans can define their own event hierarchies and publish the events that the bean defines. The listeners are based on a naming convention:

The standard design pattern for EventListener registration is:
public void add<ListenerType>(<ListenerType> listener);
public void remove<ListenerType>(<ListenerType> listener);

And of course these methods are expected to access a Vector to store the listeners. A special case is that of limiting the number of listeners using java.util.TooManyListenersException, not something I've ever seen. Oh, and you are supposed to declare and throw checked exceptions in listeners, not unchecked.

Section 7 covers properties, described as "discrete, named attributes of a JavaBean". They are defined by a naming convention we all know well:

void setFoo(PropertyType value); // simple setter
PropertyType getFoo(); // simple getter

There is also direct support for indexed properties, but only on arrays:

void setter(int index, PropertyType value); // indexed setter
PropertyType getter(int index); // indexed getter
void setter(PropertyType values[]); // array setter
PropertyType[] getter(); // array getter

Note that the spec is slightly unclear here, using "setter" and "getter" as a placeholder for a "setFoo" type name. All getters and setters are allowed to throw checked exceptions.

Bound and constrained properties get a mention, along with PropertyChangeListener, PropertyVetoException and VetoableChangeListener. Vetoing gets complicated when there are multiple event listeners and some may have been notified of a success before the veto occurs. The spec has a suprising amount of detail on these two concepts, including a variety of ways of registering listeners.

The introspection section finally talks in detail about using reflection ad design patterns to find getters and setters, plus the ability to use a more specific BeanInfo:

By default we will use a low level reflection mechanism to study the methods supported by a target bean and then apply simple design patterns to deduce from those methods what properties, events, and public methods are supported. However, if a bean implementor chooses to provide a BeanInfo class describing their bean then this BeanInfo class will be used to programmatically discover the beans behaviour.

...within Java Beans the use of method and type names that match design patterns is entirely optional. If a programmer is prepared to explicitly specify their properties, methods, and events using the BeanInfo interface then they can call their methods and types whatever they like. ... Although use of the standard naming patterns is optional, we strongly recommend their use as standard naming conventions are an extremely valuable documentation technique

Bean properties, getters and setters, are matched based on the "get" and "set" prefix, and they may be defined in a superclass. Read-only and write-only properties are permitted. Boolean properties may use the "is" prefix, which may be used instead of, or in addition to, the normal "get" prefixed method.

Bean events are similarly matched by "addFooListener" and "removeFooListener" pattern matching. Both must be present for an event to be recognised.

Bean methods are simply defined as all public methods of the class. The list of methods includes getters, setters and event methods.

The BeanInfo class is used to selectively replace parts of the reflected information. Thus, the properties could be defined, but the events obtained by reflection. The java.beans.Introspector class is used to obtain the combined view, including the BeanInfo and reflected data.

It turns out that there are specific rules around capitalization in property names:

Thus when we extract a property or event name from the middle of an existing Java name, we normally convert the first character to lower case. However to support the occasional use of all upper-case names, we check if the first two characters of the name are both upper case and if so leave it alone. So for example,
“FooBah” becomes “fooBah”
“Z” becomes “z”
“URL” becomes “URL”

When customizing a bean, the default approach is to take the set of properties and expose an editor. This would operate as a key-value table, but where each property can nominate a java.beans.PropertyEditor to provide a GUI for defining that property. The classic example is a colour picker for a property of type Color. Again, any GUI is an AWT Component. And you can register an editor simply by naming it after the property being configured - Foo class is edited by FooEditor in the same package or a set of search packages.

The official tutorial is also instructive.

The simple view is that a bean just needs to be serializable, have a no-args constructor and have getters/setters matching a naming convention. While this is true, the actual spec has a lot more in it, including many rules that most developers do not follow, such as the use of Beans.instantiate() and Beans.getInstanceOf().

Summary

This has been a whistlestop tour of the JavaBeans spec. What hits you between the eyes when you read it is a sense of how old it is. The world has very much moved on.

More significantly however, is that the "beans" that are so common in Java code, consisting of mutable classes with getters and setters are not what the authors of the spec had in mind. As such, we probably shouldn't really call them beans.

But perhaps it is time to write up a JavaBeans v2 spec to rethink the problem being solved in the absence of a properties language feature.

Thursday, 13 November 2014

No properties in the Java language

Here at Devoxx 2014, Brian Goetz went a little further than he has before about whether properties will ever be added to Java as a language feature.

No properties for you

Properties as a language feature in Java has been talked about for many years. But ultimately, it is Oracle, the Java stewards, who get to decide whether it should be in or out.

Today, at Devoxx, Brian Goetz, Java Language Architect, went a little further than he has before to indicate that he sees little prospect of properties being added to the language at this point.

Oracle have chosen to prioritize lambdas, modularization and value types as key language features over the JDK 8 to 10 timescale. As such, there was no realistic prospect of properties before JDK 11 anyway. However, the indications today were reasonably clear - that it isn't on the radar at all.

When quizzed, Brian indicated two main reasons. First, that it is perhaps too late for properties to make a difference as a language feature, with compatibility with older getter/setter beans being a concern. Second, that there are many different, competing visions of what properties means, and there is an unwillingness to pick one.

Competing visions include:

  • Just generate getters, setters, equals, hashCode and toString
  • Generate observable properties for GUIs
  • Raising the level of abstraction, treating a property as a first class citizen
  • Immutability support, with builders for beans
  • New shorter syntax for accessing properties

While it is easy to argue that these are competing visions, it is also possible to argue that these are merely different requirements, and that all could be tackled by a comprehensive language enhancement.

(Just to note that "beans and properties" does not imply mutable objects. It is perfectly possible to have immutable beans, with or without a builder, but immutable beans are harder for frameworks to deal with. Value types are intended for small values, not immutable beans.)

As is well known, I have argued for properties as a language feature for many years. As such, I find the hardening of the line against properties to be intensely disappointing.

Every day, millions of developers interact with beans, getters, setters and the frameworks that rely on them. Imagine if someone today proposed a naming convention mechanism (starts with "get") for properties? It would be laughable in any language, never mind the world's most widely used enterprise development language.

Instead, developers use IDEs to generate getters, setters, equals and hashCode, adding no real value to their code, just boilerplate of the kind Java is notorious for.

Consider that with 9 million Java developers, there could easily be 50,000 new beans created every day, each with perhaps 100 lines of additional boilerplate getters/setters/equals/hashCode/toString - easily 5 million lines of pointless code created, per day.

(And plenty more code in serialization and mapping code that either tries to deduce what the properties are, or results in lots of additional manual mapping code)

Realistically however, we have to accept that in all likelihood Java will never have properties as a language feature.

Summary

The Java language is not getting properties.

Comments welcome, but please no "Foo language has properties" comments!

Sunday, 29 May 2011

Beans and properties

A few words on beans and properties in Java, prompted by the JavaFX 2.0 API and my work on Joda-Beans.

Beans and Properties

I was prompted to write this by the new API of JavaFX 2.0. It has a new extension to JavaBeans that adds support for properties, so that the JavaFX GUI can bind one property to another. I've been writing property extensions to JavaBeans for over 12 years now, so I feel I should comment on the design.

The basic design approach is to have an object representing each property on a bean. This object allows meta-data attributes to be stored per property (useful for marking errors), property change listeners (for GUIs) and tool access without reflection (allowing XML input/output, XPath, JSON etc).

The basic design adds an additional method to the JavaBean pattern. Alongside getSurname() and setSurname() there would be the property method surname(). This would return a Property object, which supports querying and setting the value, checking whether it was read-only or read-write, finding its type and adding property change listeners.

// basic querying via JavaBeans or property
  String surname = person.getSurname();
  String surname = person.surname().get();
  
  // additional features available with properties
  Property<String> property1 = person.surname();
  Property<String> property2 = person.property("surname");
  Map<String, Property<?>> propertyMap = person.propertyMap();
  person.surname().setAttribute("error", "MANDATORY");
  person.surname().addListener(...);

All the versions of this I've written follow a pattern relatively similar to that above. And the JavaFX 2.0 design is remarkably similar to this. However, some implementations of the pattern are more successful than others.

Version 1 - Original Joda

My initial work in the area was private, but I wrote a variation in open source around 2000 (unmaintained from 2002). This was the first Joda project (before Joda-Time), and still lives on the web here (Javadoc). Here is the original Joda approach (shown with generics for clarity):

public interface Person {
    Property<String> surname();
    String getSurname();
    void setSurname(String surname);
  }

In that project, the class was created using a Proxy object. Clearly, this approach was rather limiting, as a factory had to be used to created an instance of a bean. For various reasons, including the factories, this version was abandoned.

Version 2 - Instantiated Property objects

This version existed at one of my old day jobs. It used code generation rather than Proxy, which was better. However, it used this approach to the beans:

public class Person extends Bean {
    private final Property<String> surname = new Property(String.class);  // object created when person created
 
    public Property<String> surname() { return surname; }
    public String getSurname() { return (Strung) surname.get(); }     // state held on the property
    public void setSurname(String surname) { surname.set(surname); }
  }

Note that every time a Person is created, a Property object is created. Now imagine what happens when you have 20 properties on the bean - thats 21 object creations for an empty Person! And 21 garbage collections! It turns out that this design works OK for client side work, where there is a single machine and processing is limited by what one human can do. However, on the server side it performs horribly. Thus, it got converted into version 3.

Version 3 - Data on the bean

The version 2 approach stored all the state on the Property, but this approach does not work well with the JVM (it could, if the JVM/Java had the ability to inline the state of immediate child objects into the state of the parent object). Thus, the next approach was to move all the state from the property to the bean:

public class Bean {
    private final Map<String, String> attributes;
  }
  public class Person extends Bean {
    private final String surname;
 
    // code generated:
    public Property surname() { return new Property<String>(this, "surname"); }
    public String getSurname() { return surname; }
    public void setSurname(String surname) { this.surname = surname; }
 
    protected Object propertyGet(String propertyName) {
      switch (propertyName.hashCode()) {
        case 36527358: return getSurname();  // number is "surname".hashCode()
      }
      return null;
    }
  }

This approach moves all the state from the property back to the bean itself. The superclass would store any common items, like the attribute map (for error code) or the listeners, while the main person class stores the data using normal fields. The code generation adds a method that connects up the field without reflection.

Since the property is esentially stateless, it can be created on demand, used and then discarded. Short lived objects like that are good for the garbage collector, so long as they are not used too frequently. This design was successful on the server side, and supported all the other goodies, like conversion to and from XML and XPath searching, all without reflection. I believe that a dynamic code generation approach would also work, but the static code generation was effective enough that we didn't go further.

Version 4 - Joda-Beans (the next generation...)

The new Joda-Beans project (Javadoc) is an open source version of the version 3 approach, written from the ground up, but focussed on the essential elements for simplicity. It is currently in use at OpenGamma.

Again, a code generator is used to create the getters, setters and property methods, plus the supporting methods like propertyGet() and propertySet(). This time however, there is a greater focus on the meta-property level, which is the representation of the surname property as a concept, rather than tied to a particular bean instance. Think of the relationship between a property and a meta-property as similar to the relationship between an object and a class. (Effectively, Joda-beans defines both type 1 and type 2 properties.)

Rather than show a code sample here, I encourage you to look at some example classes to see what the code generator produces: Person, Address and the subclass CompanyAddress. The developer only writes the part outside the "code generated" block. The block is generated and re-generated without destroying any additional methods that are hand-written, so you can treat it as a "normal" class in all other ways.

Once again, the property objects hold no long-lived state and are created on demand. After 12 years of working with properties, I'm convinced that is the only design that scales acceptably for the server side on the JVM.

While the Joda-Beans project is not at v1.0 yet, it does work and enhances coding in Java. I'd love to have some early adopters try it out!

JavaFX 2.0

The JavaFX 2.0 approach uses stateful properties (Javadoc - javafx.beans packages). As I've discussed above, such an approach is powerful and conceptually simple, but has performance issues on anything other than the client side. Some articles on the JavaFX 2.0 approach are here and here Clearly, a major concern of the design is listeners, but I still have concerns about this approach.

Other implementations

There are other projects too that have tackled this problem, including Proper properties, Bean-properties, Better beans binding, and Remi's compiler changes (I'll add anything in the comments to this list). No project has won a large mind share though, and most seem unmaintained. A related solution is the ugly JPA typesafe extension.

Language solutions

I've said this before and I'll say it again. The lack of properties in Java is the biggest missing langauge feature and the amount of wasted development time globally by developers writing beans or tools to access properties is gigantic. Moreover, I believe that adding properties to Java is more important than both generics and closures, and should have been prioritised accordingly. (Every enterprise developer knows how much they use the broken JavaBean approach.)

The new JVM languages all have properties (no surprise there), although not all have proper support for obtaining an object to represent the property. Maybe one day, Java itself will support properties as a language feature, it is being vaguely mentioned now, but I'm not holding my breath.

Summary

Properties are a hugely beneficial language feature and raise the abstraction level of coding. While the Java language continues to not have them, you can use or help the Joda-Beans project to add them to your codebase.

My experience suggests that the JVM is poor at handling stateful property objects. Unfortunately, this is the route that JavaFX 2.0 has chosen. It might work for them (because they are client side, and because JVMs are getting faster), but I would advise against using JavaFX 2.0 properties on the server side without lots of performance testing.

Feedback welcome...

Monday, 1 October 2007

Java 7 - Properties terminology

The debate around properties is hotting up. I'm going to try and contribute by defining a common terminology for everyone to communicate in.

Properties terminology

This is a classification of the three basic property types being debated. Names are given for each type of property. My hope is that the names will become widely used to allow everyone to explain their opinions more rapidly.

Note that although none of the examples show get/set methods, all of the options can support them. It should also be noted that the interface/class definitions are reduced and don't include all the possible methods.

Type 1 - Bean-independent property

(aka per-class, property-proxy, property adaptor)

This type of property consists of a type-safe wrapper for a named property on a specific type of bean. No reference is held to a bean instance, so the property is a lightweight singleton, exactly as per Field or Method. As such, it could be held as a static constant on the bean.

 public interface BeanIndependentProperty<B, V> {
   /**
    * Gets the value of the property from the specified bean.
    */
   V get(B bean);
   /**
    * Sets the value of the property on the specified bean.
    */
   void set(B bean, V newValue);
   /**
    * Gets the name of the property.
    */
   String propertyName();
 }

This type of property is useful for meta-level programming by frameworks. The get and set methods are not intended to be used day in day out by most application developers. Instead, the singleton bean-independent property instance is passed as a parameter to a framework which will store it for later use, typically against a list of actual beans.

A typical use case would be defining the properties on a bean to a comparator, for example comparing surnames, and if they are equal then forenames. Clearly, the comparator needs to be defined completely independently to any actual bean instance.

 Comparator<Person> comp = new MultiPropertyComparator<Person>(
   Person.SURNAME, Person.FORENAME   // bean-independent property defined as static constant
 );

Bean-independent properties can be implemented in two main ways. The first option uses reflection to access the field:

 public class Person {
  public static final BeanIndependentProperty<Person, String> SURNAME =
      ReflectionIndependentProperty.create(Person.class, "surname");
  private String surname;
 }

The second option uses an inner class to access the field:

 public class Person {
  public static final BeanIndependentProperty<Person, String> SURNAME =
      new AbstractIndependentProperty("surname") {
        public String get(Person person) { return person.surname; }
        public void set(Person person, String newValue) { person.surname = newValue; }
      };
  private String surname;
 }

As bean-independent properties are static singletons, they should be stateless and immutable.

Type 2 - Bean-attached property

(aka per-instance)

This type of property consists of a type-safe wrapper for a named property on a specific instance of a bean. As the bean-attached property is connected to a bean, it must be accessed via an instance method.

 public interface BeanAttachedProperty<B, V> {
   /**
    * Gets the value of the property from the stored bean.
    */
   V get();
   /**
    * Sets the value of the property on the stored bean.
    */
   void set(V newValue);
   /**
    * Gets the name of the property.
    */
   String propertyName();
 }

This type of property is useful for frameworks that need to tie a property on a specific bean to a piece of internal logic. The most common example of this is many parts of the Beans Binding JSR, such as textfield bindings.

The get and set methods are not intended to be used day in day out by most application developers. Instead, the bean-attached property instance is passed as a parameter to a framework which will store it for later use.

A typical use case would be defining the binding from a person's surname to a textfield. In this scenario we are binding the surname on a specific bean to the textfield on a specific form.

 bind( myPerson.surnameProperty(), myTextField.textProperty() );

Bean-attached properties can be implemented in two main ways. The first option uses reflection to access the field. This example show the attached property being created new each time (on-demand), however it could also be cached or created when the bean is created:

 public class Person {
  public BeanAttachedProperty<Person, String> surnameProperty() {
    return ReflectionAttachedProperty.create(this, "surname");
  }
  private String surname;
 }

The second option uses an inner class to access the field. Again, this example show the attached property being created new each time (on-demand), however it could also be cached or created when the bean is created:

 public class Person {
  public BeanAttachedProperty<Person, String> surnameProperty() {
    return new AbstractAttachedProperty("surname") {
        public String get() { return surname; }
        public void set(String newValue) { surname = newValue; }
      };
  private String surname;
 }

Bean-attached properties are merely pointers to the data on the bean. As such, they should be stateless and immutable.

Type 3 - Stateful property

(aka bean-properties, property objects, Beans 2.0, Eclipse IObservableValue)

Note that stateful properties have been implemented in the bean-properties project, however that project goes well beyond the description below.

This type of property consists of a stateful property on a specific instance of a bean. The property is a fully fledged object, linked to a specific bean, that holds the entire state of the property, including it's value. This approach is based around an alternative to the standard beans specification, however get/set methods can be added if desired.

 public class StatefulProperty<B, V> {
   private B bean;
   private V value;
   /**
    * Constructor initialising the value.
    */
   StatefulProperty<B, V>(B bean, V initialValue) {
     this.bean = bean;
     value = initialValue;
   }
   /**
    * Gets the value of the property from the stored bean.
    */
   public V get() { return value }
   /**
    * Sets the value of the property on the stored bean.
    */
   public void set(V newValue) { value = newValue; }
   /**
    * Gets the name of the property.
    */
   public String propertyName();
 }

This type of property is intended for application developers to use day in day out. However it is not intended to be used in the same way as normal get/set methods. Instead, developers are expected to code a bean and use it as follows:

 // bean implementation
 public class Person {
  public final StatefulProperty<Person, String> surname =
      new StatefulProperty<Person, String>(this, "surname");
  }
 }
 // usage (instead of get/set)
 String s = myPerson.surname.get();
 myPerson.surname.set("Colebourne");

The important point to note is that the surname field on the bean is final and a reference to the stateful property. The actual state of the property is within the stateful property, not directly within the bean.

A stateful property fulfils the same basic API as a bean-attached property (type 2). As such in can be used in the same use cases. However, because a stateful property is an object in its own right, it can have additional state and metadata added as required.

The key difference between bean-attached (type 2) and stateful (type 3) is the location of the bean's state. This impacts further in that bean-attached properties are intended primarily for interaction with frameworks, whereas stateful properties are intended for everyday use.

Language syntax changes

Both bean-independent (type 1) and bean-attached (type 2) properties benefit from language syntax change. This would be used to access the property (not the value) to pass to the framework in a compile-safe, type-safe, refactorable way:

 // bean-independent - accessed via the classname
 BeanIndependentProperty<Person, String> property = Person#surname;
 
 // bean-attached - accessed via the instance
 BeanAttachedProperty<Person, String> property = myPerson#surname;

Stateful properties (type 3) do not need a language change to access the property as they are designed around it, making it directly available and fully safe.

The second area of language change is definition of properties. This is a complicated area, which I won't cover here, where all three types of property would benefit from language change.

The third area of language change is access to the value of a property. Again, there are many possible syntaxes and implications which I won't cover here.

Combination

The full benefit of bean-independent (type 1) and bean attached (type 2) properties occurs when they are combined. Additional methods can be added to each interface to aid the integration, and any language syntax change becomes much more powerful.

Summary

I hope that these definitions will prove useful, and provide a common terminology for the discussion of properties in Java.

Opinions are welcome, and I will make tweaks if necessary!

Thursday, 27 September 2007

Java 7 - Update on Properties

Whilst I was on holiday there was a bit of discussion about properties in Java.

Shannon Hickey announced Beans Binding version 1.0. This is the JSR that intends to develop an API to connect together swing components in a simple and easy to use manner. The idea is that you call a simple API to setup a binding between a GUI field and your data model.

During development, a lot of discussion on the JSR was about the interaction with the possible language proposal for properties. As a result, the v1.0 API includes a Property abstract class, with a subclasses for beans and the EL language from J2EE.

Per-class or per-instance

One key issue that has to be addressed with a property proposal is whether to go per-class or per-instance. The per-class approach results in usage like Method or Field, where the bean must be passed in to obtain the value:

 Person mother = ...;
 Property<Person, String> surnameProperty = BeanProperty.create("surname");
 String surname = surnameProperty.getValue(mother);

Here, the surname property refers to the surname on all Person beans. The caller must pass in a specific person instance to extract the value of the surname.

On the other hand, the per-instance approach results in usage where the property itself knows what bean it is attached to:

 Person mother = ...;
 Property<Person, String> surnameProperty = BeanProperty.create("surname", mother);
 String surname = surnameProperty.getValue();

Here, the surname property refers to the specific surname property on the mother instance. There is thus no need to pass in any object to extract the value of the surname, as the property knows that it is attached to mother.

Which is better? And which did Beans Binding adopt?

Well, its actually the case that for the swing use case, the per-class approach is really the only option. Consider a table where each row is the representation of a bean in a list. The columns of this table are clearly going to be properties, but which type? Well, when defining the binding, we want to do this without any reference to the beans in the list - after all, the beans may change and we don't want to have to redefine the binding if they do.

So, we naturally need the per-class rather than per-instance properties. And, that is what the Beans Binding project defines.

Is there ever a need for the per-instance approach? In my opinion yes, but that can be added to the per-class based property functionality easily.

Adding language support

Having seen the Beans Binding release, Remi Forax released a version of his property language compiler that integrates:

 Person mother = ...;
 Property<Person, String> surnameProperty = LangProperty.create(Person#surname);
 String surname = surnameProperty.getValue(mother);

As can be seen, the main advantage is that we now have a type-safe, compile-time checked, refactorable property Person#surname. This is a tremendous leap forward for Java, and one that shouldn't be underestimated. And the # syntax can easily be extended to fields and methods (FCM).

But, why do we see this new class LangProperty? Well, Remi's implementation returns an object of type java.lang.Property, not a Beans Binding org.jdesktop.Property. This fustrating difference means that two classes named Property exist, and conversion has to take place.

What this really demonstrates is the need for Sun to declare if Java 7 will or won't contain a language change for properties, and for a real effort to occur to unify the various different JSRs currently running in the beans/properties arena. It would be a real disaster for Java to end up with two similar solutions to the same problem (although I should at least say I'm very happy that the two parts are compatible :-).

Summary

Properties support in Java is progressing through a combination of JSR and individual work. Yet Sun is still silent on Java 7 language changes. Why is that?

Opinions welcomed as always!

Tuesday, 16 January 2007

Property access - is it an expression language?

There is lots of talk about a simpler syntax for getting and setting properties. But what are the implications?

Property value access

The basic concept is simple. The proposers of this idea (not me!!!) use a simple get or set example:

  // current code
  person.setSurname( input.getName() );

  // proposed change - not from me!
  person.surname = input.name;

As a simple example, this works fine. Its effectively an operator overload for get/set methods. I don't think it would be disastrous if implemented - just a little weak and incomplete.

First, some specific issues with it. Problem one is that the syntax clashes with public fields on any existing class. The compiler will have to have specific rules to decide whether to pick a field or a property. Or alternatively, you can't declare both with the same name. Or a syntax other than dot could be used (which has other downsides).

Problem two is that the code is no longer 'transparent' wrt what it actually does. A basic field assignment statement doesn't fail (yes, yes, I know it can, but 99.9% of the time it doesn't). With this change, what looks like an innocuous field assignment is actually a method call, which may throw an exception.

Problem three is related to two - the get and set methods could end up being remote operations performed across a network. Obviously, a remote operation may have performance and scalability issues, and should be thought about a bit more. This is very hidden from the calling code (although it could be argued that a get/set method hides it equally as much)

Problem four is null handling. Consider a more complex example:

  address.postcode = input.address.postcode;

What happens if input or address is null. Do we care? Or do we just want to assign null to address.postcode? This is related to the issue I tackled in null-ignore invocation.

Problem five is scope - the proposal only covers basic get/set. But real applications use Lists and Maps. And they need indexed and mapped access too.

  List<Person> people = ...
  Person person = people[0];

  Mapt<String, Integer> numberToBook = ...
  Integer adultsToBook = numberToBook["Adult"];

  Requirements reqs = ...
  Integer adultsToBook = reqs.flight[0].numberToBook["Adult"];

Suddenly, the scope of the change has grown dramatically to cover List.get(int), Map.get(K) and Map.put(K, V).

A full solution

So, we need a different syntax, to meet these goals:

  • no conflict with existing Java syntax
  • is isolated enough that we can be aware that an error might occur on assignment
  • can handle nulls along the way, optionally ignoring them
  • can handle indexed and mapped access

To me, this more completely set of requirements is a long way from simply an operator overload for get and set methods. These goals remind me of JSP/JSF EL. Or OGNL. These are expression languages where there is a non-Java syntax dedicated to accessing and manipulating bean properties.

Now, non-Java languages, such as Groovy, don't have a problem with this. They can design their language around the need for property and path access.

But, making the change in Java is a big deal - its almost like adding a new sub-language within the Java language. The question is whether Java can take that level of change?

A separate sub-language

So perhaps we should be honest and admit that Java isn't suited for defining these expressions. Instead, embed a new expression language, delimited by special tokens:

  String email = ${contact.email};

  ${contact.email = input.email};

  ${address.postcode = input#address#postcode};

  List<Person> people = ...
  Person person = ${people[0]};

  Mapt<String, Integer> numberToBook = ...
  Integer adultsToBook = ${numberToBook["Adult"]};

  Requirements reqs = ...
  Integer adultsToBook = ${reqs.flight[0].numberToBook["Adult"]};

This seems to meet the goals in a much cleaner fashion. The expression is clearly delineated, using ${...}, to indicate it follows different syntax rules. It can interact fully with all the enclosing variables. In fact it would be compiled to bytecode so the resulting code would be indistinguishable. Nulls can be ignored, here with a # syntax. Lists and maps are dealt with using a syntax that is familiar from other ELs.

It does rather feel like the additional ${} characters get in the way though.

Summary

Groovy has shown that you can embed a full property access syntax, GPath, within a syntax like Java. But is it viable to change Java by that degree? The expression-language concept allows a new syntax to be used in Java that doesn't clash with existing assumptions in language.

I'm not sure I'm sold on the concept though - for a start it just seems to look a bit ugly. All I hope to do is to consider some of the issues involved, and hopefully trigger other ideas elsewhere. As usual, your thoughts are welcomed.

Monday, 8 January 2007

Java 7 - Property objects

Property syntax for Java 7 is the current discussion de jour. But I've been pointing out that we can go beyond get/set methods to create refactorable, compile checked property objects too.

Property syntax

The proposals being discussed revolve around syntax sugar code generation. So, the developer codes:

  public class Person {
    public property private String forename;
    public property private String surname;
  }

This would code generate the get/set methods:

  public class Person {
    private String forename;
    public String getForename() {return forename;}
    public void setForename(String forename) {this.forename = forename;}

    private String surname;
    public String getSurname() {return forename;}
    public void setSurname(String forename) {this.forename = forename;}
  }

Discussions on Javalobby and various blogs have focussed on the basic mechanics of the syntax for defining a property (keyword vs annotation vs token) and javadoc. In addition, a completely separate discussion about arrow operators has confused the debate. This is all fine, but in my view it misses the huge opportunity that is presented by this change.

Property objects

Currently, many many tools, especially frameworks, have to access beans in a dynamic way. By this I mean where a String property name is used to identify a property and reflection is used to access it. For example, this code might be used to bind the surname property in a validation, swing or database framework.

  binder.bind(person, "surname");

But this design is really utter madness!!! A key strength of Java is static typing, allowing compile time detection of errors and refactoring. With a design like this, all these features of Java are lost. For example, if you rename the property, then the binding will fail at runtime - yuck!!! What I want to write is:

  binder.bind( person.propertySurname() );

This is fully type-safe, refactorable and compiled. And once you have it, you find an awful lot of places where it can be used - Database bindings, Swing bindings, WebApp bindings, XML access, ...

Implementation

Full details can be foud in the download zip. In summary, there are four interfaces, the most significant is Property:

  public interface Property<B, T> {
    B bean();
    MetaProperty<B, T> metaProperty();
    T get();
    void set(T value);
  }

The bean method returns the bean that owns this property. The meta property holds details about the property such as its name and type. The get and set methods access the bean. The key point is that the get method actually calls the real getSurname() method on the bean. Likewise for set. So, the property object isn't breaking encapsulation, it just provides a higher level view of the property.

So, why the link to the current property debate? Well, the method propertySurname() needs to be generated along with the get and set methods. (In fact a metaProperty static method should be generated as well to complete the picture, see the download zip for full details). Anyway, with my proposal, the property code generation would create the following:

  public class Person {
    private String forename;
    public String getForename() {return forename;}
    public void setForename(String forename) {this.forename = forename;}
    public Property propertyForename() {return new SimpleProperty(this, "forename");}

    private String surname;
    public String getSurname() {return forename;}
    public void setSurname(String forename) {this.forename = forename;}
    public Property propertySurname() {return new SimpleProperty(this, "surname");}
  }

In other words, the proposal simply means one more syntax sugar generated method per property (see the download zip for full details).

Summary

The get/set method convention is extremely widely used in Java, and so any property solution must generate get and set methods. But if we go a little further and create property objects then we can dramatically change the interaction between our applications and the frameworks we use day-in day-out. Personally, I just love the refactorable, static-type checks and compiler safety that this brings. Do you agree?