This article is sponsored by the Java Community Process.
Dynamic Language Support on the JVM

A Conversation with Danny Coward

by Frank Sommers
December 11, 2006

Summary
Java SE 6 is no longer only about the Java language: SE 6 can be used to execute dynamic scripting language code as well. According to Danny Coward, Sun's Java SE platform lead, scripting language support is merely the first step in turning the JVM into the best possible execution platform for any dynamic language. Artima spoke with Coward about his new JSR 292, Supporting Dynamically Typed Languages on the Java Platform.

By including an implementation of JSR 223, Scripting for the Java Platform, Java SE 6 can be used to execute scripting language code written in dynamic languages, such as Ruby, Python, Groovy, or JavaScript. However, implementing a dynamic language interpreter on top of a virtual machine designed for a statically typed language is not without challenges, according to Danny Coward, Sun's platform lead for Java SE, and spec lead for the new JSR 292, Supporting Dynamically Typed Languages on the Java Platform.

On the eve of Sun's release of Java SE 6, Artima spoke with Coward about the future of dynamic language support on the JVM, about a new bytecode, invokedynamic, explicitly designed to support dynamic languages, about hot-swapping—the ability to change or add a method to a class at runtime—and about the goal of turning the JVM into an ideal target for dynamic language implementation.

Frank Sommers: One of the most interesting features of Java SE 6 is support for dynamic languages. Could you give us an overview of what is available in today's Java SE release, and what additional dynamic language support are you planning?

Danny Coward: We noticed over the last couple of years that the Java developer community—unlike the .NET developer community—was starting to experiment with dynamic languages. Dynamic languages are increasingly becoming part of many developers' daily work with Java applications, and are often used for prototyping, for places where you want to put something rapidly together. People have been using dynamic languages to glue those parts of a larger [Java] application together that need to evolve quickly.

JSR 223, Scripting for the Java Platform, is shipping today with Java SE 6. JSR 223 took the first step towards organizing the community of people focused on [dynamic scripting] languages. It does that, first, by providing developer APIs that allow mixing in fragments from other languages with Java code. The second piece of JSR 223 is a framework that allows developers to plug in scripting engines that interpret dynamic languages. In Java SE 6, we included the Rhino JavaScript engine so that out of the box developers can use JavaScript.

With the framework for scripting engines, developers can plug in their own interpreter engines as well. We managed to collect together more than twenty dynamic language engines at the java.net scripting project, scripting.dev.java.net. That's stage one for scripting language support in Java, and we delivered on that today.

JSR 292, Supporting Dynamically Typed Languages on the Java Platform, is the logical follow-on. Java is a statically typed language. The bytecode in Java expects certain information about what a return type is, and what the parameter types are for a method invocation.

When developers write interpreter engines for dynamically typed languages, they have to invent a lot of synthetic Java types to be able to fill in what's needed by the Java bytecode for method invocations. That makes those interpreters brittle: if someone changes the code, it's difficult to have to go in and reinvent all those synthetic types. Equally important, it slows down the performance. Interestingly, the Java virtual machine doesn't require to know statically what those types are, only the bytecode requires that.

JSR 292 is going to provide an additional bytecode that we will probably call invokedynamic. This provides an instruction to the JVM to make a method invocation, but without the types of the return value and the method parameters to be known in the bytecode. It's quite a technical, bureaucratic reason, but the implication is that it will speed up those interpreter implementations on the JVM, and will also make them more robust.

Frank Sommers: Could you give us an example of how invokedynamic will help a dynamic language interpreter perform faster?

Danny Coward: Suppose what you're doing is growing a collection by a certain size, and the return type [of that method] is Collection. In JRuby, for example, that kind of method might be implemented without having a specifically typed return value. Developers may understand in their heads that what's going to be returned is a collection, but there is not a specific type of the return [value], because [Ruby] is not a statically typed language.

Creators of dynamic language engines are in the business of taking, say, Ruby code and turning that into Java bytecode. When today's JRuby engine tries to convert that method call into bytecode, it has to create a synthetic interface to represent the return type. That isn't an interface a developer creates, but is one purely created by the JRuby engine [so] that it can take that method invocation and [turn that into] the bytecode. And that was just the return type—the same holds true for method parameters and exceptions.

JSR 292 removes the need for that synthetic interface. Today, dynamic language interpreters must output the methodinvoke bytecode, even when interpreting, say, a piece of Ruby code. Tomorrow, with JSR 292, they will be using the invokedynamic version. It will streamline the engine implementations because a lot of today's engines are worrying about creating new synthetic types and doing lots of book-keeping: when a method is called in seven or eight different places, they have to re-use that synthetic type all over the place.

