I kind of want to do something different today. When I write I tend to write, in cliche blog form, in two modes: “Hey, look at this!” or “I’m going to be snarky and rant about this!” Today, I would kind of like to have a narrow conversation.
The advent of the invokedynamic JSR, as well as the continuing RoR vs whatever hype and framework proliferation in Java has brought a question to the forefront: where is Java going? I have some ideas that I would like to express. This isn’t necessarily a highly structured treatise, but more of a braindump.
However, I would like to hear what other people would like to see. I don’t mean this as an exploration of other programming models or an academic conversation in language design. Rather I would like people to look at (a) what tools are they using all the time that should just be there, and (b) what would really make your day to day life better, both of these taken in terms of the JSE — lets leave the web framework wars out of this for a little while.
One of the things that was just gawd awful was an idea floated a while back for integrating XML at the language level. You might have seem this discussion about API enhancements in Dolphin. I think there are some good ideas there, but it bothers me that the XML is dealt with as Strings. What we really need is something akin to JDOM there. That is a W3C compatible object model that is loose bound and easy to use. There have also been much more radical ideas floated, such as support actual tags IN the .java files as initializers and constructors.
My problem here is something much more fundamental, however: Java needs help with datatypes and method signatures. Cedric kind of touched on this recently though in a completely different context. Things like bound integer values have more uses than just performance in constrained systems: they help make the Java definition model closer to the XSD system. The problem with Java right now, especially in terms of XML mapping, is there is no way to constrain, for instance, a String value to a certain length or a RegEx match, or an Integer to a certain range, while XML Schemas provide for this. This means than any back and forth mapping of data really has to be started with the Schema as authoritative, and I really dislike this.
Moreover, method signatures do not provide means of giving schema hints for web services, and even a good “design by contract” ideology in the code. “public void doSometing( Integer foo, Integer bar )” has no indication that a null is allowable for bar, but not foo and Foo has to be between -4 and 27. Moreover when this gets translated into a SOAP call, there is no way for an Schema generator to make these determinations.
Now, annotations DO solve some of this problem, especially at the metadata level for back generating stuff, however, annotations don’t actually give you anything at the language level. Moreover, the finality of the java.lang types means that you cannot provide backward access to code if you created new types. This is the kind of thing that really does need to be in at the language level, and tighten up the signatures and datatypes.
The next thing I would like to talk about is the JRE itself, and from there I will spiral off into a couple of different areas, including my poo pooing of invokedynamic.
The JRE sucks. Really. Don’t get me wrong, I know that Mustang is faster (and I do find it funny how nobody bashes Ruby for being slow like they have Java for years). The problem is the JRE does too much, has too much legacy stuff in it nobody cares about in new software, and lacks things it really needs. To this end, I think the JRE needs to be broken out into 3 different distributions:
- A Classic or Server JRE that has everything.
- A desktop application JRE, perhaps just packaged and branded WebStart that includes what you need for most desktop apps, with some changes. Cut all the CORBA code and SOAP clients. Add Gecko as a JRE supported component. A binary repository system that is more Maven and less (like the current) WebStart.
- A slim JRE that runs as a system-service level. It could share the binary repo with the desktop, but it needs an intelligent download-as-needed jar system. It needs to start in less than 3 seconds on the average low-end desktop. This is an Applet runner and external call system. Basically, there is no reason Applets can’t perform as well as Flash. The second part of this goes to something I will talk about in a bit.
There are a few points here that seem to me to be critical to Java development.
First, applets need to be viable against Flash. This means they need to start fast; they need to download additional jars from the server on a JIT basis; they need better media support and access to devices for which Java now kind of sucks (see: CCD cameras, microphones, USB widgets — how old is the javax.usb JSR now?). For this I say executing them all in a persistent runtime environment, rather than an isolated JRE is the best case scenario — unless the Applet demands more than the standard limited sandboxing. Mostly, though, people want to use applets to provide things that a browser can’t — DnD, better comms, etc. I would also add to this system service a persistent applet runner application comparable to Dashboard, SuperKaramba or Konfabulator. This isn’t a great leap forward, but it would put a little of the sex appeal back in applets.
Second, this persistent Java runtime needs good hooks for external coding and code execution. SOAP is nice, CORBA is… well.. CORBA, but there is no reason the average little app needs this to make calls into Java. There are two points here, I will go with the more mundane first, then I will anger some people.
The first point of this is if Java applications are going to be a first class citizen on the Desktop then they need to work with the other desktop apps. MBeans should show up as COM automation components; they should show up as Apple Automator elements; they should show up as DCOP providers. We have all kinds of stuff right now — JNI is mediocre, Com4J is pretty slick and KDE-Java works OK. However, all of these are, for lack of a better description, outbound. A Java application should be as integrated with desktop tools as other desktop applications.
The other half of this goes to why I *hate* invokedynamic: let us not pretend that Ruby or Python people give a [expletive deleted] about being “first class citizens in the JVM. Ruby on JVM will never be “real” Ruby. Python on the JVM will never be *real* Python. Don’t believe me? How many Java people out there really care about IKVM? Do you really want your Java to be running in the CLR? No. What we need is an inbound call system that lets these other languages execute Java in the real Java runtime and execute their own code in their own runtime/interpreter. What Java really needs is a better external system for integrating with other APIs in the proper way.
Next on my rant list is SWING. Josh Marinacci is a friend of mine and he listens to my rants on this topic more than he would care to, I am sure. However, for all SWING is powerful, it is lacking in major ways that really matter to most developers. First, it lacks a real framework. Most of the reason people think Java apps are “slow” is because people write bad Java apps. However, people write bad Java apps because it is EASY too. For all the Matisse editor and the new Layout manager makes creating a good looking SWING app easier, even if you are using NetBeans, it doesn’t provide a framework for separate UI threading, which makes UI response feel bad as comms and processing is down inline. Secondly, all these years after the JavaBeans spec, SWING still doesn’t have a decent databinding system, nor is it in general Collections aware. Next to things like Flex and Laszlo, this is a killer in the “RIA” space. Lastly, UI needs to be declarative, not programmatic. Avalon and Sparkle are truly awesome. XUL is really nice. Even ObjC/XCode on the Mac with its “freeze dried” objects is not bad. Next to all of these, SWING has an Everest-style learning curve to work with proficiently.
Next, we should be able to create a Dynamic Proxy off an Object class. This seems a little more academic than I want this discussion to be, but giving this ability would require a lot less invasive changes to the language than invokedynamic but would allow Java to see RoR style frameworks.
Finally, JNDI needs to not suck. Really, looks at what Spring does in terms of factory providers, configuration and service registries. There is no reason for it, except everyone has always hated the JNDI interface. Perhaps we just need a whole new system here, rather than overhaul JNDI, but we need something that knows how to get SOAP services, use basic factories and handle some basic config stuff without the LOC overhead than JNDI always seems to have. EJB3 takes a big step forward on the J(2)EE spec. JAX-WS is a bid step forward for web services. It is time for javax.naming to get some serious love.
This isn’t a really well structured list of things or particularly well correlated, but it does represent my wish list for Java in small, discreet quanta. Now the question: what do you wish Java had, or alternately, why am I a moron?