Monday, November 12, 2007

The Ugly Duckling of Java!

It took me time to find a good title. It could have been things like:
  • What's so ugly about explicit type parameters?
  • Done with inference!
  • Let's pave the way for reification and promote explicit type parameters!
Chaotic java already made a similar point: Can someone please explain type inference to me?.

But all these compiler language terms, are showing off for no reason. The problem is not so complicated, but the stakes are high. Like Eric Burke says in his blog A Syntax Trick I Was Not Aware Of, there is a syntax in Java that very few people use and encounter: Explicit type arguments or parameters. One of the rare places where you may have encountered it, is in the JLS and javac code and test code. So, it looks like:
List<String> empty = Collections.<String>emptyList();
The first reaction, for most Java developers, is: WTF?!

But I remember the first time I started converting some 1.4 code to use generics and wrote:
Map<Integer, Map<String,Thing>> messages;
Wow, that's a lot of <>! And when I saw the amount of bugs the compiler gave me (wrong casting and objects in put()), I really thanked the <>, and asked for more ;-)

Why, the Java compiler wants to hide <> of explicit type parameter?
On IntelliJ the <String> before the emptyList method, is underlined with the remark: Explicit type arguments can be inferred. Basically, it means the compiler can be smart enough to replace the content of <> with the correct type. Great, at first. But wait?
Like Stephan says in Explicit Static Types are not for the Compiler, but for the Developer - Duh, the compiler knows a lot more stuff. He can remove a lot of all this types we are writing.
I love strongly type Java, and all the types repetition. I love the types in the code because it's more readable.

Question: Why explicit type parameters are an exception?
Answer: It got the Ugly Duckling stamp for some reason! Some said that it was dangerous for kittens!

Personally, I think there are 2 reasons:
- When Java 5 came out it looked like too much <> all over and Sun tried to remove some unneeded ones.
- It lacks consistency. I would really like to know, why explicit type parameters are declared BEFORE the method name? When, in constructor and type declaration, they are declared AFTER. In the later, they are enforced, and everybody is using them!

Another worrying inconsistency that may appear in Java 7 is around the "Short instance creation" issue. For example the nicest proposal so far is Neal's constructor type inference. I really like this proposal because it enables inference to work, but you SEE it working. It's not hidden woodoo compiler stuff. According to this proposal instead of:
List<String> list = new ArrayList<String>();
you'd write:
List<String> list = new ArrayList<>();

Again, a strange sense of peculiarity for the method emptyList. In the type inference block of Alex Miller Java 7 page, you see the peculiar treatment of methods compare to types.
Why nobody wants:
List<String> empty = Collections.<>emptyList();
It's the same, no? Let's be consistent!

Now, the main big issue that I have with this inference vs. explicit issue, is that it's moving Java away from reification of generics. It's going in the wrong direction. I just refactored some JPA code from:
// The Class of the bean implementaion provided by
// the framework and unknown to the client
Class implClass = ...;
MyBeanInterface b = (MyBeanInterface) em.find(implClass,pk);
to
MyBeanInterface b = em.<MyBeanInterface>find(implClass,pk);
It may be just changing casting to generics. But that's the point of generics being way nicer and more powerful.

The other point is, when generics will be reified I'd be closer to the perfect methods:
MyBeanInterface b = em.<MyBeanInterface>find(pk);
or with VISIBLE type inference
MyBeanInterface b = em.<>find(pk);
These methods will find the implementation from the interface. Exactly what I need, the client code doesn't know about the implementation class, and the code is very clean and readable.

Today, because of erasure, in most methods (80%) that use generic types, you end up having Class<T> or Collection<T> as a parameter. So, inference works most of the time, and it's saving us from having to visualize the Ugly Duckling. For sure, it worked.

Now, for the 20% that still resist the roman empire of javac guru inference power, a new wave is coming. They want to write a "smarter" javac, that will make inference work (Check Kevin Bourrillion and Bob Lee comments here).

Here, there is a shift in the javac thinking, and it's going against readability, since: The "smarter" (or magical) the compiler is, the less "readable" your code is. Furthermore, inference will never be (by definition) 100% sure. So, why bother? The final code is more readable anyway...

IMHO: The kittens are safe, and reifying generics is more important than inference.

Thursday, November 8, 2007

Is JSF following EJB road?

First I have to be clear: I don't like JSF!

But, I did not like EJB 1.0 when it came out. And still, I did bet on it's success.

When EJB 1.0 came out I just finished my personal implementation of a CORBA Application Server, so this new Specification was "way below" my stuff. I was young, but still you cannot stop the machine coming from Sun, BEA and after quite some time IBM.
EJB came in a world were crazy techies (like me) thought they can build great servers which can handle enormous load. So, this specification really calm down crazy development and provided a good base for containers (usage and implementation).
But, it was flawed, right from the beginning.
All the API, interfaces and design concentrated on showing off the "great" power of the Application Server. Look how I can passivate/activate, look I can do security and transaction, and look I even save in DB for you. And for every "look" as a poor developer you needed to answer (implement, declare) something.
There was no escape, your code was full of unwanted pollution.
EJB 2.0 did not solve the problem and actually added more "look" at my beautiful AS: Messaging and CMP.

We had to wait for JBoss guys to take over EJB specification for 3.0, to finally end the developer nightmare.

And now, the funny trick. Please replace in the above EJB with JSF...
Amazing, it fits.

JSF came when Web UI was a total mess (All Struts usage override most configuration and basic classes) and everyone had his own "best/better" implementation.
So, JSF did some clean up in Web UI design and implementation.
But, JSF is really "showing off": Look my nice lifecycle in 42 steps, Look my nice big list of jsp tags/attributes, Look my nice EL, Look my nice XML configuration, and so on.
By "showing off" I mean that you need to fill all this with a lot of unreadable and incomprehensible repetition. And the worst of it you need to master all this in order to:
- debug correctly,
- integrate external stuff (Ajax4JSF and so on),
- create just one JSF UI component (Does someone sells T-shirt with: I wrote my JSF component! without breaking the lifecycle?),
- write stupid HTML pages.

A really good description of all JSF flaws are listed in Gavin blog: EE6 Wichlist
In this blog entries, the first one on EJB the second on JSF, looking quickly at the code examples you understand the gap. EJB is full of nice Annotations and Meta Annotations (the future for sure), and JSF full of ugly XML and Expression Language (scheduled to die).

The biggest conceptual flaw of JSF is the usage of EL.
EL is breaking encapsulation, in term of IoC: it's on the wrong side of the road. Ophir pointed me to a nice essay from Terence Parr "Enforcing Strict Model-View Separation in Template Engines ", that really nicely proves my point.
A UI definition (Web page, Swing panel, ...) should not know about the object graph. If I am a UI designer, I'm not a business modeler.
The answer is in architecture like Wicket and JSR-295 (The EL in this Beans Binding is due to the lack of property support).
In these good architecture: The UI components have an ID related to the page/panel, and the Java developers bind data to these components and receive events from these components. This is the good way to do UI, integrate UI design and manage UI logic. From experience, it works great.

All the other flaws are due to the age of JSF and the fact that it was written for ugly request/response Web UI behavior.

So JSF is today at the stage of EJB 1.0, I can see JSF 2.0 pushing more in the wrong direction, and so having finally a JSF 3.0 were developers will stop having nervous shake when they hear: JSF!

Friday, November 2, 2007

Playing with the full abstract enum!

Since Neal Gafter released the closure prototype, Ricky Clarkson has been having a lot of fun. He wrote 2 nice blogs:
Both have "Java 7 Example" in their titles - So closures is going in Java 7: Got that!

The Java code is a little scary at first, but after a while it works, you can read it. IMHO: all the inlining of closure syntax can get very confusing. I know they supposed to be, but I played with the code and when you create variables for the closures it helps increased readability.

Anyway, I really like the fact that you can now really test, today, closures and their impact on your code.
All this, gave me the idea to do the same for abstract enum.

The reasons for abstract enum (and there are more I'm sure) are:
  1. I wanted abstract enum for solving the property binding issue in a type safe way.
  2. I found out that you cannot use String Enum.name() and int Enum.ordinal() methods as annotations parameters.
  3. I know there are way too many strings in annotations (methods, fields, scopes, states, package, groups, ...). I don't like strings describing my code.
  4. While I was at it, Steven Coco asked for generics in enums, so it's there also. That happens to be quite an interesting feature, that was already there from Neal (but buggy ;-).
For all those reasons I know abstract enum is a good thing. Changing the javac to implement this feature is at least 2 orders of magnitude easier than implementing closures, so it was within my reach ;-)

I have exposed some mercurial repositories for langtools and for the jdk. You need to have a mercurial working copy of openJDK, then inside langtools run:
hg pull http://www.jfrog.org/hg/openJDK/MASTER/langtools

You can "hg log" to see what's going on, then do:
hg up

The patch for the JDK is very small, and actually (in my view), it is just another valid way (in a Java 5 environment) to do Class.isEnum() and Annotations parsing. The new JDK is needed for the tests to pass because abstract enum are not considered enum by java.lang.Class otherwise :-(.

Type safe reflection


The solution for field binding is straight forward. The abstract enum looks like:
public abstract enum FieldDefinition {
private Field reflectField;

public Field getField() {
if (reflectField == null) {
Class modelClass = null;
try {
modelClass = this.getClass().getEnclosingClass();
reflectField = modelClass.getDeclaredField(name());
} catch (NoSuchFieldException e) {
throw new ObjectMappingException("Field " + this +
" does not exists in " + modelClass, e);
}
}
return reflectField;
}
}

And to use it in my Value Object it looks like:
public class ModelMock {
private String firstName;
private String lastName;
private int age;

public static enum fields extends FieldDefinition {
firstName, lastName, age;
}
}
Of course is not as good as properties as a language support, but it solves my problem. From the above, I extended to property using generics. So, the PropertyDefinition takes the property type as generic parameter, so the generic getter/setter methods are generic typed. I took (type 1 and 2) from Stephen Colebourne's Weblog Java 7 - Properties terminology, and converted it.

Before abstract enum there was:
public class MyBeanBefore {
private String firstName;
private String lastName;
private BigDecimal height;
private Date dob;

public PropertyDefinition<MyBeanBefore, String> firstNameProperty() {
return ReflectionAttachedProperty.create(this, "firstName");
}
public PropertyDefinition<MyBeanBefore, String> lastNameProperty() {
return ReflectionAttachedProperty.create(this, "lastName");
}
public PropertyDefinition<MyBeanBefore, BigDecimal> heightProperty() {
return ReflectionAttachedProperty.create(this, "height");
}
public PropertyDefinition<MyBeanBefore, Date> dobProperty() {
return ReflectionAttachedProperty.create(this, "dob");
}
}
always using strings :-( And now:
@FieldPrefix("_")
public class MyBean {
private String _firstName;
private String _lastName;
private BigDecimal _height;
private Date _dob;

public static enum properties<V> extends PropertyDefinition<MyBean,V> {
<String> firstName,
<String> lastName,
<BigDecimal> height,
<Date> dob
}
}
This code actually compile and run (with the strange _ prefix ;-). Cool, no. The full code is under subversion here.
Now, with this, I can find usages, refactor, and get compilation errors for every binding using a field that does not exist. Like in here:
MyBean bean = new MyBean();
PropertyAdaptor<MyBean, Date> dobProperty = MyBean.properties.dob;
PropertyInstance<Date> dobPropertyInstance = dobProperty.getPropertyInstance(bean);
The type safety is not entirely true, since in my own Model class I get Runtime error for mismatching fields in the "fields" enumeration. This can be solve in 2 ways: make fields a keyword in Java and generate it automatically ;-), and/or test your model class and fields enumeration correctly.

abstract enum in Annotations


Like with closures, today when I encounter a problem in some projects, I often end up with: That will have been a lot faster and nicer with closures, and that will be solved perfectly with abstract enum. Now, I know it's the standard disease of being too much into it ;) But still I think it's true.

And abstract enum in Annotations is, for me, a really powerful feature.

So, one problem I had was with JPA schema names, cache names, and fields associations. All those information need to be provided as strings inside annotations. And of course they are repeating themselves a lot, they get misspelled, and basically you loose the strong typing.
So, I wanted to use enum (Schemas, Caches, Fields) to control the strings. But I would hit a dead end: Enum.name() is not a string literal, so you cannot use it in Annotations.
Now, with abstract enum, I have way more flexibility and type safety.
For the caches for example I can have Hibernate declaring something like:
public abstract enum CacheDefinition {
private CacheConcurrencyStrategy defaultUsage;
private String defaultInclude;

CacheDefinition(CacheConcurrencyStrategy defaultUsage, String defaultInclude) {
this.defaultUsage = defaultUsage;
this.defaultInclude = defaultInclude;
}

public CacheConcurrencyStrategy getDefaultUsage() {
return defaultUsage;
}

public String getDefaultInclude() {
return defaultInclude;
}
}
and then in my application:
public enum MyCaches extends CacheDefinition {
references(CacheConcurrencyStrategy.READ_ONLY,"all"),
business(CacheConcurrencyStrategy.TRANSACTIONAL,"non-lazy");
}
to use in:
@Cache(MyCaches.business)
class Action {
...
}

I wrote a blog (JPA NamedQueries and JDBC 4.0) about how to solve the string association issue in JPA named queries. Frank Cornelis answered with an addition that enables the reuse of query methods. The main problem with this addition is it adds more strings in annotations.
This case can also be solved with abstract enum.

So, if you reached there and you like the language feature of abstract enum: Vote for the RFE: 6570766.