Categories

Archive pour la catégorie ‘Java’

A tribute to Groovy

My life as a developer :

Update : it’s my life as a professional developer, since my life as a programmer began in 1983 on a Sinclair ZX81

  • 1995 : Java 1.0 beta is released. I begin playing with it. Hotjava browser, applets are all the rage. Soon after, the infamous « Loading Java » status bar message in Netscape is the signal that you’ll loose control of your browser for at least 15 seconds while the JVM loads an applet.
  • 1996 : Academic and toy projects in Java. Since JDBC is not out yet, I decide to write my own DBMS in Java. It works but of course it’s crappy. Cloudspace, Hypersonic and over 100% pure Java DBMS are safe.
  • 1997 : Wrote an HTTP 1.0 server in Java, with pluggable controller modules named « lumps » (Java <-> coffee <-> sugar lumps, nudge nudge wink wink). Damn, I should have thought about « Servlets ». Wrote a lump which interprets a server page language not unlike ColdFusion (that is, as crappy, but at least at that time it already ran on the JVM). Wrote my first server pages which could access an Access database through the freshly released JDBC-ODBC bridge and display data on my browser. As a trainee, I have to work on a project built with Borland Intrabuilder. That was both interesting and very scary, since the thing was drowning in bugs.
  • 1998-1999 : Had to work, first part time, then full time. Of course, it’s all about EJB 1.0 beta and my lead developer Laurent Quérel and I try to build something around EJBs and Persistence Powertier which would not look totally unlike Hibernate today. I begin to get the abstraction addiction. It’ll take me a few years to get rid of this addiction.
  • 2000-2001 : the future is on the mobile phone, and WAP is going to be the next web. In full abstraction addiction mode, my team and I develop our own specialized application server, so that you can write a web application once and browse it from any web-enabled device, the presentation being abstracted and adapted to the zillion different devices that would soon access our apps. We develop half a dozen application with this application server before the net bubble explodes and we realise that it would need a few more years before the Internet on a mobile phone would become a Big Thing. One good thing, though : when we began this application server business, we drop all the EJB nonsense. We built our own IoC container, much like Spring. And we didn’t need an ORM, because all we needed to map to was XML, dude. This was the time when I read & wrote a lot on the xml-dev mailing list.
  • 2002-2003 : I’m done with the abstraction addiction. I’ve got a challenging job, lots of work to do, and no much time to think and ponder about abstracting anything. The code I write must be straightforward and must get things done. I’m feeling more and more irritated by the verbosity of Java and the zillion XML configuration files I’m forced to write. An IoC container is a nice thing, but honestly, I sometimes feel that a simple scripting language would be much more suited to configure my apps. I begin experimenting with Jython. I also try for the first time Groovy, which is under development, but the language seems a bit goofy at the time, a patchwork of good ideas but nothing really as coherent as Python.
  • 2004 : OK, I finally get it. I need a dynamic language. I hesitate between Python and Ruby ; Ruby is more interesting but less polished, and at the time, a lot of documentation is badly translated from Japanese. I choose to invest in Python. I fall in love with Python. I use it first for any kind of data massaging tasks, then progressively for web development. I begin tinkering with mod_python, which will eventually lead to my active participation in the project. In the same time, I experiment with Zope, find it fascinating and decide to use it for a classic web application project. Big mistake, that I’m still paying for four years after.
  • 2005 : Ruby on Rails appears. People marvel at the thing. I don’t get that the scaffolding demos that begin to invade the blogosphere have nothing to do with the real power of RoR. When watching those demos, I told myself « OK, that’s really cool, but real apps are much more complicated than just CRUD screens ». Of course, Sherlock, but do you really expect that things will be brighter in any other framework you can choose if even the basic stuff like CRUD is complicated ? Oh, and on August, the 23rd, my daughter Violette was born.
  • 2006 : it’s time for a comeback to Java (nothing to add to what I’ve wrote at this time). I also work 50% on my time for Yoono, once again with Laurent Quérel. One day, walking back from lunch in a Parisian street, I recognize Guillaume Laforge, which I knew took over the leadership of the Groovy project. I tell him « Excuse me, but aren’t you Guillaume Laforge » ? Yes indeed – I think he found it a little creepy to have reached celebrity to the point of being recognized in the street by total strangers :) . Anyway, at the time, in the street in front of our offices, I naively propose him to work for Yoono, as we were looking for top notch Java developers. Of course he declined politely, but now that I know what Guillaume was working on, I’m glad he did !
  • 2007 : for a new big project, I hesitate quite a long time between Java + Spring + Hibernate + Struts, Python + Django and Ruby on Rails. I finally decide to give RoR a go. It’s awesome. Nothing to regret as of today, except maybe my choice of MySQL + InnoDB tables which gives strange problems with table locks. Apart from that, I get the same rush than anyone else trying RoR : freedom and power ! However, the deployment model sucks. What, a single-threaded application server ? You have to launch multiple servers and load-balance between them using Apache 2.2 mod_proxy_balancer, lighttpd or Pound ? OK, I’ve done it with mod_proxy_balancer and it was no rocket science, but seriously, It’s a bit of an hassle to manage. And the performance is not so great, I squeeze 60 reqs/sec per instance, with is totally sufficient for the app we built, but come on ? I get easily 4 or 5 times more reqs/sec with any badly configured Python or Java stack (please don’t flame me for this obviously inane benchmark).
  • 2008 : Grails 1.0 is out. I have a new look at Groovy. It has been totally morphed into one of the coolest dynamic language out there under the lead of Guillaume Laforge. Groovy is now a true dynamic language, with a seriously good feature set. All my favorites from Python and Ruby are there. And it runs, fast, on the JVM. What can I say ? It looks almost perfect. Of course, writing such a language is a difficult task, and things could get ruined by weird lexical scoping interaction with closures or things like that (no, I don’t think about any particular language, Ruby). But at first sight, it looks very, very good. Could I ask more ? A nice web framework running on top of the JVM ? Well, Grails sure looks promising, I can’t wait to try it on a real application ! Performance-wise, my first benchmark tell me we’re far above Ruby on Rails. Oh, and IntelliJ supports Groovy and Grails with a pretty cool plugin, too. So I guess life as a web developer is now perfect, end of story :) .

