- Developer Tools
John Wetherill, January 21, 2013
Stackato has supported Java from the beginning, but without buildpacks the choice of Java runtimes has thus far been limited to exactly one: Java6 (née jdk1.6) which until recently was the most widely used Java release. Now that has changed. Java 7, codenamed Dolphin, was released by Oracle in July 2011, and while its reception didn't seem as enthusiastic as previous Java versions (see below for some reasons), its adoption is now gaining momentum.
So the time is ripe for Stackato and Java 7 to join forces. The latest Stackato release (2.6.7) includes Java 7 in its list of core runtimes, easily selectable at deploy time.
This article will summarize some of the additional features provided by Java 7, and step through deploying a Java Web application to Stackato using both runtimes.
Java 7: A Rocky Start
Shortly after the first release of Java 7 a number of serious bugs surfaced that resulted in such undesirable outcomes as file corruption, major performance hits, and "incorrect" loop execution. Scathing articles warned (using words like "dangerous" and "frightening") developers to stay away from Java 7 until its shortcomings were fixed.
Furthermore Oracle significantly reduced the scope of this release which had originally called for innovative features like closures, native XML support, and collection literals. Sadly none of these (along with several others) made the cut: instead they're being pushed to Java 8.
So what did make it in?
As with every major Java release to date, Java 7 claims considerable improvements in performance and security. These alone may be enough to encourage the move to Java 7. We'll dive deeper into performance below.
Java 7 also introduces a handful of language enhancements, mostly syntactic sugar, but useful as they help help improve the expressiveness, conciseness, readability, and maintainability of Java. These are a subset of JSR 334, known as "Project Coin," and include:
- The switch statement now allows strings
- Binary literals are supported
- Multiple exceptions can be caught in one statement
- Rudimentary type inference is now supported by the so-called "diamond" operator
There are some new and improved features too:
- a new File I/O API with better and faster handling of directories and concurrency
- a revamped garbage collector with higher throughput
- initial work on modularizing the increasingly bloated Java release
- enhancements to the JVM to better support dynamic languages
- a new fork/join concurrency framework for hardware parallelism
At first I was underwhelmed by the new features of this release (and I admit I was/am still lamenting the exclusion of closures). If the new features (file API, fork/join, etc.) aren't specifically needed, is it really worth an upgrade just for the minimal language enhancements?
But that's not taking performance into account. If performance is a concern (isn't it always?), it's certainly worthwhile evaluating an upgrade.
So let's do exactly that. I'll use Stackato to deploy a rudimentary benchmark to two application instances, one running Java 6, the other running Java 7.
Before looking at the application code itself, we'll look at the steps involved to tell Stackato to use Java 7 instead of Java 6 when deploying a Java application.
The Deployment Descriptor / Manifest
Stackato is good at deducing the runtime and framework required for agiven application, but we recommend including a configuration file (stackato.yml or manifest.yml) with each app to fully specify its characteristics and requirements. Since we want to specify a different runtime, this file is required.
For our simple benchmark application, which I'll build as a Java Web app, the stackato.yml file looks like this:
name: javabench framework: type: java_web mem: 1024M
No Java version is mentioned, so the default Java 6 is used. To use Java 7, add a single line "runtime:" directive:
name: javabench7 framework: type: java_web runtime: java7 mem: 1024M
A Rudimentary Benchmark
For the purposes of this article I need a barebones benchmark to exercise Java. A quick search rewarded me with a simple Java benchmark that's easy to understand (at a high level anyway), and is trivial to wrap into a class, which I'll call JavaBench.
I simply added a few lines to a basic "hello world" servlet that invoke JavaBench.bench() and print the result.
Then it's a simple matter of building the app and pushing to the Stackato cluster.
Using maven the steps are:
- mvn clean package
- add the stackato.yml file from above
- stackato push -n
After the push completes a URL is displayed. Visiting this in a browser results in a page that shows the Java version, and displays thebenchmark results.
I'd like to deploy both versions to the same Stackato cluster. This is easily accomplished by changing the name and runtime in stackato.yml...
# updated stackato.yml name: javabench7 framework: type: java_web runtime: java7 mem: 1024M
...and then pushing the app again:
$ stackato push -n
As expected, both apps now show up in the web console.
Visiting both urls shows the results:
The numbers show the effective performance in MFLOPS of each VM, and what do you know: Java 7 is faster. At least, it's faster according to this limited benchmark which focuses on numerically intensive operations and uses only a single thread. Your mileage will vary.
Using the same procedure (i.e., adding the runtime: java7 directive to stackato.yml) applications built with the Spring, Play, Java_EE, and Grails can also run with Java 7 SE.
This was is a long-winded way of saying that Stackato now seemlessly supports Java 7. Java-based applications, including those based on Spring, Play!, and Java_Web can now be deployed to Stackato to take advantage of the new features and improved performance that Java 7 offers.
Trackback URL for this post:
Share this post: