Adopting New JVM Languages in the Enterprise (Update) 105

Posted by Dean Wampler Thu, 15 Jan 2009 07:40:00 GMT

(Updated to add Groovy, which I should have mentioned the first time. Also mentioned Django under Python.)

This is an exciting time to be a Java programmer. The pace of innovation for the Java language is slowing down, in part due to concerns that the language is growing too big and in part due to economic difficulties at Sun, which means there are fewer developers assigned to Java. However, the real crown jewel of the Java ecosystem, the JVM, has become an attractive platform for new languages. These languages give us exciting new opportunities for growth, while preserving our prior investment in code and deployment infrastructure.

This post emphasizes practical issues of evaluating and picking new JVM languages for an established Java-based enterprise.

The Interwebs are full of technical comparisons between Java and the different languages, e.g., why language X fixes Java’s perceived issue Y. I won’t rehash those arguments here, but I will describe some language features, as needed.

A similar “polyglot” trend is happening on the .NET platform.

The New JVM Languages

I’ll limit my discussion to these representative (and best known) alternative languages for the JVM.

  1. JRuby – Ruby running on the JVM.
  2. Scala – A hybrid object-oriented and functional language that runs on .NET as well as the JVM. (Disclaimer: I’m co-writing a book on Scala for O’Reilly.)
  3. Clojure – A Lisp dialect.

I picked these languages because they seem to be the most likely candidates for most enterprises considering a new JVM language, although some of the languages listed below could make that claim.

There are other deserving languages besides these three, but I don’t have the time to do them justice. Hopefully, you can generalize the subsequent discussion for these other languages.

  1. Groovy – A dynamically-typed language designed specifically for interoperability with Java. It will appeal to teams that want a dynamically-typed language that is closer to Java than Ruby. With Grails, you have a combination that’s comparable to Ruby on Rails.
  2. Jython – The first non-Java language ported to the JVM, started by Jim Hugunin in 1997. Most of my remarks about JRuby are applicable to Jython. Django is the Python analog of Rails. If your Java shop already has a lot of Python, consider Jython.
  3. Fan – A hybrid object-oriented and functional language that runs on .NET, too. It has a lot of similarities to Scala, like a scripting-language feel.
  4. Ioke – (pronounced “eye-oh-key”) An innovative language developed by Ola Bini and inspired by Io and Lisp. This is the newest language discussed here. Hence, it has a small following, but a lot of potential. The Io/Lisp-flavored syntax will be more challenging to average Java developers than Scala, JRuby, Jython, Fan, and JavaScript.
  5. JavaScript, e.g., Rhino – Much maligned and misunderstood (e.g., due to buggy and inconsistent browser implementations), JavaScript continues to gain converts as an alternative scripting language for Java applications. It is the default scripting language supported by the JDK 6 scripting interface.
  6. Fortress – A language designed as a replacement for high-performance FORTRAN for industrial and academic “number crunching”. This one will interest scientists and engineers…

Note: Like a lot of people, I use the term scripting language to refer to languages with a lightweight syntax, usually dynamically typed. The name reflects their convenience for “scripting”, but that quality is sometimes seen as pejorative; they aren’t seen as “serious” languages. I reject this view.

To learn more about what people are doing on the JVM today (with some guest .NET presentations), a good place to start is the recent JVM Language Summit.

Criteria For Evaluating New JVM Languages

I’ll frame the discussion around a few criteria you should consider when evaluating language choices. I’ll then discuss how each of the languages address those criteria. Since we’re restricting ourselves to JVM languages, I assume that each language compiles to valid byte code, so code in the new language and code written in Java can call each other, at least at some level. The “some level” part will be one criterion. Substitute X for the language you are considering.

  1. Interoperability: How easily can X code invoke Java code and vice versa? Specifically:
    1. Create objects (i.e., call new Foo(...)).
    2. Call methods on an object.
    3. Call static methods on a class.
    4. Extend a class.
    5. Implement an interface.
  2. Object Model: How different is the object model of X compared to Java’s object model? (This is somewhat tied to the previous point.)
  3. New “Ideas”: Does X support newer programming trends:
    1. Functional Programming.
    2. Metaprogramming.
    3. Easier approaches to writing robust concurrent applications.
    4. Easier support for processing XML, SQL queries, etc.
    5. Support internal DSL creation.
    6. Easier presentation-tier development of web and thick-client UI’s.
  4. Stability: How stable is the language, in terms of:
    1. Lack of Bugs.
    2. Stability of the language’s syntax, semantics, and library API’s. (All the languages can call Java API’s.)
  5. Performance: How does code written in X perform?
  6. Adoption: Is X easy to learn and use?
  7. Tool Support: What about editors, IDE’s, code coverage, etc.
  8. Deployment: How are apps and libraries written in X deployed?
    1. Do I have to modify my existing infrastructure, management, etc.?

The Interoperability point affects ease of adoption and use with a legacy Java code base. The Object Model and Adoption points address the barrier to adoption from the learning point of view. The New “Ideas” point asks what each language brings to development that is not available in Java (or poorly supported) and is seen as valuable to the developer. Finally, Stability, Performance, and Deployment address very practical issues that a candidate production language must address.

Comparing the Languages

JRuby

JRuby is the most popular alternative JVM langauge, driven largely by interest in Ruby and Ruby on Rails.

Interoperability

Ruby’s object model is a little different than Java’s, but JRuby provides straightforward coding idioms that make it easy to call Java from JRuby. Calling JRuby from Java requires the JSR 223 scripting interface or a similar approach, unless JRuby is used to compile the Ruby code to byte code first. In that case, shortcuts are possible, which are well documented.

Object Model

Ruby’s object model is a little different than Java’s. Ruby support mixin-style modules, which behave like interfaces with implementations. So, the Ruby object model needs to be learned, but it is straightforward or the Java developer.

New Ideas

JRuby brings closures to the JVM, a much desired feature that probably won’t be added in the forthcoming Java 7. Using closures, Ruby supports a number of functional-style iterative operations, like mapping, filtering, and reducing/folding. However, Ruby does not fully support functional programming.

Ruby uses dynamic-typing instead of static-typing, which it exploits to provide extensive and powerful metaprogramming facilities.

Ruby doesn’t offer any specific enhancements over Java for safe, robust concurrent programming.

Ruby API’s make XML processing and database access relatively easy. Ruby on Rails is legendary for improving the productivity of web developers and similar benefits are available for thick-client developers using other libraries.

Ruby is also one of the best languages for defining “internal” DSL’s, which are used to great affect in Rails (e.g., ActiveRecord).

Stability

JRuby and Ruby are very stable and are widely used in production. JRuby is believed to be the best performing Ruby platform.

The Ruby syntax and API are undergoing some significant changes in the current 1.9.X release, but migration is not a major challenge.

Performance

JRuby is believed to be the best performing Ruby platform. While it is a topic of hot debate, Ruby and most dynamically-typed languages have higher runtime overhead compared to statically-typed languages. Also, the JVM has some known performance issues for dynamically-typed languages, some of which will be fixed in JDK 7.

As always, enterprises should profile code written in their languages of choice to pick the best one for each particular task.

Adoption

Ruby is very easy to learn, although effective use of advanced techniques like metaprogramming require some time to master. JRuby-specific idioms are also easy to master and are well documented.

Tool Support

Ruby is experiencing tremendous growth in tool support. IDE support still lags support for Java, but IntelliJ, NetBeans, and Eclipse are working on Ruby support. JRuby users can exploit many Java tools.

Code analysis tools and testing tools (TDD and BDD styles) are now better than Java’s.

Deployment

JRuby applications, even Ruby on Rails applications, can be deployed as jars or wars, requiring no modifications to an existing java-based infrastructure. Teams use this approach to minimize the “friction” of adopting Ruby, while also getting the performance benefits of the JVM.

Because JRuby code is byte code at runtime, it can be managed with JMX, etc.

Scala

Scala is a statically-typed language that supports an improved object model (with a full mixin mechanism called traits; similar to Ruby modules) and full support for functional programming, following a design goal of the inventor of Scala, Martin Odersky, that these two paradigms can be integrated, despite some surface incompatibilities. Odersky was involved in the design of Java generics (through earlier research languages) and he wrote the original version of the current javac. The name is a contraction of “scalable language”, but the first “a” is pronounced like “ah”, not long as in the word “hay”.

The syntax looks like a cross between Ruby (method definitions start with the def keyword) and Java (e.g., curly braces). Type inferencing and other syntactic conventions significantly reduce the “cluuter”, such as the number of explicit type declarations (“annotations”) compared to Java. Scala syntax is very succinct, sometimes even more so than Ruby! For more on Scala, see also my previous blog postings, part 1, part 2, part 3, and this related post on traits vs. aspects.

Interoperability

Scala’s has the most seamless interoperability with Java of any of the languages discussed here. This is due in part to Scala’s static typing and “closed” classes (as opposed to Ruby’s “open” classes). It is trivial to import and use Java classes, implement interfaces, etc.

Direct API calls from Java to Scala are also supported. The developer needs to know how the names of Scala methods are encoding in byte code. For example, Scala methods can have “operator” names, like ”+”. In the byte code, that name will be ”$plus”.

Object Model

Scala’s object model extends Java’s model with traits, which support flexble mixin composition. Traits behave like interfaces with implementations. The Scala object model provides other sophisticated features for building “scalable applications”.

New Ideas

Scala brings full support for functional programming to the JVM, including first-class function and closures. Other aspects of functional programming, like immutable variables and side-effect free functions, are encouraged by the language, but not mandated, as Scala is not a pure functional language. (Functional programming is very effective strategy for writing tread-safe programs, etc.) Scala’s Actor library is a port of Erlang’s Actor library, a message-based concurrency approach.

In my view, the Actor model is the best general-purpose approach to concurrency. There are times when multi-threaded code is needed for performance, but not for most concurrent applications. (Note: there are Actor libraries for Java, e.g., Kilim.)

Scala has very good support for building internal DSL’s, although it is not quite as good as Ruby’s features for this purpose. It has a combinator parser library that makes external DSL creation comparatively easy. Scala also offers some innovative API’s for XML processing and Swing development.

Stability

Scala is over 5 years old and it is very stable. The API and syntax continue to evolve, but no major, disruptive changes are expected. In fact, the structure of the language is such that almost all changes occur in libraries, not the language grammar.

There are some well-known production deployments, such as back-end services at twitter.

Performance

Scala provides comparable performance to Java, since it is very close “structurally” to Java code at the byte-code level, given the static typing and “closed” classes. Hence, Scala can exploit JVM optimizations that aren’t available to dynamically-typed languages.

However, Scala will also benefit from planned improvements to support dynamically-typed languages, such as tail-call optimizations (which Scala current does in the compiler.) Hence, Scala probably has marginally better performance than JRuby, in general. If true, Scala may be more appealing than JRuby as a general-purpose, systems language, where performance is critical.

Adoption

Scala is harder to learn and master than JRuby, because it is a more comprehensive language. It not only supports a sophisticated object model, but it also supports functional programming, type inferencing, etc. In my view, the extra effort will be rewarded with higher productivity. Also, because it is closer to Java than JRuby and Clojure, new users will be able to start using it quickly as a “better object-oriented Java”, while they continue to learn the more advanced features, like functional programming, that will accelerate their productivity over the long term.

Tool Support

Scala support in IDE’s still lags support for Java, but it is improving. IntelliJ, NetBeans, and Eclipse now support Scala with plugins. Maven and ant are widely used as the build tool for Scala applications. Several excellent TDD and BDD libraries are available.

Deployment

Scala applications are packaged and deployed just like Java applications, since Scala files are compiled to class files. A Scala runtime jar is also required.

Clojure

Of the three new JVM languages discussed here, Clojure is the least like Java, due to its Lisp syntax and innovative “programming model”. Yet it is also the most innovative and exciting new JVM language for many people. Clojure interoperates with Java code, but it emphasizes functional programming. Unlike the other languages, Clojure does not support object-oriented programming. Instead, it relies on mechanisms like multi-methods and macros to address design problems for which OOP is often used.

One exciting innovation in Clojure is support for software transactional memory, which uses a database-style transactional approach to concurrent modifications of in-memory, mutable state. STM is somewhat controversial. You can google for arguments about its practicality, etc. However, Clojure’s implementation appears to be successful.

Clojure also has other innovative ways of supporting “principled” modification of mutable data, while encouraging the use of immutable data. These features with STM are the basis of Clojure’s approach to robust concurrency.

Finally, Clojure implements several optimizations in the compiler that are important for functional programming, such as optimizing tail call recursion.

Disclaimer: I know less about Clojure than JRuby and Scala. While I have endeavored to get the facts right, there may be errors in the following analysis. Feedback is welcome.

Interoperability

Despite the Lisp syntax and functional-programming emphasis, Clojure interoperates with Java. Calling java from Clojure uses direct API calls, as for JRuby and Scala. Calling Clojure from Java is a more involved. You have to create Java proxies on the Clojure side to generate the byte code needed on the Java side. The idioms for doing this are straightforward, however.

Object Model

Clojure is not an object-oriented language. However, in order to interoperate with Java code, Clojure supports implementing interfaces and instantiating Java objects. Otherwise, Clojure offers a significant departure for develops well versed in object-oriented programming, but with little functional programming experience.

New Ideas

Clojure brings to the JVM full support for functional programming and popular Lisp concepts like macros, multi-methods, and powerful metaprogramming. It has innovative approaches to safe concurrency, including “principled” mechanisms for supporting mutable state, as discussed previously.

Clojure’s succinct syntax and built-in libraries make processing XML succinct and efficient. DSL creation is also supported using Lisp mechanisms, like macros.

