Monday, January 28, 2008

Wild Java Properties, The Wild Part

Following my previous blog entry, I tried to use Remi's property implementation for JPA or WebBeans. These 2 recent (WebBeans being still in diapers) frameworks really represent what I need from the property proposal. Generally I'd like to be able to do things like:

JPA (Hibernate)

@Id
public property long id get;

@Column("FIRST_NAME")
public property String firstName;

new Criteria(Person#firstName, value);

Validations

protected <B,T> void propertyChanged(
java.lang.Property<B,T>
property,
Object
oldValue,Object newValue) {
// Activate validation rules and so stop setting the value
}

WebBeans (JSR-299) or Guice

@Log
private static property Logger log;

Wicket or Swing

new TextField(Person#firstName);
new DynamicPanel().addAll(Person.properties());
I'd like to say that Remi's work is truly amazing and is a good first draft. It is open source for us to analyze and contribute to. The benefits of properties in the cases above are:
  1. No issue of annotations on either a field and/or getter/setter methods. All is centralized on one property declaration.
  2. No reflection. All method calls from and to the framework are compiled and wired without using reflection. This is a great boost for UI and Dependency Injection framework.
  3. Introspection without reflection.
Trying to write the properties for the logger example (in fact any DI/IoC framework) and validations framework, I found that this implementation is not helping, and even worse - It's stopping me from doing what I need. Here are the limitations:
  1. The first problem I encountered is that writing get and set blocks inline looks really good but breaks Object Orientation. I cannot do inheritance or use polymorphisms in these blocks. I ended up having more boilerplate code than without the usage of properties.
  2. The second is that the private field exists only if there is no get/set block. So, if you wish to write getter/setter that uses a field, you need to declare this field. Suddenly, a lot of the generated syntactic sugar disappears and you find yourself writing almost as much as before.
  3. The third issue is that encapsulation is asymmetric. What I mean by that is System.out.println(firstName) will use directly the field, but this.firstName = "toto" will become this.setFirstName("toto");

So, I tried to see how I can solve these limitations. Since modularity is the most important feature for me, a clean solution for the DI framework property issue is critical. This can really turn Java into a true Component based platform at its root. So as for the Logger issue I actually want to write:
private static property Logger log
init {
log = Logger.getLogger(Person.class.getName());};
I added here some init block in the same line as the get/set block, since this is really what I want - to declare how the field is initialized. But, I'd like to write this once and reuse it. Furthermore, I want the init to be executed when the field (either static or instance) is declared, or on demand (lazy init). The only good way to do it is to have a class wrapping the Type2 property. It would look something like:
public class Person {
public final static Property<Logger> log = new LazyInitProperty() {
protected void init() {
value = Logger.getLogger(Person.class.getName());
}
};
public final Property<String> lastName = new Property<String>();
}

public class Property<T> implements BaseProperty<T> {
private T value;
public T get() {return value;}
public void set(T value) {this.value = value;}
}

public abstract class LazyInitProperty<T> implements ReadOnlyProperty<T> {
protected T value;
public T get() {
if (value == null)
init();
return value;
}
protected abstract void init();
}
Of course it is missing a lot of good (or not) synchronized, but the idea is here. Basically I ended up with the Joda Beans or java.net bean properties concept, and also Yardena's idea.
This is an old idea about the notion that properties don't need to be a language feature. Take a look at What Makes Bean-Properties Special, and 2 discussions on The Java Posse Google group: Wonder what Joe thinks of this properties solution, Still hope for first-class properties.

Conclusion

The solution to all of my problems: Properties should not be a language feature!
When I got there for the first time I thought: WTF! But that's a logical step, isn't it? Properties are field level encapsulation with accessors and events. You can do this in any OO language with a class wrapping your field. So why are we suffering?

The main problem with open source properties projects is that all the classes and interfaces of PropertyType2<T> and PropertyType1<B,T> belong in the JDK. They need to be made a standard so that all framework and component will use them. To be useful, the bean-properties project needs to be in a JSR and included in Java 7. Why didn't any open source property project became a de-facto standard? It's amazing how many Property classes already exists out there!
  1. Joda does binding with no boilerplate but changes the getter/setter style.
  2. Bean-properties does the binding boilerplate code (and even setter/getter) with bytecode generation. Personally I prefer good syntactic sugar.
  3. Annotations on these specific "Property" fields are not understood by 3rd party framework like JPA.
  4. You need to declare public final fields.
  5. Even if the amount of code is quite low, you still repeat yourself in the field declaration.
  6. Bean introspection and Property object access are done using Strings and reflection.
  7. The amount of features (Read, Write, initialized, Lazy, bind), types (Simple, Array, Set, Map,...), Modifiers (private, public, synchronized, volatile, for field/getter/setter), are generating a combinator which is impossible to implement with a Property<T> class hierarchy.
Personally, I don't find items 1 and 4 to be a problem. The getter/setter style is related to encapsulation. It's the OO convention for dealing with properties. For me, automatically transforming person.firstName="toto"; to person.setFirstName("toto"); in Java today is very confusing. With Joda style, the type of person.firstName is Property<String>, so when "toto" is assigned to it, something needs to box the value! Transforming person.firstName="toto"; to person.firstName.set("toto"); looks very close to the boxing/unboxing feature, doesn't it? Basically I feel comfortable with the idea that if you want to encapsulate a field in a Property, you should use a class for the encapsulation, not getXXX() and setXXX() methods. And if it's a class, make it clear, don't hide it. So, as for point 4 - a property may be visible or not. Here, I have a strong issue with visibility control around the field, getter, setter trio. Today, I do use different modifiers for each of them. Is it really useful?

So what!

Well, my final wild idea is:
  • I want a unique Type1 interface in the JDK (like Remi's Property<B,T>) called PropertyAdaptor<B,T> to be separated from bean-properties class. This can (and will in my kijaro branch) be implemented with an abstract enum.
  • I want Person#firstName to return the above Type1 enum instance, and then use it to remove the need to change the class format (similar to what needs to be done in Remi's implementation today).
  • I want a nice, small and simple Type2 property interfaces and classes hierarchy, that are making a heavy usage of Annotations and the above unique Type1 enum entry for initialization. Basically this means making some "kind of" bean-properties project part of the Kijaro JDK (KDK ;-).
  • The Type1 methods "T get(B)" and "void set(B,T)" should delegate (by the javac phase) to "T get()" and "set(T)" of the Type2 instance. This would remove the need for reflection.
  • There should be no restrictions on extending classes or interfaces in the JDK based Property<T> (Type2) hierarchy and on using them. This way, WebBeans and JPA can provide state-of-the-art properties implementations tuned for their needs. This would provide the loose coupling and transparent state management at a language level without reflection.
  • The property keyword should be replaced by the above annotation. This Annotation will activate all the syntactic sugar that would remove the standard properties boilerplate code. But, most of the actual Type2 implementation will come from the super class and extra annotations.
Each time I apply the concept of Type2 property class provided and implemented by frameworks, I find a new way to clean and optimize my code:
  • Dependency Injection (OSGi), dynamic object allocation and redirection - can be done by calling set on the required properties, by having a smart get or by setting a dirty flag. Whatever the solution be, it is totally transparent to the business code declaring the property field.
  • Persistence framework providing validations (from DB type, data and annotations) and listening to property changes.
  • Swing bindings of course, but used by higher level framework that can manage full business objects and all their properties.

What I'm gonna' do!

Independently of the wild crazy idea of properties by annotation as a language feature, the property list introspection will be done using a unique abstract enum java.property.PropertyDefinition<B,T>:
public abstract enum PropertyDefinition<B, T>
implements PropertyAdaptor<B, T> {
public abstract T get(B bean);
public abstract void set(B bean, T newValue);
public abstract Property<T> getProperty(B bean);
public String propertyName() {
return name();
}
public Class<B> getBeanClass() {...}
public Class<T> getPropertyType() {...}
public Annotation[] getAnnotations() {...}
public boolean isReadable() {...}
public boolean isWritable() {...}
public int getFieldModifiers() {...}
public int getGetterModifiers() {...}
public int getSetterModifiers() {...}
}
And the javac generated code will look like:
public class Person {
[...]
public static enum properties<T> extends PropertyDefinition<Person,T> {
<String> firstName,
<String> lastName,
<Integer> age
}
}
The above work is a simple merge of Remi's implementation and the abstract enum. On top of that, I'll implement the generic Type2 thing. First an annotation needs to be associated with a Property<T> (Type2) abstract class. I'll use a meta-annotation PropertyClass, so anyone can declare a future @Property annotation.

The meta annotation:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface PropertyClass {
Class value();
}
The specific annotation for a basic property:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@PropertyClass(BasePropertyImpl.class)
public @interface BasicProperty {
PropertyAccess value();
}
The specific annotation for a property that can be bound:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@PropertyClass(ObservablePropertyImpl.class)
public @interface ObservableProperty {
// Using FCM
#void(PropertyStateEvent) onSet default null;
}
Then, the bean class:
public class Person {
@BasicProperty(PropertyAccess.READ_WRITE)
private String firstName;
@ObservableProperty(Person#firstNameChanged)
private String lastName;
@BasicProperty(PropertyAccess.READ_ONLY)
private int age;

private void firstNameChanged(PropertyStateEvent se) {
System.out.println("property changed "+se);
}
}
And so the boilerplate code generated by javac will look like:
public class Person {
@BasicProperty(PropertyAccess.READ_WRITE)
private final BasePropertyImpl<String> firstName =
new BasePropertyImpl<String>(properties.firstName);
@ObservableProperty(Person#firstNameChanged)
private final ObservablePropertyImpl<String> lastName =
new ObservablePropertyImpl<String>(properties.lastName);
@BasicProperty(PropertyAccess.READ_ONLY)
private final BasePropertyImpl<Integer> age =
new BasePropertyImpl<Integer>(properties.age);

private void firstNameChanged(PropertyStateEvent se) {
System.out.println("property changed "+se);
}

public static enum properties<T> extends PropertyDefinition<Person,T> {
<String> firstName,
<String> lastName,
<Integer> age
}
}
And all accessors to person.firstName will be wrapped in javac with person.firstName.set() and person.firstName.get().

This proposition respects Object Orientation, it is very flexible and open for future extension. It removes a lot of boilerplate code and makes Java ready for easy-to-use components. For example, by applying this solution IoC frameworks can really be "inverted". What I mean by that is that instead of trying to invoke setXXX() on the components at the right time (object life cycle and/or component state), they can simply provide a state-of-the-art getter in the property type2 class that will fetch the right object at the right time, all the time. This is transparent decoupling, keeping type safety and without using reflection.

So it solves some (but not all) of the issues like:
The only thing that property as a language feature will have a hard time providing is dynamic creation of properties, but that's another story.

A few more white nights are ahead of me so I can put all this in kijaro, I guess ;-) Unless someone finds a good reason to stop me in my wild Java experience!

Wild Java Properties, The Road So Far

First I'd like to thank Alex Miller for keeping good track of links regarding properties in Java 7,
I don't have to repeat them!

I'll just add a few links:
  • The kijaro project has the first version of Remi Forax's Property implementation.
  • The google doc by Remi that documents this first usage of property as a language feature (as far as I know it's the only one).
  • The usage of this implementation with Beans Binding in Remi's blog entry.
After integrating my work on Abstract Enum in the kijaro project (abstract enum branch, to access it you need to be a kijaro reader), I started merging Remi Forax's branch with one simple goal: Having the list of properties of any class automatically generated (syntactic sugar) as an enum! One of Remi's comments about using enum for property enumeration complained on the inability to use Generics with enums. With Abstract Enum it is possible, and I'll show how here.

The benefits of using abstract enum to enumerate properties are:
  • Easy and type-safe properties introspection: MyClass.Property.values() returns the collection of MyClass.Property<MyClass,?>;
  • Easy and type safe conversion from a string to a property object: MyClass.Property.valueOf("firstName") returns MyClass.Property<MyClass,String> MyClass#firstName;
  • I can switch (aProperty) {case firstName:...};
  • MyClass#myProperty is an instance of MyClass.Property and so I can use == comparator with no risk.
  • I can use MyClass#myProperty in annotations that accept the abstract Enum PropertyAdaptor as parameter. Things like @LinkTo(Person#firstName).
Before I started coding I played, reviewed and analyzed the current implementation, and I will try to describe how it works. Here is the basic example using property keyword ("property" is not really a keyword since it can be used only before the type declaration of a member, but anyway):
public class Person {
public property String firstName;
public property String lastName;
public property int age;
}
Analyzing the syntactic sugar generated by Remi's implementation, I needed to clarify where are the Type1 (Bean-independent property: aka per-class, property-proxy, property adaptor) and Type2 (Bean-attached property: aka per-instance) properties classes and instances. These types are nicely defined in Stephen Colebourne's blog Java 7 - Properties terminology. Remi calls the Type1 a "Property Literal" and it is implemented with an anonymous class inheriting from a new class in the JDK: java.lang.Property.

For Type2 there is no need for a class since the basic property boilerplate code generated is:
private String firstName;
public String getFirstName() {return firstName;}
public void setFirstName(String param) {firstName = param;}
The above code is the syntactic sugar created by javac, and so not editable in any way. For the Type1 the generated code is:
public static Property<Person, String> firstName() {
return new Property<Person, String>(
"firstName",
String.class,
Person.class) {
public String get(Person person) {return person.getFirstName();}
public void set(Person person, String s) {person.setFirstName(s);}
};
}
And for Bean introspection (getting the list of properties) another piece is generated:
public static Property<Person,?>[] properties() {return $PROPERTIES;};
private static Property<Person,?>[] $PROPERTIES = new Property[]{firstName(),lastName(),age()};
This is the code for a basic property, but there are more features implemented like:
  • Generating a getter method only or a setter method only
  • Implementing getter and setter inline of the property declaration
  • And the very powerful 'bound' which allows automatic events on setXXX() without boilerplate code.
For example if lastName is read only with a provided block and age is bound, the Person class will be:
public class Person {
public property String firstName;
public property String lastName get { return "XXX"; };
public property int age bound;

protected <B,T> void propertyChanged(java.lang.Property<B,T> property,Object oldValue,Object newValue) {
System.out.println("property changed "+property+" "+oldValue+" "+newValue);
}
}
Here is the generated code:
public String getLastName() {return "XXX";}

public static Property<Person, String> lastName() {
return new Property<Person, String>(
"lastName",
String.class,
Person.class) {
public String get(Person person) {return person.getLastName();}
public void set(Person person, String s) {throw new UnsupportedOperationException();}
};
}

private int age;
public int getAge() {return age;}
public void setAge(int param) {
int oldValue = age;
age = param;
this.<Person,Integer>propertyChanged(age(),oldValue,param);
}

public static Property<Person, Integer> age() {
return new Property<Person, Integer>(
"age",
int.class,
Person.class) {
public Integer get(Person person) {return person.getAge();}
public void set(Person person, Integer s) {person.setAge(s);}
};
}
That's a lot of syntactic sugar, but that's the point of properties, isn't it: Value objects WTF!!?!!2!. This property implementation works very well for Swing and Beans Binding implementation like Remi's demo shows. You can also write very quickly generic equals and hashcode methods based on the properties list. But, as a backend developer I also need properties.

Property as language feature is not just syntactic sugar generation it's really solving a problem that just CANNOT be solved in Java today: How can I safely (which means maintaining type safety) pass a field or method (which are the elements that represent a property today - getter/setter) to a framework like JPA, WebBeans, Validations framework, Wicket, Swing Bindings, and all the others developed out there? Today, you NEED to pass a String (EL) and do reflection. That does not make sense. When I know a UI component is bound to Person.firstName, why do I need to write bind(Person.class, "firstName") and loose type safety, compiler existence check (whether or not firstName property exists), and so refactoring ability.

Next post, I'll expose how I wish to have properties for all ;-)

The Java Wild series!

This blog has been silent for more than 2 months now... And this just after I started some good work on the great kijaro project. I'm really happy to say that it was for a great trip to Guatemala where we picked up our newly adopted child.






This is the first time ever since I discovered coding (1985) that I did not write one line of code for 2 months in a row ;-) Very relaxing, and I still have a very hard time going back ;-)

Anyway, even without coding I've spent a lot of time reading blogs and article about The End of Java and other worrying thoughts. All this ended up in this Java Wild entries. Playing with Kijaro and the different patches that can change the Java language clarified what I really want from Java and the platform.

The conclusion is that the most critical feature needed for Java 7 (and maybe even for 6 update N) is: Modularity. The JDK needs to be built out of nice dependent modules with superpackages and JSR-277 (or OSGi) packaging. This is critical for the future of Java. And Stephen's blog entry about the JCP inefficiency and OSGi vs. JSR-277 war is, for me, the darkest cloud above Java.

Mostly my thinking about the topics covered in my Java Wild series goes: "If it helps write to modules: good". But beside this I really went wild, and it was fun.
  1. The first entry is about properties that really got bad publicity lately. One entry was too much, so there is: "Wild Java Properties, the Road so Far" and "Wild Java Properties, The Wild Part".
  2. The second entry is about extension methods and how Modules and API can really benefits from them.
  3. And the third is, again, about checked exceptions.

I wanted to publish all these in one go, because I hate suspense ;-), but time is running out. So, I'll do it in steps.

Anyway, the "sad" conclusion of all this work and thinking is that I bought the Scala book, and starting today, will start playing on the grass of Java neighbors. May be, it is really greener?