And now for the punch line : I have now reached a position at work where I’m supposed not to code any more, at all.

WHAT ? All those years of sweating, fighting and yearning, and now that a good web development stack is out in the wild, I’m supposed to retire as a developer and become a friggin’ MANAGER ? I tell ya, there’s no justice anymore in this world.

Oh, and 13 years after, my browser still hangs for more than 15 seconds as soon as I try to load a page with an applet. Meanwhile, Flash objects load almost instantly, without any problem…

Neat trick : a Factory embedded in the interface of the object it builds

I’ve seen this trick performed by IntelliJ when using their integration with Google Web Toolkit. Usually, you’ve got an API defined as an interface, and you need a factory to build an implementation of the interface. The factory uses some configuration information to choose an implementation :

public interface MyService {
     // ...
}

public class MyServiceFactory {
   public static MyService getMyService() {
         // ... load configuration and return an instance of a class implementing MyService
   }
}

// Usage example :
MyService serviceP = MyServiceFactory.getMyService();

Of course there are hundreds of variations to this pattern, with or without singletons for the factory etc. The trick I’ve seen performed by IntelliJ relies on the fact that you can define an inner class in an interface :

public interface MyService {
     // ...
     public static class Factory {
         public static MyService getMyService() {
             // ... as before...
         }
     }
}

// Usage example :
MyService serviceP = MyService.Factory.getMyService();

It doesn’t change much but it feels cleaner like that ; of course you can’t implement factories of factories of factories, if that’s your pleasure, but to me it’s way simpler to have the factory defined right in the interface.

Java Map literals, continued

Here is a better map literal, since it keeps keys close to their values :

public class Literals {
     // ...
     public static <S, T> MapBuilder<S, T> map(S key, T value) {
         return new MapBuilder<S, T>().map(key, value);
     }

     public static class MapBuilder<S, T> extends HashMap<S, T> {
         public MapBuilder() {
         }

         public MapBuilder<S, T> map(S key, T value) {
             put(key, value);
             return this;
         }
     }
}

// Example usage :
import static Literals.map;
Map<String,Integer> example = map("hello",1).map("world",2).map("!",3);

Java map litterals

Following my previous post, here is a map literal :

 public final class Literals {     public static <T> List<T> list(T... itemsP) {         return new ArrayList<T>(Arrays.asList(itemsP));     }     public static class Mappable<S> {         private S[] keys;         private Mappable(S... keysP) {             keys = keysP;         }         public <T> Map<S,T> to(T... valuesP) {             HashMap<S,T> resultP = new HashMap<S,T>(keys.length);             int lP = keys.length;             for(int iP = 0;iP < lP;iP++) {                 resultP.put(keys[iP], valuesP[iP]);             }             return resultP;         }     }     public static <S> Mappable<S> map(S... keysP) {         return new Mappable<S>(keysP);     } } 

Usage example :

 public void testMap1() {     Map<Integer,Integer> map1P = map(1, 2, 3).to(3, 2, 1);     // intValue needs to be used to disambiguate the call     assertEquals(3, map1P.get(1).intValue());     assertEquals(2, map1P.get(2).intValue());     assertEquals(1, map1P.get(3).intValue()); } 

Java list litterals

I was recently deploring the lack of a list litteral in Java. It turns out that since Java 1.5, thanks to Java generics, variable length argument lists, and static import, one can get a rather good list litteral :

import junit.framework.TestCase;
import java.util.List;
import static java.util.Arrays.asList;
public class LiteralsTest extends TestCase {
     public void testList1() {
         List<String> list1P = asList("Hello","this","is","a","test");
         assertEquals("Hello",list1P.get(0));
         assertEquals("this",list1P.get(1));
         assertEquals("is",list1P.get(2));
         assertEquals("a",list1P.get(3));
         assertEquals("test",list1P.get(4));
     }
     public void testList2() {
         List<Integer> list1P = asList(3,2,1);
         // intValue needs to be used to disambiguate the call
         assertEquals(3,list1P.get(0).intValue());
         assertEquals(2,list1P.get(1).intValue());
         assertEquals(1,list1P.get(2).intValue());
     }
 }

The name could be a bit better, so it’s just a matter of building an alias :

public final class Literals {
     public static <T> List<T> list(T... itemsP) {
         return Arrays.asList(itemsP);
     }
 }

Or even, if you want the list to be mutable (Python-style) :

public final class Literals {
     public static <T> List<T> list(T... itemsP) {
         return new ArrayList<T>(Arrays.asList(itemsP));
     }
}

A whole new bag of tricks is opening…

Hello again, Java !

For my currently biggest project at work, I’ve decided to get back in the flow and write the code in Java. These are a few reasons why I chose to use Java instead of Python for this particular occasion :

  • Performance. I literaly have to parse gigabytes of fixed-width formatted data, perform business logic and computation on it, then spit ou millions of rows in output files and in RDBMSes. Even when restricting the scope of my benchmark to the first part (data parsing), I get at least 5 times and up to 20 times better performances using Java versus Python + Psyco.
  • Productivity. If performance what all that mattered, I would have done it in C++, but hey, I really need to focus on the task at hand and not to fight with the compiler. Plus, it’s difficult to find, test and integrate third party libraries. In Java I could find and test two RETE engines (Jess and Drools) in less time than I would have spent just figuring how to build or integrate an obscure open source or a very expensive library.
  • Of course, Python is highly productive, but in this corner case it’s not performing well enough. Plus, I have to confess with a shudder that it’s not enterprisey enough for the context of this project, meaning that if I tell my client that the project is implemented in Python, I’ll get a lot of worried faces. Some people will be worried about how they will be able to maintain a project developed in a language they don’t know (yet), and some other people will just be worried because Enterprise©™ means Java and nothing else.

Of course, after having spent two years coding exclusively in Python and C++, I was quite happy to come back to my former favorite programming language. I wrote my first applet for the beta version of Hotjava, running on an SGI workstation at my school back in 1995, and was thrilled to see the same bytecode run on a Sun workstation, then later on my own PC. Write once run anywhere, yay ! I then proceeded to learn and use this language for 8 years, until I decided to have a taste of Python in 2003 and subsequently stopped writing Java code :) .

This two years experience of using Python and C++ in professional projects have been quite instructive, to say the least. Coming back to Java, I can’t help but notice huge limitations and design issues that plague the language and the platform. As long as I drank the Kool aid, I didn’t see all this, but coming back from abroad allows me to make a few remarks on Java, for what it’s worth.

The good

First, the good things.

Performance. Java was already darn fast, and it feels like it is even faster now. Granted, the JVM initialization time is huge, but once it gets its momentum, it really flies. I’ve been doing some small benchmarks with my friend Laurent Quérel, and Java can clearly compete with C++, now, even surpass it since its memory management system is highly optimized.

The language is simple. The Java language is clean and simple, even with the generics and annotation system that Java 1.5 brought. Java and Python are equally simple to me, at least from the perspective of a wannabe C++ hacker. I’d even go further and say that Python may be more complex and sometimes ugly looking, with things like the __init__ constructor name, subtelties with __new__, metaclasses and so on. Note that I’m writing about the language, not the libraries, we’ll see that later.