Interestingly, this is not a feature of the language, but a feature of the bytecode. Java developers won't ever knowingly use a feature of JSR 292—it's something that goes on under the covers. What's most fascinating about this additional bytecode is that it will be the first bytecode [in Java] that isn't used by the Java language. We're proposing to add this bytecode purely for languages like Ruby, Groovy, BeanShell, Python, and so on. We have high hopes that those languages will run more quickly on the JVM than they do today as a result.

Frank Sommers: Will this additional bytecode work on today's JVM's?

Danny Coward: The other part of JSR 292 is to investigate something called hot swapping. In many dynamic languages, methods can be changed, and even added to a class, at runtime. That was the bread and butter of Smalltalk programming. The idea is to be able to adapt classes at runtime.

JSR 292 just got started earlier this year, and we're not certain how this will work out yet. But it's part of the expert group's task, and this may also contribute to performance improvements in dynamic interpreters. This feature will probably require some re-working of the JVM, and the JVM will require some changes because of this. The expert group will also have to be careful about security concerns. We're certainly not going to open up any security holes in the platform.

Frank Sommers: You mentioned many advantages of dynamic languages. Do you see Java itself becoming a more dynamic language over time?

Danny Coward: It might be interesting to look at how we could evolve Java into a dynamic language, but a lot of the strength of Java—the robustness, the maintainability, the ease with which you can publish APIs to other people—are afforded by Java's static typing. That's something we wouldn't actually want to change. Instead, by making other languages run better on the JVM, there will be less of a need to change Java.

We still think that the Java language is the best language for long-lived, maintainable, shareable application code. For applications that enterprises are writing, that need to survive for a long time, and where parts of those applications are going to be shared—perhaps between different development teams, maybe even shared in the community—the static typing features of Java, the modularity we're working on, the package structure, all those things together add up to a language that helps create long-lived and robust applications.

Where we see the use of dynamic languages is in a bit of a different design center: in situations where at least parts of an applications evolve very rapidly. In those situations, it's less important to be able to share code with someone else, or perhaps to be able to read a piece of code six months later and understand what it does. Instead, it's more important to be able to evolve the code quickly, and perhaps throw together a demo or re-work the way widgets are wired on a Web form, for example.

That's why JSR 223 is important: we allow Java developers to program parts of their applications in a dynamic language, and then either evolve those parts of an application into Java over time, or keep writing the more robust, longer-lived parts of the application in Java, and the rest in a more dynamic language. We're living in a community where people have very different tastes over the languages they want to use. Why shouldn't they want to use Ruby as well as Java?

Equally important, the Java language has been around for ten or eleven years, and we've made remarkably few changes to the language. We are very aware that it's absolutely possible to keep adding new features to the Java language to satisfy every possible need in the community. But if we did that, we would end up with a very complicated language. We'd end up with something like C++, where I think they favored language features over simplicity.

Frank Sommers: To what extent do you consider the JVM to be an ideal target environment for implementors of dynamic languages? Do you see any limitations in the JVM that makes such language implementors' tasks hard?

Danny Coward: The bytecode is the main problem today, that you have to invent synthetic types. That's why JSR 292 is important.

Theoretically, of course, the JVM can host any language interpreter. Many things are possible, and theory is good, but practice is even better. The key is to make [dynamic] languages perform really screamingly fast on the JVM, and that's what we're trying to do.

So let me turn this question around, and ask that if you are a dynamic language designer or implementor, why would you not want to target the JVM as your primary implementation platform? We've spent eleven years pouring the output of some really smart people into a cross-platform, scalable runtime that's very widely deployed in the industry. Why wouldn't you target that if you were inventing a new dynamic scripting language? What runtime is better?

In the future, there is going to be a new language that's going to be really popular. The Java community, and Sun especially, is very interested in making sure that we can bring all the benefits of the JVM to whatever that new language may be.

Resources

JSR 223, Scripting for the Java Platform
http://www.jcp.org/en/jsr/detail?id=223

JSR 292, Supporting Dynamically Typed Languages on the Java Platform
http://www.jcp.org/en/jsr/detail?id=292

The Scripting Project Home Page, which lists the 20 scripting engines currently included in the project:
https://scripting.dev.java.net/

Talk back!

Have an opinion? Readers have already posted 15 comments about this article. Why not add yours?

About the author

Frank Sommers is a Senior Editor with Artima Developer. He also serves as chief editor of the IEEE Technical Committee on Scalable Computing's newsletter, and is an elected member of the Jini Community's Technical Advisory Committee. Prior to joining Artima, Frank wrote the Jiniology and Web services columns for JavaWorld.