Stability

Clojure is the newest of the three languages profiled here. Hence, it may be the most subject to change. However, given the nature of Lisps, it is more likely that changes will occur in libraries than the language itself. Stability in terms of bugs does not appear to be an issue.

Clojure also has the fewest known production deployments of the three languages. However, industry adoption is expected to happen rapidly.

Performance

Clojure supports type “hints” to assist in optimizing performance. The preliminary discussions I have seen suggest that Clojure offers very good performance.

Adoption

Clojure is more of a departure from Java than is Scala. It will require a motivated team that likes Lisp ;) However, such a team may learn Clojure faster than Scala, since Clojure is a simpler language, e.g., because it doesn’t have its own object model. Also, Lisps are well known for being simple languages, where the real learning comes in understanding how to use it effectively!

However, in my view, as for Scala, the extra learning effort will be rewarded with higher productivity.

Tool Support

As a new language, tool support is limited. Most Clojure developers use Emacs with its excellent Lisp support. Many Java tools can be used with Clojure.

Deployment

Clojure deployment appears to be as straightforward as for the other languages. A Clojure runtime jar is required.

Comparisons

Briefly, let’s review the points and compare the three languages.

Interoperability

All three languages make calling Java code straightforward. Scala interoperates most seamlessly. Scala code is easiest to invoke from Java code, using direct API calls, as long as you know how Scala encodes method names that have “illegal” characters (according to the JVM spec.). Calling JRuby and Clojure code from Java is more involved.

Therefore, if you expect to continue writing Java code that needs to make frequent API calls to the code in the new language, Scala will be a better choice.

Object Model

Scala is closest to Java’s object model. Ruby’s object model is superficially similar to Scala’s, but the dynamic nature of Ruby brings significant differences. Both extend Java’s object model with mixin composition through traits (Scala) or modules (Ruby), that act like interfaces with implementations.

Clojure is quite different, with an emphasis on functional programming and no direct support for object-oriented programming.

New Ideas

JRuby brings the productivity and power of a dynamically-typed language to the JVM, along with the drawbacks. It also brings some functional idioms.

Scala and Clojure bring full support for functional programming. Scala provides a complete Actor model of concurrency (as a library). Clojure brings software transactional memory and other innovations for writing robust concurrent applications. JRuby and Ruby don’t add anything specific for concurrency.

JRuby, like Ruby, is exceptionally good for writing internal DSL’s. Scala is also very good and Clojure benefits from Lisp’s support for DSL creation.

Stability

All the language implementations are of high quality. Scala is the most mature, but JRuby has the widest adoption in production.

Performance

Performance should be comparable for all, but JRuby and Clojure have to deal with some inefficiencies inherent to running dynamic languages on the JVM. Your mileage may vary, so please run realistic profiling experiments on sample implementations that are representative of your needs. Avoid “prematurely optimization” when choosing a new language. Often, team productivity and “time to market” are more important than raw performance.

Adoption

JRuby is the the easiest of the three languages to learn and adopt if you already have some Ruby or Ruby on Rails code in your environment.

Scala has the lowest barrier to adoption because it is the language that most resembles Java “philosophically” (static typing, emphasis on object-oriented programming, etc.). Adopters can start with Scala as a “better Java” and gradually learn the advanced features (mixin composition with traits and functional programming). Scala will appeal the most to teams that prefer statically-typed languages, yet want some of the benefits of dynamically-typed languages, like a succinct syntax.

However, Scala is the most complex of the three languages, while Clojure requires the biggest conceptual leap from Java.

Clojure will appeal to teams willing to explore more radical departures from what they are doing now, with potentially great payoffs!

Deployment

Deployment is easy with all three languages. Scala is most like Java, since you normally compile to class files (there is a limited interpreter mode). JRuby and Clojure code can be interpreted at runtime or compiled.

Summary and Conclusions

All three choices (or comparable substitutions from the list of other languages), will provide a Java team with a more modern language, yet fully leverage the existing investment in Java. Scala is the easiest incremental change. JRuby brings the vibrant Ruby world to the JVM. Clojure offers the most innovative departures from Java.

Comments

Leave a response

  1. Avatar
    j pimmel about 1 hour later:

    Have you guys already covered Groovy and Grails in your analyses of new JVM languages? Groovy is a language which has now matured significantly, Grails being a close follower in terms of Web App DSL / Framework built upon Spring / Hibernate.

    I would be interested to hear your thoughts on these compared to the rest, or else reasoning as to why it was excluded in your article – could be you just didn’t know about it.

  2. Avatar
    http://jshingler.blogspot.com about 1 hour later:

    Humm, . . . Kinda surprised not to see Groovy, and Grails mentioned

  3. Avatar
    James Iry about 2 hours later:

    Grails is not a language guys. He didn’t mention Lift or Rails either. But it is strange to skip at least a mention of Groovy and why it’s not covered.

    One minor quibble is that all three of the languages you talk about support both “pre-compiling” and script based running – even Scala.

    Also, Clojure’s use of STM isn’t innovative. STM has been around awhile; Haskell has it and arguably does it better due to its monadic efffects system. What I do think is innovative is the use of multi version concurrency control, which AFAIK is unique or at list first in Clojure’s implementation of STM.

  4. Avatar
    Josh Reed about 3 hours later:

    He did mention Ruby on Rails a couple of times (maybe 5?). I just was surprised about the lack of Groovy mention given that some of the more obscure languages like Ioke was mentioned.

    I can see why he chose each of the 3 languages he chose to focus on. JRuby is dynamic and a different enough syntax. Scala has a great (static) type system and embraces functional programming concepts. Clojure brings the greatness of Lisp to the JVM. If you were going to focus on the diversity of the alternative JVM languages, this is a great lineup that really shows off the diversity that the JVM is capable of.

    I’m not going to lie, I’m a fan of Groovy. I don’t think you need to dote on Groovy (though I think there’s plenty there worth talking about). However, I think not including Groovy in the list seriously damages the credibility of the article.

    Cheers, Josh

  5. Avatar
    Dean Wampler about 4 hours later:

    Yes, omitting Groovy was a dumb oversight. No slight was intended. With Grails, Groovy is pretty much interchangeable with Ruby and Rails, as far as the discussion is concerned. Groovy will often be more appealing than Ruby for shops that want a dynamically-typed language that’s closer to Java (by design, of course).

    Paradoxically, my personal “hunch” is that Groovy won’t be as widely used as Ruby, in the long run, precisely because it’s seen as too close to Java. Ruby seems to have better momentum now, at least. However, it’s exciting to see the main team behind Groovy now working for SpringSource! Should be a killer combination.

    @James is right about interpreted Scala and STM. I only mentioned Scala interpretation in passing and didn’t include interpretation as a “deployment” option only because it’s not a complete REPL. Unlike JRuby and (I think) Clojure, the interpreter can’t handle all Scala code (e.g., if it declares packages), due to some implementation decisions. Conversely, not all Scala “scripts” can be compiled to class files. So, I think of the Scala interpreter mode as an exploration/experimentation tool, but not one I use very often for writing production scripts (where I tend to use Ruby or Bash…). Still, I didn’t make that clear.

    I also glossed over the history of STM (which I don’t know well, anyway). I alluded to the fact that it has been controversial, but Clojure has made it more successful. Thanks, James, for clarifying the unique aspects of STM in Clojure.

    Thanks all for keeping me honest ;)

  6. Avatar
    Dean Wampler about 4 hours later:

    I updated the content to give Groovy, Grails (and Django…) their due!

    (Note: had to change the title to work around an apparent bug in Typo that prevented the changes from showing up!)

  7. Avatar
    Ben about 5 hours later:

    For a post with a goal of evaluating “new JVM languages for an established Java-based enterprise,” exluding Groovy is a HUGE oversight.

    Groovy is ideal if you are a Java shop and are looking to get the productivity of these alternative, dynamic JVM languages, but you don’t want the infrastructure, training, and maintenance cost of developing and supporting multiple languages.

    Interoperability: For 99% of Java code, you could rename the file .groovy and you have a Groovy program. The model is nearly identical if you are striving for interoperability and Java consistency.

    Object Model: Identical, with plenty of syntactic sugar to take away the verbosity and other pain points in Java.

    New “Ideas”: Metaprogramming, DSLs, XML and SQL Processing—All of these are soo easy to do in Groovy. Many frameworks are being developed in Groovy to leverage it’s flexibility.

    Stability: Very robust. As solid as Java.

    Performance: Very performant. Easy to be as fast as Java for compiled Groovy.

    Adoption: The perfect dynamic language to try if moving from Java. Very familiar syntax (if you choose), and you can adopt specific language features as you find use for them.

    Tool Support: All major Java IDEs have support for Groovy.

    Deployment: Groovy is Java. Grails is Java. No infrastructure changes are necessary.

    That’s just off the top of my head—I’ll let you finish the complete write up after you get your head out of your Scala book and do some learning about Groovy.

    http://groovy.codehaus.org/Documentation

  8. Avatar
    James Iry about 7 hours later:

    @Dean, It is peculiar that Scala’s script runner can’t accept package declarations. I understand why the REPL can’t, but the script runner shouldn’t face the same issues. Like you say, it’s an implementation detail that leaks a bit.

    But compiling a script is always possible AFAIK. You should be able to compile any Scala script into a set of fairly ordinary .class files using the -Xscript option.

    /test> cat Test.scala

    println(“hello world”)

    /test> scalac -Xscript Hello Test.scala

    /test> java -cp /usr/share/scala/lib/scala-library.jar:. Hello

    hello world

    /test> scala Hello

    hello world

  9. Avatar
    Markus Kohler about 10 hours later:

    Regarding performance. Scala is in my experience the fastest of all those languages. When looking at performance memory usage needs also to be taken into account.

    Since Scala is very close to Java, memory usage should be in most cases not much much.

    This is not true for the dynamic languages because an object in JRuby or Groovy for the matter, does not directly map to a Java Object.

  10. Avatar
    Jeff foster about 10 hours later:

    > Finally, Clojure implements several optimizations in the > compiler that are important for functional programming, > such as optimizing tail call recursion.

    That’s not quite right. Clojure provides no guarantee about tail call optimization (because JVM doesn’t support it at the moment, and won’t in JDK7 either).

    It does provide a special operator, recur, which does constant space variable looping by rebinding variables.

  11. Avatar
    Stefan Zeiger about 12 hours later:

    The statement “Hence, Scala probably has marginally better performance than JRuby, in general” seems to be very misleading if you compare results of the Language Shootout. The difference is huge. While JRuby is faster than Ruby 1.8, that alone is not much of an endorsement. Pretty much anything is faster than Ruby.

  12. Avatar
    Dean Wampler about 14 hours later:

    @Ben, it was an oversight to omit Groovy, which I fixed in the update. Your comments were great until the last paragraph. Why the sour note? I tried to make it clear in the opening section that I picked representative languages that are currently leading contenders. Discussing Groovy to the same depth as JRuby would be redundant for the purposes of this post, which is about analyzing the characteristics of “X” vs. a set of requirements. I understand, though, that Groovy backers would have preferred that I switched Groovy for JRuby…

    @James, I did not know about the -Xscript option. Thanks! Concerning running a script with scala that has package declarations, I tried it again and it didn’t work. Unless I did something wrong, it appears that the script runner works the same as the REPL, at least where package declarations are concerned.

    @Jeff, my understanding is that Clojure itself does some tail call optimizing when generating byte code and they recently added “trampolining” for 2 methods that call each other recursively. So, JVM support isn’t required (but it sure would be nice!). Again, my ignorance about Clojure exceeds my ignorance about JRuby and Scala ;)

    @Stefan, I was being conservative when I said “marginally”. Thanks for the link. As @Markus said, there is some unavoidable overhead that dynamic languages have and JRuby in particular has to map Ruby’s object model to Java’s and vice-versa. Hopefully, such performance gaps will decrease over time as the languages improve and the JVM is enhanced to better support them.

  13. Avatar
    Zorg about 14 hours later:

    there’s also CAL

  14. Avatar
    Ed Cetera about 15 hours later:

    Clojure, like most modern Lisps, does not ever interpret anything. Even expressions entered into the REPL are compiled, then run.

  15. Avatar
    Daniel Spiewak about 17 hours later:

    Just a minor quibble: I would actually make the claim that Scala is better for internal DSL development than Ruby. Implicit conversions do a world of good (even beyond emulating open classes), and they are one feature which is simply not possible in a dynamic language.

    Interop Samples

    This is a section which I feel was missing from the article.

    Each of the three languages reviewed have excellent support for interop with Java and moderate support for interop from Java. Just to give you a the flavor, here are some snippet showing both directions in all three languages:

    JRuby to Java

    import javax.swing.JFrame
    import javax.swing.JButton
    
    frame = JFrame.new 'My Window'
    frame.add(JButton.new 'Push me!')
    
    frame.default_close_operation = JFrame::EXIT_ON_CLOSE
    frame.visible = true

    Java to JRuby

    (from the JRuby Wiki)

    import javax.script.ScriptContext;
    import javax.script.ScriptEngine;
    import javax.script.ScriptEngineManager;
    import javax.script.ScriptException;
    
    ...
    ScriptEngineManager m = new ScriptEngineManager();
    ScriptEngine rubyEngine = m.getEngineByName("jruby");
    ScriptContext context = rubyEngine.getContext();
    
    context.setAttribute("label", new Integer(4), ScriptContext.ENGINE_SCOPE);
    
    try{
        rubyEngine.eval("puts 2 + $label", context);
    } catch (ScriptException e) {
        e.printStackTrace();
    }

    Scala to Java

    import javax.swing.{JFrame, JButton}
    
    val frame = new JFrame("My Window")
    frame.add(new JButton("Push Me!"))
    
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
    frame.setVisible(true)

    Java to Scala

    import scala.List;
    
    ...
    List<String> strs = List.apply("Daniel", "Chris", "Joseph");
    String me = strs.apply(0);
    
    List<String> more = strs.$colon$colon("Renee");
    String sis = more.apply(0);
    me = more.apply(1);

    As a minor plug, I have done some work in directly integrating JRuby and Scala. Using my minor frameworks, it is possible to intuitively call JRuby from within Scala (no need to use the Java 6 scripting framework directly) as well as easily integrate with Scala higher-order methods and operator overloading.

    • JRuby Interop DSL in Scala
    • Integrating Scala into JRuby

    Clojure to Java

    (import '(javax.swing (JFrame, JButton)))
    
    (doto (new JFrame "My Window")
      (add (new JButton "Push Me!"))
      (setDefaultCloseOperation
        (JFrame/EXIT_ON_CLOSE))
      (setVisible true))

    Java to Clojure

    ; Clojure source
    (ns com.mycompany.MyTest (:gen-class))
    
    (defn -testMethod1 []
      (println "In testMethod1"))
    
    (defn -sayHello [to]
      (println (str "Hello, " to "!")))
    // Java source
    import com.mycompany.MyTest;
    
    ...
    MyTest test = new MyTest();
    test.testMethod1();
    test.sayHello("Daniel");

    Extras

    Not shown in these examples is the fact that all of these languages support class inheritence as part of their interop.

    • A JRuby class can extend a Java class or mixin a Java interface just as if it were a regular Ruby class or module (respectively).
    • Java classes can’t really inherit from Ruby classes. At least, not usefully.
    • Scala classes can natively inherit from Java classes
    • Java classes can natively inherit from Scala classes
    • Clojure doesn’t really have classes, but it can create dynamic proxies for interfaces, and its :gen-class syntax provides support for inheritence.
    • Don’t even go there… I’m assuming that you could probably hack something up, but extending a Clojure :gen-class in Java is bound to be fairly painful.

    All in all, Scala has the best interop of any JVM language (well, Groovy’s interop is about equivalent except where things like generics come into play); but neither JRuby and Clojure are too far behind.

  16. Avatar
    James Iry about 19 hours later:

    @Dean,

    Scala automatically optimizes away direct tail recursive calls, although you have to be careful because methods can’t generally directly call themselves due to the nature of virtual dispatch. Clojure has a construct called “recur” that does direct tail recursion, but otherwise does not automatically optimize tail calls. Clojure recently added an optional trampolining construct for general tail calls to the language and Scala allows you to define one in your own code (an officially blessed version is likely in the next release). Both language communities curse the JVM’s lack of a tail call instruction as found in the .NET CLR since what we’re using right now is a bunch of band-aids and hacks.

    For the sake of completeness I’ll mention that two JVM based Schemes also do tail calls. Kawa can automatically trampoline everything and SISC uses its own heap based stack instead of the JVM stack. Both solutions have performance and Java interop issues which is why you don’t find them in Clojure and Java.

  17. Avatar
    matt 1 day later:

    @Ben: “Performance: Very performant. Easy to be as fast as Java for compiled Groovy.” You are incorrect. For most things groovy is 3 – 5x less performant. In some cases, even when optimized, it’s several orders of magnitude. I’ve seen this in real life as well as it appears to be the same in the debian language shootout. ( http://shootout.alioth.debian.org/gp4/benchmark.php?test=all&;lang=java&lang2=groovy ) <- link is busted and i don’t wanna learn the kind of markup for this blog (just cut n paste)

  18. Avatar
    tim dugan 1 day later:

    here’s another, Ada!

    http://www.adahome.com/Resources/Ada_Java.html

    That page says “there are two Ada-to-JVM compilers. Intermetrics (AppletMagic) and Aonix (ObjectAda) have re-targeted their Ada 95 compilers to generate j-code.”

    Although I am having trouble finding additional details…

    Jython – The first non-Java language ported to the JVM

  19. Avatar
    Dean Wampler 1 day later:

    @Daniel, Thanks for the detailed comment on interoperability. It makes my “handwaving” points concrete.

    @James, Thanks for clarifying details about recursion handling.

    @all, Thanks for the spirited debate and for filling in many details. My goal isn’t to make the case for one language or another, since each team will have different circumstances, etc. Rather, I want to offer suggestions for how to do that investigation for yourself.

  20. Avatar
    jim cakalic 6 days later:

    Thank you for your analysis. Robert Tolksdorf has been maintaining an expanding list of languages implemented on the JVM since at least 2003, although not with the insights that you provide in your article: http://www.is-research.de/info/vmlanguages/index.html

  21. Avatar
    Steven Shaw 6 days later:

    Seems a little to mention Ioke. Pretty sure it doesn’t have a Java “FFI” yet…

  22. Avatar
    Paul Barry about 1 month later:

    You say “Ruby does not fully support functional programming”. What functional programming features does Ruby not have?

  23. Avatar
    Paul Barry about 1 month later:

    You say “Ruby does not fully support functional programming”. What functional programming features does Ruby not have?

  24. Avatar
    Dean Wampler 3 months later:

    @Paul, (I just noticed your comment/question.) My statement was perhaps a little strong, because you could make it about other languages that are considered “functional”.

    Ruby is obviously an OO language with some functional features, like blocks. In that sense, it’s a hybrid sort of like Scala, but weaker in its emphasis on functional programming.

    However, the “biggies” that come to mind are 1) Ruby methods aren’t first class, although blocks & Procs are, 2) It doesn’t provide mechanisms to promote immutability (using “attr_reader” only helps, but the object it refers to isn’t automatically immutable), 3) It doesn’t have the same strong pattern matching facilities built in that a typical functional language would have. However, libraries like the Case gem make up for this as I blogged more recently.

    Otherwise, a few features that aren’t “pure”, but are also true of some other hybrid languages include 1) Ruby doesn’t promote any mechanisms to encourage side-effect free functions, 2) Ruby didn’t have tail-call optimization until very recently (1.9.1 YARV and JRuby, I believe) and it’s not as complete as, say, Haskell’s recursion optimizations, 3) The libraries have some functional support (like map, inject, etc. methods), but not a full set of functionally-oriented data structures and functions.

    These are all quibbles, really. You can do a lot of functional programming in Ruby. I did a talk about this at last year’s RubyConf. http://aspectprogramming.com/papers/BetterRubyThroughFP_v5.pdf

  25. Avatar
    rvjansen@me.com about 1 year later:

    Jython, or JPython as it was called then, where started in 1997 as you say, can not have been the first alternative language for the Java VM, as NetRexx was released by IBM in 1996 already.

  26. Avatar
    Dean about 1 year later:

    Ill have to save this url in my bookmark and read the rest later.. thanks for this post

  27. Avatar
    FLV extractor about 1 year later:

    read it

  28. Avatar
    herpes symptoms about 1 year later:

    JVM language has brought a new revolution in the story. Nice reading this post.

  29. Avatar
    cheap vps about 1 year later:

    Otherwise, a few features that aren’t “pure”, but are also true of some other hybrid languages include 1) Ruby doesn’t promote any mechanisms to encourage side-effect free functions, 2) Ruby didn’t have tail-call optimization until very recently (1.9.1 YARV and JRuby, I believe) and it’s not as complete as, say, Haskell’s recursion optimizations, 3) The libraries have some functional support (like map, inject, etc. methods), but not a full set of functionally-oriented data structures and functions.cheap VPS

  30. Avatar
    bag manufacturer about 1 year later:

    ulties at Sun, which means there are fewer developers assigned to Java. However, the real crown jewel of the Java ecosystem, the JVM, has become an attractive platform for new languages. These languages give us exciting new opportunities for growth, while preserving our prior investment in code and deplo

  31. Avatar
    Indonesian Teak Furniture: Indoor Teak Furniture, Teak Garden Furniture, Teak Table, Teak Chairs about 1 year later:

    Thank you a lot for information!

  32. Avatar
    Apartments for rent Bucharest about 1 year later:

    I really like Ruby, but I don’t know if I’d say JRuby is the current leader though it certainly has to capability of becoming so.

    He originally left Groovy completely out of the picture and I would have thought Groovy has had more acceptance simply because those new to the language can pick up on it bit by bit as they move from Java.

    I’m not a big fan of Clojure and I’m surprised it has gotten as much recognition as it has. Maybe I just need to play with it more. ((()))()(()((()(())()(()

    I like that he compared how difficult it would be for a strictly Java background programmer to pick up each language and the performance difference of code. Apartments for rent Bucharest

  33. Avatar
    oxpdffr about 1 year later:

    CHM en PDF Convertisseur est un logiciel qui convertit des fichiers CHM (Compiled HTML Help Files) en format PDF avec le titre, le temps, la table des matières, en-tête, pied de page, numéro de page, etc. CHM en PDF Convertisseur possède encore plusieurs fonctions, par exemple :ajouter des filigranes, adjuster la résolution ou la taille du fichier, protéger les documents PDF par mot de passe, etc. Télécharger gratuitement CHM en PDF Convertisseur et expérimenter ce logiciel.

  34. Avatar
    chanel store about 1 year later:

    Here is very different. Thank you

  35. Avatar
    Inchirieri Auto Constanta about 1 year later:

    Currently, I’m playing around Clojure and all what I say, what a learning curve! I never played around any LISP dialect, maybe this is why I find it is hard to digest but it is a nice departure from many other programming languages. JRuby is great for Ruby programmers how are suffering from the bad performance of Ruby interpreter and they are seeking to deploy Rails applications on Glassfish. I don’t know why Groovy is underestimated, this language offers the best integration with Java Platform and so easy to grasp.

  36. Avatar
    Pandora about 1 year later:

    These databases are typically managed with functional techniques, like map-reduce.

  37. Avatar
    iPhone SMS Transfer about 1 year later:

    We, how can we to be a good programmer, we should study alll the time, never lose our heart, keep good habit, learn from other people. that’s it.

  38. Avatar
    iPhone to Mac Transfer about 1 year later:

    The New JVM Languages is hard to understand, a long time past and I can’t manage it.

  39. Avatar
    iPad ePub transfer about 1 year later:

    Code everyday, for our progress, how to be a good programmer, here how can we?

  40. Avatar
    www.heyheytrade.com about 1 year later:

    You know, it is not to understand it, however, you can finish it, enjoy much.www.lightinthehandbags.com www.hotshoesshop.com

  41. Avatar
    http://www.blacktowhiteiphone4.com about 1 year later:

    The modern and delicate makes iphone 4 white so charming that even me, want to own one. But what i can do now, is to wait the price to decline.

  42. Avatar
    dvdsoft about 1 year later:

    With the right tool, you can easily burn mp4 to dvd and itunes to dvd. Also, you can use drm removal tool to remove drm protection from itunes, zune, amazon legally. wmv to dvd, mov to dvd, mp4 to dvd, itunes to dvd

  43. Avatar
    replica tag heuer carrera about 1 year later:

    is to wait the price to decline.

  44. Avatar
    Truth About Quickness Review about 1 year later:

    Currently, I’m playing around Clojure and all what I say, what a learning curve! I never played around any LISP dialect, maybe this is why I find it is hard to digest but it is a nice departure from many other programming languages. JRuby is great for Ruby programmers how are suffering from the bad performance of Ruby interpreter and they are seeking to deploy Rails applications on Glassfish. I don’t know why Groovy is underestimated, this language offers the best integration with Java Platform and so easy to grasp.

  45. Avatar
    Criminal Check about 1 year later:

    Scala is the easiest incremental change. JRuby brings the vibrant Ruby world to the JVM. Clojure offers the most innovative departures from Java.

  46. Avatar
    accounting services over 2 years later:

    I really like Ruby, but I don’t know if I’d say JRuby is the current leader though it certainly has to capability of becoming so.accounting services

  47. Avatar
    US Criminal Record over 2 years later:

    JRuby is the most popular alternative JVM langauge, driven largely by interest in Ruby and Ruby on Rails.

  48. Avatar
    Server management over 2 years later:

    An awesome flier. Real informative and metropolis. I revalue the author for presenting much a turn accumulation. This types of posts are always bookmarkable. I’ll wait for specified posts here all the abstraction. Server management

  49. Avatar
    Server management over 2 years later:

    An awesome call. Truly informative and prissy. I appreciate the communicator for presenting much a cold airman. This types of posts are ever bookmarkable. I’ll wait for such posts here all the period.

  50. Avatar
    Server management over 2 years later:

    An awful send. Truly informative and precise. I see the communicator for presenting much a caller communication. This types of posts are e’er bookmarkable. I’ll move for specified posts here all the moment. Server management

  51. Avatar
    iPad PDF Transfer for Mac over 2 years later:

    I really like this essay. Thank you for writing it so seriously. I want to recommend it for my friends strongly. iPad PDF Transfer for Mac can help you transfer ebooks in PDF format from ipad to mac/iTunes.

  52. Avatar
    iPad to mac transfer over 2 years later:

    Thanks for shareing! I agree with you. The artical improve me so much! I will come here frequently. iPad to Mac Transfer lets you transfer music, movie, photo, ePub, PDF, Audiobook, Podcast and TV Show from iPad to Mac or iPad to iTunes.

  53. Avatar
    facebook and dating over 2 years later:

    I talk about numerous topics, still debating in every single element that may be debated, and at the finish of my course (every single week), I advised them in regards to the conclusion of your respective theme. Hot theme and environment can be fun right here. After which, you might be shocked that my college students received new story every single working day, and also all of them can express their thought in residence and college. facebook and dating

  54. Avatar
    Criminal Records over 2 years later:

    This post emphasizes practical issues of evaluating and picking new JVM languages for an established Java-based enterprise.

  55. Avatar
    dvdsoft over 2 years later:

    With the right tool, you can easily burn mp4 to dvd and itunes to dvd. Also, you can use drm removal tool to remove drm protection from itunes, zune, amazon legally. wmv to dvd, mov to dvd, convert mp4 to dvd, itunes to dvd

  56. Avatar
    Matteo over 2 years later:

    7

  57. Avatar
    mosic over 2 years later:

    8

  58. Avatar
    Jones over 2 years later:

    9

  59. Avatar
    ssara over 2 years later:

    Nice idea for a better business.Maine Child Care Form

  60. Avatar
    Sunglass over 2 years later:

    Buy $10 Replica Designer Sunglasses with 3-day FREE SHIPPING Hurry up

  61. Avatar
    tree information over 2 years later:

    You got a really great blog I have been here reading for about half an hour. I am a newbie and your post is valuable for me.

  62. Avatar
    dory over 2 years later:

    The blog was absolutely fantastic! Lots of great information and inspiration, both of which we all need. thank you so much.Keep up the good works. Social Network

  63. Avatar
    tahmid_nsu_bba@yahoo.com over 2 years later:

    This is a fascinating blog. I have gone through several sites that are cramped with irrelevant things. This site satisfies me with every aspect. Very reliable articles. The explanations are easy to perceive. female swimming scholarships

  64. Avatar
    Big pony over 2 years later:

    Wow, this is too cool. I am very like it, Thank you for sharing, let me so happy! At the same time ,i also love polo ralph lauren outlet very much !

  65. Avatar
    haris4242 over 2 years later:

    Seating The very first glance at this site made me its fan. You have assorted incredibly huge resources. I like the way you have customized it. I find very reader friendly. Hope to see more of them. New and Used Office Desks and Chairs

    Commercial Office Furniture Denver

    Denver Office Furniture

  66. Avatar
    okey oyunu oyna over 2 years later:

    it is nice informative article. Thanks

    internette görüntülü olarak okey oyunu oyna, gerçek kisilerle tanis, turnuva heyecanini yasa.

  67. Avatar
    mbt shoes sales over 2 years later:

    Yay! Glad to hear it worked out. :D Best wishes to you guys~.

  68. Avatar
    Jewellery over 2 years later:

    Online UK costume and fashion jewellery shop with, Online UK costume and fashion jewellery shop with, Online UK costume and fashion jewellery shop with,

  69. Avatar
    abercrombie paris over 2 years later:

    These databases are typically managed with functional techniques, like map-reduce.

  70. Avatar
    lose thigh over 2 years later:

    Thanks for the JVM discussion!

  71. Avatar
    commission predators over 2 years later:

    What a wonderful article! And are doing well on the whole, but their work also has shortcomings.

  72. Avatar
    hcg diet atlanta over 2 years later:

    Really appreciate the effort behind this site. It is perfectly designed. I can have a glance easily because of the eye catching background. I almost daily move my mouse scroll here. Well done.

    hcg diet atlanta

  73. Avatar
    cookies gift baskets over 2 years later:

    Blog posts about wedding and bridal are always rare to find , at least with great quality,you qualify for a great blog post writer title,kep the great job happening

  74. Avatar
    stump removal Houston over 2 years later:

    This blog definitely has very broad collection. The resources are really comprehensive. I have been visiting at least two or three times a week. It helps me a lot to gain knowledge about this topic. Looking forward to get more stuffs like this.

  75. Avatar
    upvc door over 3 years later:

    This blog seems to be advanced than other blogs. It’s very appealing to the readers. I found every posts informative. You need to improve the looks. Well done anyway.

  76. Avatar
    composite doors over 3 years later:

    There is lots of important information here in this site. Though it looks bit complicated. But it truly has significant contribution to the topic. I told my buddies to go through this regularly. Good job .

  77. Avatar
    Crystal Jewellery over 3 years later:

    Great post! Nice and informative, I really enjoyed reading it and will certainly share this post with my friends . Read everything about the concept of gold karat when applied to gold

  78. Avatar
    beats by dre store over 3 years later:

    and informative, I really enjoyedhigh quality headphones new design headphonesreading it and will certainly

  79. Avatar
    upvc door over 3 years later:

    upvc door

  80. Avatar
    louis vuitton handbags womens on sale over 3 years later:

    Those are amazing. Wonderful collection. This is real design. Love it man. Thank you so much for shearing.

  81. Avatar
    canada goose coat over 3 years later:

    When it comes to feather dress, what appears in your mind? Which kind brand of down jacket do you like prefer? Though there are many down jackets for you to choose from, on the word, which one you really enjoy? I want to say that canada goose coats is really your best choice. I believe you can’t agree with me any more. When you take the quality into consideration, you will find that it is superior to any other kind of coat. Besides, discount canada goose jackets is a world well-known brand, which has gained high reputation in the world, which has accepted by our customers and some organization. Because of its high quality, some of our loyal customers have promoted it to the people around them. In their opinion, it is good to informing others to know it. Recently, Canada Goose Trillium Parka is on hot sale. What I have to inform you is that all the products there are made by hand, so they are elaborative and elegant enough. It is really beautiful once you dress in. So, if you are a lovely girl or woman, go to the store to buy one for you. You will appreciate it that you have such a coat.In addition, they also have any other products like canada goose Gloves and canada goose jacket supplier.Hope your will like its!

  82. Avatar
    canada goose coat over 3 years later:

    When it comes to feather dress, what appears in your mind? Which kind brand of down jacket do you like prefer? Though there are many down jackets for you to choose from, on the word, which one you really enjoy? I want to say that canada goose coats is really your best choice. I believe you can’t agree with me any more. When you take the quality into consideration, you will find that it is superior to any other kind of coat. Besides, discount canada goose jackets is a world well-known brand, which has gained high reputation in the world, which has accepted by our customers and some organization. Because of its high quality, some of our loyal customers have promoted it to the people around them. In their opinion, it is good to informing others to know it. Recently, Canada Goose Trillium Parka is on hot sale. What I have to inform you is that all the products there are made by hand, so they are elaborative and elegant enough. It is really beautiful once you dress in. So, if you are a lovely girl or woman, go to the store to buy one for you. You will appreciate it that you have such a coat.In addition, they also have any other products like canada goose Gloves and canada goose jacket supplier.Hope your will like its!

  83. Avatar
    canada goose coat over 3 years later:

    When it comes to feather dress, what appears in your mind? Which kind brand of down jacket do you like prefer? Though there are many down jackets for you to choose from, on the word, which one you really enjoy? I want to say that canada goose coats is really your best choice. I believe you can’t agree with me any more. When you take the quality into consideration, you will find that it is superior to any other kind of coat. Besides, discount canada goose jackets is a world well-known brand, which has gained high reputation in the world, which has accepted by our customers and some organization. Because of its high quality, some of our loyal customers have promoted it to the people around them. In their opinion, it is good to informing others to know it. Recently, Canada Goose Trillium Parka is on hot sale. What I have to inform you is that all the products there are made by hand, so they are elaborative and elegant enough. It is really beautiful once you dress in. So, if you are a lovely girl or woman, go to the store to buy one for you. You will appreciate it that you have such a coat.In addition, they also have any other products like canada goose Gloves and canada goose jacket supplier.Hope your will like its!

  84. Avatar
    Ashley Bowling over 3 years later:

    A fish always rots from the head down

  85. Avatar
    name:Belstaff Jackets Uk Online over 3 years later:

    There’s no denying the fact that our is well-know for its fine quality. Mens Belstaff XL 500 Jacket There are many repeat customers just for theBelstaff Jackets Uk Online quality of our products. Mens Belstaff Daytona Blouson Jacket Here, I provide you the most fashionable and most durable that always designed with high qaulity and also foMens Belstaff Jacketsllow the fashion trend. Belstaff leather In order to improve.Mens Moncler Down Jackets customer satisfactionBelstaff Bags, a number of discount Belstaff Jacketactivities are ongoing inBelstaff UK our store. Mens Belstaff Trialmaster Classic Tourist JacketSuch as the which with pretty design and colorful style, Womens Belstaff Jackets and the which made of the latest technology and follow the fashionable trend. Just come to our you will find many unexpected surprise are waiting for you.

  86. Avatar
    flac converter over 3 years later:

    good post, i think so.Thank you!

  87. Avatar
    christian louboutin over 3 years later:

    The professional design make you foot more comfortable. Even more tantalizing,this pattern make your legs look as long as you can,it will make you looked more attractive.Moveover,it has reasonable price.If you are a popular woman,do not miss it.

    Technical details of Christian Louboutin Velours Scrunch Suede Boots Coffee:

    Color: Coffee
    Material: Suede
    4(100mm) heel
    Signature red sole x

    Fashion, delicate, luxurious Christian louboutins shoes on sale, one of its series is Christian Louboutin Tall Boots, is urbanism collocation. This Christian louboutins shoes design makes people new and refreshing. Red soles shoes is personality, your charm will be wonderful performance.

  88. Avatar
    Cheap Beats By Dr.Dre over 3 years later:

    She stopped a few years, until the 2008 producer Vincent van Herbert sign her to Interscope.

  89. Avatar
    cheap air shoes over 3 years later:

    Yet addition breadth in which you can locate them for auction is suppliers which accommodate jeu things and merchandise.

  90. Avatar
    cheap china jerseys over 3 years later:

    Outlets that accept sports associated things are apprenticed to accept stocks of these articles in assorted models back of the addition in fresh era snapback and the newest developments in appearance for these hats.

  91. Avatar
    inexpensive jerseys over 3 years later:

    Physical purchasing provides you a likelihood to attending at the hat aloof afore you access it, not like back you are attractive on line.

  92. Avatar
    cheap snapback hats over 3 years later:

    Wide selection of brand new snapbacks a fresh installment of mitchell and ness x lakers snapbacks has just landed on the e-commerce runway new era snapback hat to match lebron 9 miami nights.

  93. Avatar
    cheap snapback over 3 years later:

    So in addition to 50 yards, you will apperceive that the hat youve compensated for matches you and of acceptable top quality.

  94. Avatar
    Backup iPhone sms over 3 years later:

    Well. try most of the other ways doesn’t work for me and I learn about this here and find the best method to solve this problem and it really good.

  95. Avatar
    lipozene over 3 years later:

    Your site always offer some really interesting information. Thank you for sharing it with us.

  96. Avatar
    medical billing georgia over 3 years later:

    The Java virtual machine is a software simulation of a real machine. When you run a Java program, the computer starts up the Java virtual machine and the virtual machine runs the program. Instructions from the program are translated by the virtual machine into instructions for the system it is running on. There are different versions of the Java virtual machine for each platform PC, Mac or Linux .. but the same Java program will run on any of them…. medical billing georgia

  97. Avatar
    Outlook Setting over 3 years later:

    Any language which can be compiled into JVM bytecode is able to be run by the Java Virtual Machine.. An example would be Jython, a Java bytecode compiler for the Python language… Outlook Setting

  98. Avatar
    bladeless fans over 3 years later:

    Adopting New JVM Languages in the Enterprise (Update) 97 good post139

  99. Avatar
    louboutin sales over 3 years later:

    Adopting New JVM Languages in the Enterprise (Update) 98 hoo,good article!!I like the post!103

  100. Avatar
    cheap adidas f50 over 3 years later:

    She kept true to the party’s nationalist theme, but, in an Cheap Adidas Adipure attempt to widen her electoral base, vowed to tone down the xenophobic legacy of her father. http://www.cheapadidasf50.com/ CF

  101. Avatar
    Injection mold over 3 years later:

    Intertech Machinery Inc. provides the most precise Plastic Injection Mold and Rubber Molds from Taiwan. With applying excellent unscrewing device in molds,

    Intertech is also very professional for making flip top Cap Molds in the world. Mold making is the core business of Intertech (Taiwan). With world level technology, Intertech enjoys a very good reputation for making Injection Mold and Plastic Molds for their worldwide customers.

  102. Avatar
    building a home brisbane over 3 years later:

    Thank you for another essential article. Where else could anyone get that kind of information in such a complete way of writing ? I have a presentation incoming week, and I am on the lookout for such information.

  103. Avatar
    Cap Mold over 3 years later:

    With more than 20 years of experience, Intertech provides an extensive integrated operational ability from design to production of molds 100% made in Taiwan. Additional to our own mold making factory, we also cooperate with our team vendors to form a very strong working force in Taiwan.

    For the overseas market, we work very closely with local representatives in order to take care of the technical communication and after-sales service to our customers. We also participate in the EUROMOLD & FAKUMA exhibitions and meet our customers every year in Europe. By concentrating on mold “niche markets”, we play a very useful mold maker role from the Far East whenever customers want to develop their new projects. We provide services from A to Z to our customers on a very economic cost and effect basis.

  104. Avatar
    cosplay store over 3 years later:

    http://www.outfitscosplay.com/cosplay-accessories/detective-conan-accessories Deluxe Detective Conan Accessories for Sale.Find your favorite characters and cosplay outfits from all the popular anime and games.

  105. Avatar
    japanese cosplay over 3 years later:

    http://www.outfitscosplay.com/cosplay-accessories/dragon-ball-accessories Deluxe Dragon Ball Accessories for Sale.Find your favorite characters and cosplay outfits from all the popular anime and games.

Comments