Tools. As soon as I’ve decided to use Java once again, I bought a license of IntelliJ Idea. This IDE is simply amazing. There are pretty good open source IDEs out there, Eclipse and Netbeans come to mind. I’ve tried them both, and they are good. But IDEA just blow them away.

Anyway, I don’t care what IDE is the best, my point is that the simplicity of Java and the fact that it is a statically typed language gives birth to really helpful IDEs, with top notch code completion, really helpful refactoring support, and so on and so forth. This is not the case for Python, because being a dynamically typed language it is very hard for the IDEs to understand the code being written and to assist the developer (and yeah, I know about the hypothesis that Python is such a good language that refactoring isn’t needed. Well, duh !). C++ has a better IDE support (I’ve heard that MS VS Studio 2005 has a vastly improved Intellisense system that fully groks templates) but it seems that mainstream refactoring support is scarce. So nowadays, only Java allows you to fully stretch and mold your code without breaking anything. Plus, having a good IDE support is really helpful for newbies.

Libraries. There are many, many more Java libraries out there than you can wave a stick at. Which could be a good thing, if they weren’t so darn complicated, but I’ll come to that in the « bad » part. Meanwhile, let’s enjoy the fact that almost anything you can think about is already implemented once or twice in Java, usually in an open source fashion.

Centralized and steady evolution of the standard. Some may despise this, but the fact that Sun is still holding the reins of the development of Java and its peripheral APIs means that the language still evolves way, way more rapidly than C++ does. Remember this article about C++Ox ? One version every ten years isn’t going to help C++ to survive in the current frenzy. And it’s not only a matter of survival, C++ could really use a little bit of improvement here and there.

The bad

Everything has to be an interface or a factory. Really, be it in the standard library or in third party APIs, everything has to be an interface or a factory. It looks that to the Java developer, concrete code is bad, abstraction is goood.

Heck, I was easily doing what needed do be done in a few lines of hyper-concrete Python code, but now that I’ve came back to Java, I’ve gone back to the ways of putting interfaces anywhere and feeling bad as soon as I need to give a real class name to instantiate instead of going through a series of factories to do the same thing. Which is stupid anyway, because without a good configuration system (which takes a lot of time to write or integrate, believe me, I’ve done both), then you HAVE to instantiate concrete classes anyway if you want something done.

To add insult to injury, factories are usually implemented with Singletons or static methods, which are one of the most static constructs of a program… What ? You don’t abstract around your factory class ? What if you want to change it ? Maybe you should provide a factory for your factories ? Actually, IIRC a situation like that exists in the JNDI API…

I guess that this problem tends to show that Java developers secretely want to code in Python and benefit from the freedom multiple inheritance and dynamic typing provides. Alas, we are stuck in Java, and we need to make sure we have interfaces everywhere, in the hope that this will help us to change anything in our code.

This is really ridiculous. I was doing a few tests with the Google Adwords API, just have a look at the code needed to make a simple API call. There is something very weird in having to build a factory instance (no singleton / static method this time) to build an instance that implements an interface for which we know there’s only one implementation ! A single constructor with the proper connection parameters would suffice, but no, that would be waaaaay too concrete.

I don’t have anything against the Google Adwords API per se, it just happened to be the latest example that I’ve seen of this widespread disease. For another symptomatic example, see this documentation about the Jakarta connection pool library and cry (there’s even a bit of IoC through an XML document, because you know, instantiating concrete class in Java code is baaaaaaad). One you’ve regained a bit of eyesight, have a look at an equivalent in Python. « But it’s not as configurable ! » I hear you yell. Yes it is, just read the documentation. It only happens that the defaults the code provide are sensible, so 80% of the time you don’t have to worry about them unless you find out that a configuration issue in your connection pooling is really the source of your problems.

No syntax sugar for tuples, lists, sets and maps. In Java, if you want to build a list with 5 elements, you have to instantiate the list and add the 5 elements. You cannot even chain the 5 add calls. Likewise for sets or maps. I understand that in light of the previous items, introducing some syntax sugar to build list would force the compiler to choose – aaaarghh – a concrete implementation of the java.util.List interface, and that would be taboo. But come one, there must exist clever ways to have a nice syntax for lists and map all the while retaining the sacro-saint implementation independence !

Everything must be an object. Code without class does not exists. You want to implement a callback function, bam, you have to implement an interface. Granted, you can do it anonymously, but this uses an awkard syntax, and generates yet another class that the JVM must load and instantiate just to execute one function. Please, I need first-hand function objects !

As a consequence of the two previous items, there is not functional programming support in Java. Even if it could be done with an interface defining a one parameter function returning an object, there is not way to map a function on a collection other than iterating manually on it. That’s a good thing we have new-style for loops in JDK 1.5, then. What is a single liner in Python, for example map(string.capitalize,["nIcOlAs","LeHuEn"]) becomes a chore in Java. Functional programming in Python is not perfect (lambda expression have been controversed for years now), but it works, and it’s a real time saver when writing, testing and even reading the code.

It’s pretty symptomatic that there isn’t any standard interface to represent a single parameter function object. This pretty basic building block is not abstracted in the land of abstraction. It’s because Java doesn’t like functional programming, even in an OOP disguise.

Everything is not an object. You cannot store integral types like int or long in containers. You previously had to wrap them in an Integer or Long instance, but now with the JDK 1.5 you don’t have to, thanks to the new « autoboxing » feature. Of course wrapping an int in an Integer instance requires at least 10 times more memory, but who cares ? Well, people like the ones who wrote FastUtil do, and I’d like to thank them, because I do too. But wait, maybe new new generics feature could help us there ? Well, unfortunately…

Generics suck badly. Really. For instance, you cannot use integral types as type parameters. And even if you could, the result would NOT be an optimized ArrayList<int> class that would store ints and only ints, like you could expect from your C++ background. The generics implementation is merely a bit of syntactic sugar, and under the hood it’s always the same classes which store Object references. So you can get your ArrayList<Integer> and cry when watching your memory usage reach unforeseen heights, or turn to FastUtil.

Not only that, but the generics implementation is actually dangerous. It gives you a false sense of security, when security you don’t have because the current compiler cannot prevent you from getting a ClassCastException at runtime if you don’t pay attention (which was what the generics system was all about in the first place). I’ll give examples in future posts.

C++ templates have nothing in common with Java generics, except maybe the < > syntax. C++ templates are way more powerful than Java generics, and I really don’t understand why Sun has decided not to go this way. They had the opportunity of a real breakthrough, here, because even if C++ templates are powerful, they are also horribly complicated. Sun could have pushed templates within Java without breaking the bytecode, all the while giving us a simpler and thus better templating system than the one found in C++. So much for the opportunity.

Default parameters and named parameters are real time savers… Yet Java do not provide those features. As a result, you sometimes see tens of overloaded versions of the same method with different parameters. Of course, the particular version you need is often the one that is not implemented (there is a combinatory explosion of the number of possible overloadings), so you have to use the most complete version and enter the default value for the parameters you don’t care about by yourself. Take the above example about the connection pool configuration in Python : everything is done through one single function, and if you want to change something, you just use a named parameter.

Managing the JDK / JRE installation is a nightmare. I think I’ll leave this one for later, because it deserves a blog entry of its own. To sum it up, Downloading, installing and upgrading the JDK / JRE is a nightmare, and you often end up with tens of megabyte of duplicate files.

Tens years after, Java applets are still a joke. Java applets are disappearing progressively. The best hint that a web page contains a Java applet, nowadays, is that the web browser pauses up to ten seconds while loading the JVM and the application from the web. The situation has not improved since the first infamous « Loading Java » status bar message issued by Netscape around 1996 ! The only moment applets were running smoothly was when Microsoft implemented its own JVM and integrated it in Internet Explorer. Since they removed it, it’s a nightmare.

« No one cares about Java applets« , you may tell me. Oh really ? So I guess all those Flash thingies that you can see pretty much anywhere on the web don’t matter ? The virtual machine running Flash movies should be the JVM, not a proprietary VM from Macromedia. Flash movies could have been implemented in applets, it was just a matter of providing the appropriate development environment. But legal issues with Microsoft and Sun’s utter lack of competence in the desktop environment have just doomed the platform.

Java on the desktop is dead, and there is no replacement yet.The next result of the last two remarks is that Java as a distributed environment for desktop applications is a lost cause. There are a lot of thing going on right now (AJAX et al) that would never have seen the light if Java was successfull on the desktop. One could imagine that today’s desktop application landscape would be very different, if deploying Java desktop application was possible. But it’s not, and Sun is the only one to blame here.

What’s sad is that there are no alternative. A true, standardized, portable, high performance desktop platform is nowhere to be found. Nowadays, the only safe target platform is the web browser, with AJAX providing a little bit more interactivity than the request/response scheme previously allowed. But the web browser is far from being as powerful and integrated with the OS as a native GUI application could be, and writing portable code for the many browsers out there is a PITA.