Tuesday Feb 17, 2015

Planning safe removal of under-used “endorsed extension” directories

As the Java platform moves forward, we look for ways to reduce and eliminate technical debt. One example is the planned removal of deprecated Garbage Collection combinations, as outlined in JEP 214. As another example, in Java 8 update 40, as part of JEP 220, we will be deprecating two rarely-used extension capabilities, with the intent to remove them in JDK 9, providing suitable replacements as necessary. Most developers do not use these features, and system administrators can quickly tell if any legacy systems will be affected.

What is changing: Removals of the endorsed-standard override mechanism and the extension mechanism

Previous versions of Java SE have allowed developers to place JAR files into two directories within the JRE, making anything in those JAR files available to all launched applications.

The original Endorsed Standards Override Mechanism enabled Java to quickly take advantage from new versions of external standards that were developed outside of the JCP, such as CORBA and XML Processing. As different libraries and build systems became available, developers have taken a preference of including such libraries directly within their applications rather than deploying these endorsed standards directories within the JRE. The Extension Mechanism enabled developers to do similar activities by placing JAR files into a jre/lib/ext directory.

Details about this planned change for JDK 9 can be found in JEP 220. The associated ticket, JDK-8065702 discusses the deprecation of the extension mechanism in JDK 8. As called out in the ticket, there will be a new JVM flag in JDK 8u40 that people can use to see if this change will cause any problems: -XX:+CheckEndorsedAndExt.

When is this change taking place?

A preliminary feature is being introduced in Java 8 update 40, that will allow developers to more easily identify if they will be affected by this change. No actual changes are being made; rather this is a tool to help identify potential future problems.

The actual change to remove this under-used functionality will take place alongside the release of Java 9. By providing detection tools in advance, we intend to help applications that plan to adjust.

Developers: Why most applications are unaffected

The majority of applications in use today do not use either of those features and will be unaffected by this change. Instead, most applications bundle third party JAR files. By bundling their own dependencies, applications could be moved between systems without requiring pre-requisite files to be installed inside the JRE. It has also made upgrades easier, where system administrators can upgrade the JRE without worrying about these internal directories.

If you are building or maintaining an application that requires third party JAR files to be present in the JRE, please consider providing those JAR files as part of your application.

System Administrators: How to tell if your applications are affected

System Administrators managing deployments may want to verify that their applications will be unaffected by this change.

Use a Java startup flag (recommended)

The easiest way to identify usage of endorsed standards is to ask the JVM to detect their usage.

When launching Java applications and servers, add -XX:+CheckEndorsedAndExt to your invocation. This will cause the system to print a message about any unexpected items in the endorsed standards or extensions directory.

Check your jre/lib/ext directory

One way to identify if this change will affect anything is to look at your JRE’s jre/lib/ext directory and see if there is anything present there that is not included by default.

The following is a sample list from my system to identify a normal installation. If your folders look like this, then you are not using the extension mechanism.

Java 8 update 25 jre/lib/ext
Java 7 update 60 jre/lib/ext
Thirteen (13) files:
  • access-bridge-64.jar
  • cldrdata.jar
  • dnsns.jar
  • jaccess.jar
  • jfxrt.jar
  • localedata.jar
  • meta-index
  • nashorn.jar
  • sunec.jar
  • sunjce_provider.jar
  • sunmscapi.jar
  • sunpkcs11.jar
  • zipfs.jar
Nine (9) files:
  • access-bridge-64.jar
  • dnsns.jar
  • jaccess.jar
  • localedata.jar
  • meta-index
  • sunec.jar
  • sunjce_provider.jar
  • sunmscapi.jar
  • zipfs.jar

The presence of anything listed above is normal and expected. Other files are not.

What to do if you are affected

Although most applications do not use the endorsed standards or extension mechanism, some applications do. If you are a developer, please consider providing dependencies as part of your application rather than requiring external system configurations. If you are not the developer, please contact the individual software vendor for support.

Monday Jan 05, 2015

Java Web Start in or out of the browser

The Java Runtime Environment offers a number of ways to run applications. On client systems, one common method is Java Web Start. It allows applications to be launched through browsers or directly via the Java Network Launching Protocol (JNLP). This capability was introduced back in 2001 and has been used by many applications throughout the years. It is quite common in enterprises and certain countries.

As browsers evolve, many users still need to continue to run these applications. Since Java Web Start applications can be launched independently of a browser, as they don’t rely on a browser plugin, in many cases they can provide a migration path from Java Applets.The business owners of these applications may have additional questions about how the support lifetime of Java Web Start affects their applications.

JDK Support Timelines

At present, Oracle offers two publicly available, supported versions: Java SE 7 and Java SE 8 (most current). Both are available through the Java.com website and Oracle Technology Network (OTN). I encourage users and developers to upgrade to Java SE 8.

Oracle’s support timeline is described on the SE Roadmap web page. Companies or ISVs that require support and/or updates after the end of public availability can obtain a commercial solution. This timeline extends well beyond the end of public updates and includes patches/updates to the Deployment Technology for Applets and Web Start applications as described.

Commercial support customers (including ISVs) may continue to use JDK 7 and JDK 6 for years beyond its end-of-public-updates and receive regular updates. This includes the ability to file support tickets with Oracle.

Other users should upgrade to Java SE 8.

Running Web Start Applications

Users that need to run Web Start application may launch that application through a web browser such as Internet Explorer, Mozilla Firefox, Apple Safari, or Pale Moon. Chrome users may consult "How do I use Java with the Google Chrome browser."

Most users should obtain Java directly from the Java.com website. Advanced users may download via the Oracle Technology Network and should choose the correct 32 and/or 64 bit version.

Controlling prompts and dialogs

Java prompts and dialogs about execution can be controlled through Deployment Rule Sets or the Exception Site List. Deployment Rule Sets work well for enterprises that need to run different Java applications with different Java versions. The Exception Site List works well for an end-user that wants a specific Java RIA to run. Additional details can be found at:

Companies that need to create Deployment Rule Sets may consider using the Advanced Management Console.

Many browsers have their own dialogs and control mechanisms. For example Internet Explorer has a post about their dialogs with the phrase, "Can this feature be disabled if my enterprise requires an older version of the Java runtime?"

Running Web Start applications outside of a browser

Web Start applications can be launched directly with a JNLP file. Application developers may consider providing a direct link for users to download their JNLP files.

Example instructions on Windows:

  • Right-click any JNLP file that you have downloaded.
  • Select Properties.
  • Next to “Opens With,” click the Change button.
  • Locate your Java version and choose javaws.
    The recommended program is “Java(TM) Web Start Launcher.”
    Example path: C:\Program Files\Java\jre1.8.0_40\bin\javaws.exe

Additional Deployment Options

With changes in web browser plugins, application developers may consider alternative distribution methods. Several options are available:

Native Windows/Mac/Linux packages

The javapackager command allows developers to create standalone native install bundles that do not require a separate JRE installation. The native options include: installer, image, exe, msi, dmg, rpm, and deb.

This is ideal for desktop applications, where the user may not have their own JRE installed and just wants the program to run.  It may not be appropriate for server-based applications where an administrator would want full control over the environment.

Inverted browser control

JavaFX contains a feature called WebView, which enables applications to use an embedded version of WebKit to render HTML5 content. As a result, developers can create applications that use this browser to access remote applications.

For example, a developer could create a miniature web browser that makes it easier for their users to launch remote applications. WebFX is a prototype example of this behavior.

Thursday Dec 18, 2014

Node.js and io.js on Java

The Nashorn JavaScript engine is one of many improvements in JDK 8. Nashorn (German for Rhino) is a faster replacement for the previous JavaScript engine known as Rhino. There is also another noteworthy feature: the ability to run many Node.js and io.js applications in the JVM. These applications can then call back and forth between optimized Java libraries and automatically receive monitoring capabilities through JMX.

In the upcoming JDK 8 update 40, it is planned to improve Nashorn / JavaScript performance even further through optimistic typing.

Java Virtual Machine - More than just Java

The Java Platform offers a way to run different types of applications, even if those applications are not written in the Java programming language. As a result, developers can take advantage of optimizations and stability of the JVM, while system administrators can better control and monitor deployments.

Examples of other languages on the JVM include: JavaScript (Nashorn), Ruby (JRuby), Python (Jython), Scala, Groovy, and many others.

Project Avatar – A JavaScript services layer on the JVM

Avatar.js is a project to bring the node programming model, APIs and module ecosystem to the Java platform. Although written in JavaScript, these applications can take advantage of the Java platform's scalability, manageability, tools, and extensive collection of Java libraries and middleware. After downloading the Avatar.js binaries, developers can then execute their applications. For example, Tim Caswell’s article "Hello Node!" contains basic examples for hello-console.js and hello-http.js that can be used as a basic way for testing Avatar.

Nashorn, The Hidden Weapon of JDK 8 was presented at the Silicon Valley Java User Group meeting in December 2014. The available slides describe the use of Nashorn and Avatar at Netflix and provide additional Nashorn demos.

Avoid rewrites and re-use libraries

One major benefit of running serverside JavaScript applications within the JVM is access to Java libraries. Developers do not have to rewrite major libraries or functionality like SQL or NoSQL drivers, Hadoop clients, encoding libraries, etc. Additional examples are available in a previous post, Nashorn: the rhino in the room, but they are not specific to Node.js.

Niko Köbler has a two-part article about Avatar 2.0 and its Model Store API. By using this model store API, developers can more easily interact with SQL and No-SQL and benefit from many existing optimizations.

  1. Part 1 explains the architecture and threading model.
  2. Part 2 covers the technology behind the Model Store API.

Monitoring Applications on the JVM

All Java processes can be monitored through a mechanism called JMX. System Administrators can enable remote authenticated JMX connections and see inside these running applications, rather than monitoring from the outside coming in.

Additional details about JMX monitoring (both local and remote) can be found in a previous post, Deep Monitoring with JMX.

Monitoring applications with Mission Control / Flight Recorder

Java Flight Recorder is an effective way of monitoring JVM applications in production. Unlike standard development profilers (like the NetBeans profiler), Flight Recorder has negligible performance impact.

The dashboard view in Mission Control provides basic information about CPU and memory resources. Developers may use the Threads tab to better understand system throughput, or if the application is blocking around any particular resources.

To open Mission Control, run the jmc command and connect to your Avatar application. The screenshot below shows Mission Control monitoring a Node.js application identified as com.oracle.avatar.Server.

Monitoring Node.js on Java

Although the Node.js applications are written in JavaScript, Flight Recorder can also perform trigger-based recordings on events, such as a CPU spike. System Administrators and Developers can look back at the recording to see what lead up to the event.

Additional details are available on the Mission Control home page and user guide.

Additional ways of running Node.js on the JVM

Avatar is one of several ways to run Node.js applications on the JVM.

When run on Oracle Java, both projects can be monitored by Flight Recorder / Mission Control as described above. Because this monitoring is provided directly by the Oracle JVM itself, there is no need to make any code changes or apply additional monitoring packages.

Monday Dec 15, 2014

Upgrading major Java versions - technical

Many users have already upgraded from Java 7 to Java 8, to benefit from improvements in speed, brevity of code, and lower memory usage. Other users have asked for more prescriptive guidance of the upgrade: when to make the change, what to expect, and how to do it in a controlled manner.

Relation to a previous post

A previous post, Upgrading Major Java Versions, provides details for certain stakeholders: support timelines, compatibility guides, lists of changes, and different supporting material.

This post is intended to provide more prescriptive guidance of upgrading your Java SE version: how to test components and features designed to control behavior and upgrade part of your environment in stages.

The decision to upgrade is not only for companies that develop software; it also applies to users running software built by others. In many cases, users can see significant speed improvements without recompiling, simply by upgrading the runtime.

Planning upgrade in stages

The previous post explains when to upgrade in relation to platform support. When upgrading infrastructure, it is important to segment the architecture. Rather than upgrading everything at the same time, separate it into different environments so that you can test each one on its own.

Typical environments, in my preferred order of when to upgrade:

  1. Developer workstations, where developers write and test code. This is most likely where you would run IDEs like NetBeans, Eclipse, or IntelliJ.
  2. Central build servers, where code is combined, built, and unit tested through automation. Common software is Hudson or other continuous integration software. Some organizations do not have central build servers.
  3. Test or QA servers. This environment may run your application in order to find any issues before release into production.
  4. Production servers. The final environment that should be upgraded last, these servers run your application for users.

High level upgrade plan: Upgrade the build and test environments but keep things targeted for production. Once you are ready, upgrade the production environment and begin taking advantage of new features.

Backwards Compatibility

The JDK is backwards compatible, meaning that JDK 8 can run binaries produced by JDK 7 and JDK 6. The javac compiler can also produce binaries targeting earlier versions of the JDK. In planning to upgrade, we will use this capability.

Upgrading Developer Workstations and/or Central Build Servers

The important similarity between developer workstations and central build servers is that they are used to compile the application from source code into binary artifacts, such as JAR and WAR.

Upgrading a workstation or build server involves upgrading its JDK installation. The same system may run multiple versions of the JDK side-by-side, making it your choice if you want to uninstall the older one.

Environment Variables for installation

If you choose to run multiple versions, just be mindful of two environment variables:

  • PATH – identifies which actual java executable your system will use when you call java. You can circumvent this by explicitly calling the executable via /opt/jdk8/bin/java or /opt/jdk7/bin/java commands. Just call the one you want to use at the time. If you use scripts that rely on environment variables, consider isolating your terminals if you change the environment.
  • JAVA_HOME – some applications use this variable to identify where Java is.

Test your upgrade the following commands:

  • java -version
    • This should reply back with 1.8 or 1.7 depending on which you want. Just make sure it is right
  • echo $JAVA_HOME
    • On Linux, that will identify the JAVA_HOME variable that some applications may use. Check that it is the installation you intend to use.
    • On Windows, use: echo %JAVA_HOME%
    • You can also check the entire process with:
      • Linux: $JAVA_HOME/bin/java -version
      • Windows: %JAVA_HOME%\bin\java -version

Personal Tip: On my Windows 7 laptop, I regularly switch Java version to test things. To counter forgetfulness, I set my JAVA_HOME variable first, and then my PATH uses that JAVA_HOME. By doing this, I only need to change one thing. My PATH starts with: %JAVA_HOME%\bin;

Cross-compiling to meet your runtime’s compatibility

By using your upgraded installation to cross-compile, you will produce artifacts that run in your not-yet-upgraded test and production environments.

The javac compiler provides three options to control compatibility: -bootclasspath -source and -target. Without the -source flag, the compiler won’t warn you about using language features that may not be available on your earlier target JDK platform.  Without the -target flag, the compiler won’t produce binaries that can run on your earlier target JDK. Finally, without the -bootclasspath flag, the compiler won’t be able to find the correct version of the core class libraries from the earlier JDK. A simple example of using all flags correctly can be found in the javac documentation’s Examples section.

Configure the build to specify the -source and -target of your runtime.

  • Regular javac: -source 1.X -target 1.X
    If you have the older JDK: javac: -source 1.X -target 1.X –bootclasspath JDK1.6/lib/rt.jar
  • Maven: Modern versions of maven have a <maven.compiler.source>1.X</maven.compiler.source> attribute that can be set in properties. Alternately, use the maven-compiler-plugin attributes like <source/> and <target/>
  • Ant: The <javac source="1.X" target="1.X" /> task, or you can use a separate ant.build.javac.source property.
  • Etc. consult your build system’s documentation.

Monitor compiler errors and warnings

Building your application with the latest JDK will identify any potentially problematic areas. Investigate compiler errors, if any.

Although compiler warnings do not cause build failures, they indicate areas of interest. Looking into them provides a safeguard of something that may affect compatibility or legibility of code.

In JDK 8, we added special indicators to point where incompatibilities may occur in the future.

com/example/App.java:[32,24] SOMETHING is internal proprietary API and may be removed in a future release

In this example, my code has made use of a JDK internal API on line 32 of App.java. If you see this message, your code will likely still work for now but you should consider moving towards the known-compatible replacement for that API.

Use jdeps or other compatibility analyzers

OpenJDK 8 features a new dependency analysis tool, jdeps, designed to identify where applications or their dependencies make use of internal JDK APIs. Usage of these APIs does not currently indicate incompatibility, rather they point out where you use non-public and unsupported internal APIs.

If jdeps identifies usage in your code, consider switching to the public replacement APIs. If jdeps identifies usage in third party code, you may still be impacted in the future. Consider upgrading those identified dependencies, patching them, or identifying an alternative.

We have previously limited access to some internal APIs in some situations. The publicly supported APIs are still available, unaffected, and fine to use.

Consider additional tools for analysis as well:

  • The Forbidden APIs project also helps identify cases where certain APIs either should not be used or should be used differently. In addition to identifying internal APIs, this finds potential locale and encoding issues.
  • The Modernizer Maven Plugin also locates legacy APIs. While jdeps is focused solely on internal JDK APIs, this finds them in other projects. That may be useful if you are upgrading those other projects as well.

Running an application in test or production

Upgrading the test and production environments will allow you to evaluate an application and see how it interacts with other systems.

The JDK is designed to be backwards compatible. Upon upgrading the test environment, it is your choice if you want to run the same cross-compiled binary.

When testing your application, it is important not to change too many things at once. For example if you test the upgrade while simultaneously testing a complete rewrite of major components at the same time, it will be hard to tell which issue came from which cause. Given time available for testing, is may not be feasible to test the upgrade alone, without any other changes. Isolate changes as best you can and do not pre-assign a root cause to any issue before investigation.

Once you have successfully upgraded your environment(s), there is no more reason to cross-compile your binaries. Consider going back to your build environment and removing the -bootclasspath, -source, and -target flags.

Environmental changes

The previous post, Upgrading Major Java Versions, provides links to detailed information and compatibility guides about what changed between different versions.

In the interest of brevity, I will list a few noteworthy differences that I have seen:

  • JDK 8 uses TLS 1.2 as its default transport protocol for connections like https. JDK 7 made TLS 1.2 available but did not use it as the default. JDK 6 did not offer this protocol. For details, see JDK 8 Will use TLS 1.2 as its default and Diagnosing TLS, SSL and HTTPS.
  • JDK 8 no longer has a type of memory called PermGen, as it was replaced by Metaspace. This should not affect most people, but older startup scripts may have used -XX:MaxPermSize options. This should not cause problems, as tuning PermGen will no longer do anything. Please consider removing unnecessary startup options as a good measure.
  • Startup switches that begin with -XX: should be validated to see if they still apply. The java command documentation identifies these as advanced options not recommended for casual use. They are subject to change. If you experience unexpected behavior or slower performance, your flags may be working around a problem that no longer exists.
  • Applications using a ScriptEngine like JavaScript will use the newer/faster Nashorn in place of the previous Rhino interpreter. If your application made extensive use of Rhino and you find errors after upgrading, please consult the Rhino Migration Guide.

Uptake of Java SE 8

Many applications are able to leverage a smooth upgrade path from JDK 7 to JDK 8, in order to benefit from improvements like speed and more concise code. Examples of teams that have successfully migrated include:

I will continue monitoring different areas and will try to follow up in the future with different strategies for upgrading.


Thursday Dec 11, 2014

That's so SecureRandom

Random numbers are an important part of software systems, especially those that deal with security or encryption. The Java platform offers different types of randomness based on intent, and static typing can further guide that choice for library developers.

This post is intended to explain how the Oracle JDK provides random numbers, to guide their usage:

  • Developers building Java software, to use the right randomness in the right place.
  • Companies buying or running Java software to understand how to evaluate or control that software.
  • System Administrators tuning the security and performance of those systems, understanding why/where/how to make adjustments.

Randomness in the JDK

Java SE provides three mechanisms for generating random numbers based on their usage:

  1. A fast Random number designed for basic tasks where true randomness is not the main goal. This is useful for things like which shade of color to use, preventing overlap in force-directed layouts, or which picture to show from a list after evaluating demographic information.
  2. High-concurrency programs may also use ThreadLocalRandom if they value speed over true randomness. This is the same as above but will likely give better performance if simultaneous threads generate pseudo-random numbers at the same time.
  3. A slower but more random SecureRandom designed for important tasks where the inability to predict numbers is crucial to success. Examples include cases like gambling, scientific sampling, or any cryptographic operations. Although slower than the other two random number generators, its better randomness in many applications.

Having these choices allows developers to make the appropriate decision based on their application.

The Java Platform also allows software operators to override and control this behavior. For example improving true-ness of the Random generator or improving speed of SecureRandom with dedicated hardware.

Security through static typing

Java’s static typing can also enforce that program authors and library users apply the proper Random implementation. The random classes are designed with inheritance, allowing full interoperability across implementations. Both SecureRandom and ThreadLocalRandom inherit from Random, which means that implementations can be swapped or specified:

Random pseudoRandom = new Random();
Random pseudoRandomConcurrent = ThreadLocalRandom.current();
Random secureRandom = new SecureRandom();

For API design, developers can choose to only accept the appropriate version based on their use case. Given that true randomness is crucial to the success of cryptographic operations, it is critical that cryptographic APIs only accept SecureRandom arguments and never the super-class of Random. One example of this is KeyPairGenerator, which helps generate public/private keys that are used by many cryptographic systems. Users can only seed this with true-random values and not pseudo-random values.

KeyPairGenerator.initialize(int keysize, SecureRandom random);

Developers can only call this method by using statically-typed SecureRandom values. The super-type Random PRNG, which might make predictable keys, cannot work. Calling the overloaded KeyPairGenerator.initialize(int keysize) will also use a SecureRandom and is fine, the point here is that static typing prevents other types of Random from being used.

Using the previous example, one could call:

kpg.initialize(4096, (SecureRandom) secureRandom);

Or by specific static typing:

SecureRandom staticEnforcement = new SecureRandom();
kpg.initialize(4096, staticEnforcement);

API designers building secure systems should follow this example of statically typing SecureRandom in method signatures. When vetting secure software, look for usage of Random where a SecureRandom might be more appropriate. The US CERT Java coding guidelines offer additional guidance on evaluating the use of random numbers. Simon Kitching also has a good write-up about Using the SecureRandom Class.

Sources of Randomness

The sources for randomness are listed in the JDK’s security Standard Names documentation, identifying which are blocking or non-blocking. Although some sources rely on entropy pools, SecureRandoms like SHA1PRNG are quite fast once seeded and do not need additional entropy.

Blocking is especially important on Linux systems, where some calls to /dev/random may pause while the system generates a new true-random number. There is a trade-off /dev/urandom device that is non-blocking but somewhat less random.

Within a Java installation, the administrator can adjust various settings through the "JRE/lib/security/java.security" configuration file. That file contains documentation about configuring securerandom.source and securerandom.strongAlgorithms. On Linux systems, the administrator may set their securerandom.source to  /dev/random or /dev/urandom accordingly.

Each operating system contains its recommended default value. System Administrators may edit that value, for example if their system has different RNGs or if they have a separate specialized hardware RNG.

JavaMex has a page describing the sources of entropy that Java uses on different operating systems.

Additional information is available in the SecureRandom javadoc.

Monday Oct 13, 2014

Upcoming Oracle Java SE 7u72 PSU

On October 14th, Oracle plans to release the regularly scheduled Critical Patch Update (CPU) release for Oracle Java SE.  

For Oracle Java SE 8, that is version 8u25.  We now encourage all Java users to download and use the latest Java SE 8 update release.  With this release, Java SE 8 is ready to debut as the default on Java.com, and as we've previously noted we will begin auto updating users to Java SE 8 in early 2015. 

For Oracle Java SE 7, there will be two releases targeting different audiences:

  • Oracle Java SE 7u71 is the regular CPU containing only security fixes.  This is the intended upgrade for most users
  • A separate Oracle Java SE 7u72 is available for developers and users requiring additional non-security improvements or for testing updated features.  You should use 7u72 if you are facing any of the specific issues as noted in its release notes, and also as part of your quality assurance cycles.  These improvements and features are planned to appear as part of the next scheduled CPU in January 2015.

For more details, please see the OTN Article "Java CPU and PSU Releases Explained". 

 - Don

 

Monday Oct 06, 2014

Upgrading major Java versions

With the release of Java 8 back in March 2014, many users have already upgraded. They can take advantage of new features such as:

There are many write-ups and tutorials that cover what’s new in Java 8. The Oracle Java 8 launch videos gathered knowledge together from many people directly involved in creating Java SE 8.

Rather than covering specific features, I would like to gather details that many software teams should understand as they work on projects.

  • What are the support lifetimes of each version of the Oracle JDK?
  • Where do we find the list of changes across the major version, such as from Java SE 7 to SE 8?

Noteworthy Points

Oracle Java SE major releases are updated for the public with bug fixes, security fixes, and minor updates for a period of at least 3 years before the release reaches end-of-public-updates (EoPU). Oracle Java SE commercial product releases are supported for an even longer period of time from initial release date, enabling IT managers and ISVs to plan their upgrades according to their individual business practices.

The release notes of major releases contain a compatibility guide about migration. Please consult the guide in addition to testing your program.

Upgrades can be controlled and done in pieces, rather than upgrading all environments at once. Start with developer systems, then test environments, then production systems.

Backward Compatibility

Java versions are expected to be binary backwards-compatible. For example, JDK 8 can run code compiled by JDK 7 or JDK 6. It is common to see applications leverage this backwards compatibility by using components built by different Java version. A Compatibility Guide (explained later) exists for each major release to provide special mention when something is not backwards compatible.

Oracle Java SE Support Timelines

Oracle provides thoroughly tested binaries across a number of platforms along with additional tools for management and monitoring.

The Oracle Java SE Support Roadmap identifies periods during which Oracle offers free (gratis) updates for a Java version.

Oracle Java SE Version General Availability End of public updates notification End of public updates
This copy only lists dates before its publication. See support roadmap for all current information.
8 March 2014
(see roadmap)
(see roadmap)
7
July 2011
March 2014
(see roadmap)
6 Dec 2006
Feb 2011
Feb 2013 (maintenance releases through Java SE Advanced)
5 May 2004
Apr 2008
Oct 2009


Users can purchase Oracle’s commercial Java SE offerings, which provide support and updates beyond the end of public updates.

There are some general rules to deal with these timeframes:

  • Users may evaluate and provide feedback on Early Access Releases before the general availability of a specific major version. For example, eager developers can already test JDK 9 as it is being developed.
  • Users may consider upgrading to a major release any time after it becomes generally available. Once the end of public updates notification goes out, users of this version should begin to plan to upgrade to the next major release.
  • User who chose to avoid upgrading to the next major release can obtain a commercial support contract for Java SE in order to keep receiving updates.

Identifying the list of changes between major versions

Many application owners and developers begin their upgrade planning shortly after general availability of a major Java SE release. General availability is a time when changes and benchmarks stabilize a little, offering a more concrete understanding of, after upgrading, what will happen in production environments.

The first general availability release contains a special piece in its release notes: the Compatibility Guide. This compatibility guide provides information about what one might encounter when upgrading an application from a previous version, such as from JDK 6 to JDK 7 or from JDK 7 to JDK 8. Those skipping a version from JDK 6 straight to JDK 8 may want to consult the guide for JDK 7 in-between.

If reading the release notes causes an analysis paralysis, consider using your application in a test environment. Then go back to check the notes and you may have a better understanding of what to look for while reading.

In addition to the release notes, there are a large number of "What’s New" write-ups that showcase changes from a user perspective.

For Java SE 8, here are a few good articles that both describe and teach new features:

Presentations specific to upgrading the major Java version:

Two other presentations explicitly cover upgrading across major Java versions:

  • Smart Migration to JDK 8 by Geertjan Wielenga provides guidance on new features and how to update applications.
  • Java 7 State of the Enterprise by Markus Eisele contains good information about upgrading from JDK 6 to JDK 7. The strategic guidance on upgrades is beneficial, but it was written in 2011 when Java SE 7 was still new.

Uptake of Java SE 8

At present, both Java SE 7 and Java SE 8 are publicly updated per the Oracle Java SE Support Roadmap. The period of overlap allows thorough testing of both versions, with updates addressing issues that were identified. The current plan to debut Java 8 as the default on Java.com before the end of 2014 comes as a result of good testing: the Fedora project is switching their default, new versions of Scala will only run on Java 8, etc.

I encourage you to consider upgrading systems to use Java SE 8 and take advantage of speed, shorter code, and the other benefits that it provides.

Friday Sep 19, 2014

Choosing 64 and/or 32 bit Java

The Java Platform was designed to allow applications to run on different hardware stacks and operating systems without changes. Java is available on Microsoft Windows in 64 and 32 bit versions, allowing users to get the appropriate version for their system. Users can even run both side-by-side for 64 bit operating systems.

Getting the right version

End-users should visit Java.com and click the Free Java Download link. The site will auto-detect the web browser and serve the appropriate download.

For an explanation of how the website makes that determination, please see "Which Java download should I choose for my 64-bit Windows operating system.”

Java with 64 and/or 32 bit web browsers

Users that run Applets and Web Start applications through web browsers should choose the version of Java that matches their web browser. Generally speaking, 64 bit browsers run only 64 bit plugins and 32 bit browsers run only 32 bit plugins.

As of mid-September 2014:

When you have a choice, there are many benefits to choosing 64 bit.

Running 64 and 32 bit side by side

Most users in managed environments should choose which browsers and runtimes to use – managing one installation is easier than two.

If you cannot choose or do not know which you should choose, you can run both the 64 bit and 32 bit Java on the same computer. The relevant plugins will be available for both browser types, and system-wide configurations like Deployment Rule Sets will automatically apply to both

When running both 64 and 32 bit versions on a Windows client, there will be two installations:

  1. C:\Program Files\Java\jre8 – The 64 bit version, available for local processes and 64 bit browsers like Internet Explorer (64 bit).
  2. C:\Program Files (x86)\Java\jre8 – The 32 bit version, used currently by browsers like Firefox and Chrome.

Any configuration changes made to the runtime itself (e.g. inside the JRE folder) must be made to both Java installations: “Program Files” as well as “Program Files (x86).”

Advanced Windows users that run local Java programs may want to check the following attributes as well:

  • The PATH environment variable, to ensure that the preferred Java path is listed first. On my system, I use my 64 bit installation.
  • The JAVA_HOME environment variable, if set, should point to the preferred Java. On my system, I use my 64 bit installation.
  • The file associations for .jar and .jnlp files. On my system, I open them with my 64 bit Java.

In the above examples on my system, I have chosen 64 bit each time. To do that, I also changed my browsers around to use the 64 bit version as the default and installed a separate 32 bit Java specifically for my Firefox client.

Upgrades and Patches

The 64 and 32 bit Java installations are separate from each-other. If you choose to use both, please plan to upgrade both at each scheduled Critical Patch Update or as prompted.

If you decide to customize a JRE installation, such as disabling third party sponsor offers or changing Certificate Authority roots, you need to do that customization on both installations.

Tuesday Aug 19, 2014

New Management Console in Java SE Advanced 8u20

Java SE 8 update 20 is a new feature release designed to provide desktop administrators with better control of their managed systems. The release notes for 8u20 are available from the public JDK release notes page. This release is not a Critical Patch Update (CPU).

I would like to call attention to two noteworthy features of Oracle Java SE Advanced, the commercially supported version of Java SE for enterprises that require both support and specialized tools.

  • The new Advanced Management Console provides a way to monitor and understand client systems at scale. It allows organizations to track usage and more easily create and manage client configuration like Deployment Rule Sets (DRS). DRS can control execution of tracked applications as well as specify compatibility of which application should use which Java SE installation.
  • The new MSI Installer integrates into various desktop management tools, making it easier to customize and roll out different Java SE versions.

Advanced Management Console (product page)

The Advanced Management Console is part of Java SE Advanced designed for desktop administrators, whose users need to run many different Java applications. It provides usage tracking for those Applet & Web Start applications to help identify them for guided DRS creation. DRS can then be verified against the tracked data, to ensure that end-users can run their application against the appropriate Java version with no prompts.

Usage tracking also has a different definition for Java SE than it does for most software applications. Unlike most applications where usage can be determined by a simple run-count, Java is a platform used for launching other applications. This means that usage tracking must answer both "how often is this Java SE version used" and "what applications are launched by it."

Usage Tracking

One piece of Java SE Advanced is a centralized usage tracker. Simply placing a properties file on the client informs systems to report information to this usage tracker, so that the desktop administrator can better understand usage. Information is sent via UDP to prevent any delay on the client.

The usage tracking server resides at a central location on the intranet to collect information from those clients. The information is stored in a normalized database for performance, meaning that a single usage tracker can handle a large number of clients.


Guided Deployment Rule Sets

Deployment Rule Sets were introduced in Java 7 update 40 (September 2013) in order to help administrators control security prompts and guide compatibility. A previous post, Deployment Rule Sets by Example, explains how to configure a rule set so that most applications run against the most secure version but a specific applet may run against the Java version that was current several years ago.

There are a different set of questions that can be asked by a desktop administrator in a large or distributed firm:

  • Where are the Java RIAs that our users need?
  • Which RIA needs which Java version?
  • Which users need which Java versions?
  • How do I verify these answers once I have them?

The guided deployment rule set creation uses usage tracker data to identify applications both by certificate hash and location.


After creating the rules, a comparison tool exists to verify them against the tracked data: If you intend to run an RIA, is it green? If something specific should be blocked, is it red? This makes user-testing easier.

Check if the rule is right

MSI Installer

The Windows Installer format (MSI) provides a number of benefits for desktop administrators that customize or manage software at scale. Unlike the basic installer that most users obtain from Java.com or OTN, this installer is built around customization and integration with various desktop management products like SCCM.

Desktop administrators using the MSI installer can use every feature provided by the format, such as silent installs/upgrades, low-privileged installations, or self-repair capabilities

Customers looking for Java SE Advanced can download the MSI installer through their My Oracle Support (MOS) account.

Java SE Advanced

The new features in Java SE Advanced make it easier for desktop administrators to identify and control client installations at scale. Administrators at organizations that want either the tools or associated commercial support should consider Java SE Advanced.

Monday Aug 11, 2014

Keeping users on Internet Explorer up-to-date and secure

New features announced by Microsoft give Internet Explorers users, developers and sysadmins more tools to keep users of Java up to date and secure.[Read More]

Monday Aug 04, 2014

Java 7 update 67 patch release

The recent Java 7 update 65 contained an issue that prevents some Applet and Web Start applications from launching. As a result, we have released Java 7 update 67 to restore the functionality for affected users.

This issue only affects some Rich Internet Applications and does not impact client or server-side applications. Java 7 update 67 is a functionality release: it is not a security fix or Critical Patch.

End Users

 Download the latest release from java.com.

The functionality issue in the previous release does not affect all applications, but having the latest release removes the question of which applications are or are not affected.

Support Professionals

If your users reported being unable to launch Rich Internet Applications after installing 7u65, please guide them to upgrade to 7u67.

Release notes for 7u67 explain issue JDK-8050875, which can manifest itself with RIAs launched using a java_arguments parameter such as <param name="java_arguments" value="-Xmx192m"> but the client’s deployment.properties file does not contain a matching "deployment.javaws.jre.X.args=" entry.

Please guide users to download and install Java 7 update 67.

If your users are unable to upgrade, you may guide users to perform the following steps as a workaround:

  1. Open the Java control panel.
  2. Select the Java tab.
  3. Click View
    • In the "Runtime Parameters" area, enter the number 7 and then backspace over it.
  4. Click OK.

Wednesday Jul 30, 2014

Deep monitoring with JMX

The Java Platform is designed as a modular system, where each item in the conceptual diagram provides specific functionality. One commonly requested feature of software platforms is the ability to monitor an application for CPU, memory and resource usage, and other statistics. The Java Platform Standard Edition (Java SE) has provided the Java Management eXtension (JMX) since Java SE 5.0 (2004). There are several benefits to having this type of monitoring as part of the platform:

  1. Unlike operating system tools (e.g. htop or Task Manager), the details are specific to the application. Instead of just overall CPU and memory usage, it is possible to see what part of the application is consuming those resources.
  2. Applications can surface their own business-related Management Bean to the JMX rather than building a new monitoring user interface.
  3. The monitoring agent is already available inside the runtime. There is no need to embed additional items in your application.
  4. JMX connections take place at the JVM level rather than inside the application. Monitoring information is available either locally or remotely. By using different firewall rules for JMX than your application, you can scope monitoring to a smaller audience.
  5. System administrators can institute direct connections rather than periodic polling, for faster alerts or reaction time.

This entry will cover the role of JMX and the ways in which it is designed to help developers and system administrators.

JMX Basics: an agent and a viewer

JMX capabilities are split into two parts:

  1. The JMX agent that serves information is available within the runtime. This runs alongside your application.
  2. A JMX viewer, like jConsole or Java Mission Control. These viewers use a local or remote connection to read information from the running agent. Other third party viewers will be covered later.

By default, jConsole shows information about memory usage, CPU usage, thread usage, and class information. Unlike standard operating system tools like htop or Task Manager, the information is at a deeper level inside the JVM and can also seen on authenticated remote systems. By default JMX allows local connections to the process owner -- instead of username/password, you are authenticated by NTFS permissions (on Windows).

screenshot of jconsole

In this screenshot of one small Java application I was running, you can clearly see the periodic small garbage collections. The minor incremental collection has significantly improved since the late 1990s.

The separate MBeans tab provides ways to show additional diagnostics as well as additional information. When using third party Java applications, I often launch them through small scripts and do not know the complete invocation information. The com.sun.managementDiagnosticCommand lets me click a "vmCommandLine" button and see what the launch script actually did.

screenshot of jconsole

In many situations, such as application servers, the application may be running on an entirely different host.

Authenticated remote monitoring for System Administrators

Any remote monitoring system must come with proper access controls built in. The remote monitoring capabilities in JMX allow for clients to monitor information happening on servers or other devices without having any user interface on those systems. Applications typically turn on remote JMX capabilities either through launch scripts setting:

-Dcom.sun.management.jmxremote.port=portNum
-Djava.rmi.server.hostname=OptionalHostnameConnectionRestriction

When specifying the port number above, it is an important distinction that JMX information is served separately from the application. For example a web application might serve requests on ports 80 and 443 yet allow JMX connections on a separate port with more restrictive firewall rules. Normal users would be unable to even attempt JMX access.

After configuring a firewall rule, it is critical to authenticate users against one of the three main methods:

  1. File-based passwords are probably the simplest to set up but require a shared secret and are sometimes harder to change. Your JRE already has an example configured file at JRE/lib/management/ jmxremote.password.template.
  2. LDAP for enterprises. The benefit of LDAP integration is group authentication, as well as automatic integration with joiner/leavers processes.
  3. SSL certificates for password-less connections. This allows client authentication based on public keys in a way that no passwords are ever exchanged.

The JMX Agent user guide contains details on all other JMX configuration parameters. These capabilities can also integrate JMX with SNMP tools. For other protocols, consider using JMXMP through OpenDMK.

Do not turn security off

Within the JMX documentation, there are options listed for turning security off so that no authentication and authorization is performed on connections. Do not use that configuration unless you are temporarily testing a different tool and just wondering if authentication is causing a problem. Once you ascertain yes or no, you should stop turning authentication off.

Third party monitoring example: Nagios

JMX provides a level of application introspection that provides system administrators with a way to look inside the application and provide some level of diagnostics that are beneficial to the development teams. It can also be integrated into systems like Nagios’ JMX monitor and extends alert and monitoring capabilities to act on the extra details.

Exposing custom metrics to JMX for Developers

Items within the Java platform are designed for extensibility. While all applications look for details about resource usage, other information can be beneficial. The Java tutorial on JMX provides details on how to create new MBeans that would expose custom information to jConsole.

There are a variety of cases where a developer may want to create a new MBean. For example:

  •  A batch file processing task may count the number of files it has processed. Instead of printing to a lengthy console, the developer could monitor progress and leave the console for important information.
  • An application may count the number of successful logins per day, failed logins, or a ratio between the two. They could then monitor the system for odd behavior such as unexpected high or low usage.
  • For various use cases, the application could track how many times that use case has happened. This is similar to the login tracking above, but for different features. This would be a simple way of tracking popularity of use cases in relation to each-other.
  • Any other information that is beneficial for tracking, charting, or alerting.

API documentation is available within the java.lang.management package.

Sample code for creating MBeans and interacting with JMX within the Java SE Downloads. Download the "Demos and Samples" project and open the sample/jmx folder.

Open-Source Example: Apache QPid

Apache QPid is a message broker for reliable inter-application communication. During operation, QPid uses JMX to expose a helpful information and statistics about the runtime. A system administrator can analyze throughput, message queue statistics, or other things that would be unavailable to other monitoring tools.

The JMX Management section of the online QPid Message Broker book explains how their system can be monitored. For developers looking to create MBeans, that chapter also links directly to their open-source code for more examples.

JMX on Embedded Devices

Java SE Embedded provides JMX within its Compact 3 profile. The functionality is the same as what you would encounter on non-embedded devices.

For additional details on Compact Profiles in the embedded space, see "Compact Profiles: Space and Security" or the jrecreate command.

Advanced Monitoring

The standard jConsole system is beneficial for monitoring, but many organizations have different needs. There are different application servers, clusters, different types of systems, embedded devices, and many other cases. The Java Platform’s open standards have provided a stable foundation for a number of advanced monitoring systems. Some monitoring systems use JMX, others use the JVM TI.

Oracle provides a commercial monitoring system named Mission Control and Flight Recorder that is able to surface an application’s statistics and take automatic action. Flight Recorder has been available in all JREs since Java 7 update 2 (April 2012).

Unlike many monitoring systems that begin recording on a trigger, flight recorder is a minimal-overhead black-box that continually records. When your trigger event occurs, it can provide details about what went on before that event happened. As a result, developers can track down bugs that cannot be replicated outside of a production environment.

 

Marcus Hirt has done a video introduction to Java Mission Control that explains many details and features, such as creating recordings, setting triggers, and controlling remote operations. The video covers the current version of Mission Control (5.3) that took place after HotSpot and JRockit were merged into a single VM.

JMX Usage

The built-in monitoring capabilities of the Java platform provide developers and system administrators with ways to understand their applications without building a new interface. Developers are able to create custom MBeans that expose application-level information to any JMX browser such as jConsole or Mission Control. Many monitoring systems use JMX as a way of understanding internal application health.

For a more complete description on the role of JMX and examples of how to configure it, react to events, or build new MBeans, please see the Java Management Extensions (JMX) Technology Tutorial or Monitoring and Management for the Java Platform.

Wednesday Jul 02, 2014

Diagnosing TLS, SSL, and HTTPS

When building inter-connected applications, developers frequently interact with TLS-enabled protocols like HTTPS. With recent emphasis on encrypted communications, I will cover the way in which the JDK evolves regarding protocols, algorithms, and changes, as well as some advanced diagnostics to better understand TLS connections like HTTPS.

Most developers will not have to do this level of diagnosis in the process of writing or running applications. In the event that you do, the following information should provide enough information to understand what's happening within secure connections.

Stability: The evolution of protocols and algorithms

For the last 15 years (since 1998), the Java platform has evolved through the Java Community Process where companies, organizations, and dedicated individuals develop and vote on specifications to determine what makes up the Java Platform. Much of the efforts are centered on compatibility, like the TCK, ensuring that different implementations are compatible with each-other and that developers can predict how their applications will run. We are not changing critical default options (like TLS protocol) within minor versions.

The following chart depicts the protocols and algorithms supported in each JDK version:


JDK 8
(March 2014 to present)
JDK 7
(July 2011 to present)
JDK 6
(2006 to end of public updates 2013)
TLS Protocols
TLSv1.2 (default)
TLSv1.1
TLSv1
SSLv3
TLSv1.2
TLSv1.1
TLSv1 (default)
SSLv3


TLSv1 (default)
SSLv3
JSSE Ciphers:
Ciphers in JDK 8
Ciphers in JDK 7
Ciphers in JDK 6
Reference:
JDK 8 JSSE JDK 7 JSSE JDK 6 JSSE
Java Cryptography Extension, Unlimited Strength (explained later)
JCE for JDK 8 JCE for JDK 7 JCE for JDK 6

Sample Java code for making an HTTPS connection

Making an HTTPS connection in Java is relatively straight-forward. I will post the code here with the intent focused on tuning and understanding the underlying capabilities.

Sample back-end code for making an SSL connection:

final URL url = new URL("https://example.com");
try(final InputStream in = url.openStream()){
  //…
}

Or the connection can be tuned through a cast:

final HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
//operate on conn
conn.connect();
try(final InputStream in = conn.getInputStream()){
  //…
}

Example: Qualys SSL Labs' "View My Client" Page

Qualys SSL Labs maintains a collection of tools that are helpful in understanding SSL/TLS connections. One in particular is a View My Client page, which will display information about the client connection. By integrating with that page, I was able to control the implementation as I used different Java tuning parameters.

To test parameter tuning, I implemented a small JavaFX application in JavaScript. It displays that page in a WebView, showing information about the underlying Java SSL/TLS client connection. You can find the code in the appendix.

JSSE Tuning Parameters

When diagnosing TLS-related issues, there are a number of helpful system properties. They are generally covered in their relevant sections of JSSE but this single collection may help anyone looking to understand the flexibility of Java’s implementation or diagnose connection details.

javax.net.debug
 Prints debugging details for connections made.
Example: -Djavax.net.debug=all or -Djavax.net.debug=ssl:handshake:verbose
https.protocols
Controls the protocol version used by Java clients. For older versions, this can update the default in case your Java 7 client wants to use TLS 1.2 as its default.
Example: -Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2
http.agent
When initiating connections, Java will apply this as its user-agent string. Modifying this will handle cases where the receiving party responds differently based on the user-agent.
Example: -Dhttp.agent="known agent"
java.net.useSystemProxies
java.net.useSystemProxiesUse proxy details from the operating system itself.
Example: -Djava.net.useSystemProxies=true
http.proxyHost
http.proxyPort
The proxy connection to use for HTTP connections.
Example: -Dhttp.proxyHost=proxy.example.com -Dhttp.proxyPort=8080
https.proxyHost
https.proxyPort
The same as above, except that configuration is separate between HTTP and HTTPS.
http.proxyUser
http.proxyPassword
https.proxyUser
https.proxyPassword
Password-based credentials for the above proxies.

Many other protocols and properties can be found within the following areas:

Example of diagnosing a problem

When making an HTTPS connection, let’s assume that the client threw the following exception due to a failed handshake with the server:

 javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure 

SSLHandshakeException is a subclass of the IOException, so you do not need to catch is explicitly. Most developers will not need an explicit catch, but it may help you more easily diagnose the cause of any IOException.

When applying the -Djavax.net.debug=all property from above, the failure associated with this SSLHandshakeException would appear immediately after algorithm negotiation in the logs.

 JDK 7 (fails on unsupported algorithm) JDK 8 (works fine)
Cipher Suites: […Long list of ciphers…]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names: {…}
Extension ec_point_formats, formats: [uncompressed]
Extension server_name, server_name: [host_name: HOST]
***
main, WRITE: TLSv1 Handshake, length = 168
main, READ: TLSv1 Alert, length = 2
main, RECV TLSv1 ALERT:  fatal, handshake_failure
main, called closeSocket()
main, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
Cipher Suites: […Long list of ciphers…]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names: {…}
Extension ec_point_formats, formats: [uncompressed]
Extension signature_algorithms, signature_algorithms: …
Extension server_name, server_name: [type=host_name (0), value=HOST]
***
main, WRITE: TLSv1.2 Handshake, length = 226
main, READ: TLSv1.2 Handshake, length = 89
*** ServerHello, TLSv1.2
RandomCookie:  GMT: -1809079139 bytes = { …}
Session ID:  {…}
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
Compression Method: 0
Extension renegotiation_info, renegotiated_connection: <empty>
Extension ec_point_formats, formats: [uncompressed, ansiX962_compressed_prime, ansiX962_compressed_char2]
***
%% Initialized:  [Session-1, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]
** TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
main, READ: TLSv1.2 Handshake, length = 2308

In the case above, the failure occurred during the handshake. The most likely cause for that is algorithm support. The JDK provides a separate package called JCE Unlimited Strength, designed to add stronger algorithm support than what’s available by default. Qualys SSL Labs provides a different server SSL test that will enumerate which algorithms a server supports.

Many TLS error messages are covered in a few pieces of documentation:

Adding stronger algorithms: JCE Unlimited Strength

In a high security environment, one way of strengthening algorithms in the JDK is through the JCE Unlimited Strength policy files. In this particular case, replacing those policy files within JDK 7 allows it to use the stronger variants of existing algorithms and connect successfully.

JCE Unlimited Strength downloads: JDK 8, JDK 7, or JDK 6.

Appendix

The following code will open Qualys SSL Labs’ View My Client page within a Java client. To test configurations, run this like:

jjs -fx viewmyclient.js
jjs -fx -Dhttps.protocols=TLSv1 viewmyclient.js

var Scene = javafx.scene.Scene;
var WebView = javafx.scene.web.WebView;
var browser = new WebView();
browser.getEngine().load("https://ssllabs.com/ssltest/viewMyClient.html");
$STAGE.scene = new Scene(browser);
$STAGE.show();

Wednesday Jun 11, 2014

Nashorn, the rhino in the room

Nashorn is a new runtime within JDK 8 that allows developers to run code written in JavaScript and call back and forth with Java. One advantage to the Nashorn scripting engine is that is allows for quick prototyping of functionality or basic shell scripts that use Java libraries. The previous JavaScript runtime, named Rhino, was introduced in JDK 6 (released 2006, end of public updates Feb 2013). Keeping tradition amongst the global developer community, "Nashorn" is the German word for rhino.

The Java platform and runtime is an intentional home to many languages beyond the Java language itself. OpenJDK’s Da Vinci Machine helps coordinate work amongst language developers and tool designers and has helped different languages by introducing the Invoke Dynamic instruction in Java 7 (2011), which resulted in two major benefits: speeding up execution of dynamic code, and providing the groundwork for Java 8’s lambda executions. Many of these improvements are discussed at the JVM Language Summit, where language and tool designers get together to discuss experiences and issues related to building these complex components.

There are a number of benefits to running JavaScript applications on JDK 8’s Nashorn technology beyond writing scripts quickly:

  1. Interoperability with Java and JavaScript libraries.
  2. Scripts do not need to be compiled.
  3. Fast execution and multi-threading of JavaScript running in Java’s JRE.
  4. The ability to remotely debug applications using an IDE like NetBeans, Eclipse, or IntelliJ (instructions on the Nashorn blog).
  5. Automatic integration with Java monitoring tools, such as performance, health, and SIEM.

In the remainder of this blog post, I will explain how to use Nashorn and the benefit from those features.

Nashorn execution environment

The Nashorn scripting engine is included in all versions of Java SE 8, both the JDK and the JRE. Unlike Java code, scripts written in nashorn are interpreted and do not need to be compiled before execution.

Developers and users can access it in two ways:

  • Users running JavaScript applications can call the binary directly:
    jre8/bin/jjs
    • This mechanism can also be used in shell scripts by specifying a shebang like #!/usr/bin/jjs
  • Developers can use the API and obtain a ScriptEngine through:
    ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
    • When using a ScriptEngine, please understand that they execute code. Avoid running untrusted scripts or passing in untrusted/unvalidated inputs. During compilation, consider isolating access to the ScriptEngine and using Type Annotations to only allow @Untainted String arguments.

One noteworthy difference between JavaScript executed in or outside of a web browser is that certain objects will not be available. For example when run outside a browser, there is no access to a document object or DOM tree. Other than that, all syntax, semantics, and capabilities are present.

Examples of Java and JavaScript

The Nashorn script engine allows developers of all experience levels the ability to write and run code that takes advantage of both languages. The specific dialect is ECMAScript 5.1 as identified by the User Guide and its standards definition through ECMA international.

In addition to the example below, Benjamin Winterberg has a very well written Java 8 Nashorn Tutorial that provides a large number of code samples in both languages.

Basic Operations

A basic Hello World application written to run on Nashorn would look like this:

#!/usr/bin/jjs
print("Hello World");

The first line is a standard script indication, so that Linux or Unix systems can run the script through Nashorn. On Windows where scripts are not as common, you would run the script like: jjs helloWorld.js.

Receiving Arguments

In order to receive program arguments your jjs invocation needs to use the -scripting flag and a double-dash to separate which arguments are for jjs and which are for the script itself:
jjs -scripting print.js -- "This will print"

#!/usr/bin/jjs
var whatYouSaid = $ARG.length==0 ? "You did not say anything" : $ARG[0]
print(whatYouSaid); 

Interoperability with Java libraries (including 3rd party dependencies)

Another goal of Nashorn was to allow for quick scriptable prototypes, allowing access into Java types and any libraries. Resources operate in the context of the script (either in-line with the script or as separate threads) so if you open network sockets and your script terminates, those sockets will be released and available for your next run.

Your code can access Java types the same as regular Java classes. The “import statements” are written somewhat differently to accommodate for language. There is a choice of two styles:

  1. For standard classes, just name the class: var ServerSocket = java.net.ServerSocket
  2. For arrays or other items, use Java.type: var ByteArray = Java.type("byte[]")
    You could technically do this for all.

The same technique will allow your script to use Java types from any library or 3rd party component and quickly prototype items.

Building a user interface

One major difference between JavaScript inside and outside of a web browser is the availability of a DOM object for rendering views. When run outside of the browser, JavaScript has full control to construct the entire user interface with pre-fabricated UI controls, charts, or components. The example below is a variation from the Nashorn and JavaFX guide to show how items work together.

Nashorn has a -fx flag to make the user interface components available. With the example script below, just specify: jjs -fx -scripting fx.js -- "My title"

#!/usr/bin/jjs -fx
var Button = javafx.scene.control.Button;
var StackPane = javafx.scene.layout.StackPane;
var Scene = javafx.scene.Scene;
var clickCounter=0;
$STAGE.title = $ARG.length>0 ? $ARG[0] : "You didn't provide a title";
var button = new Button();
button.text = "Say 'Hello World'";
button.onAction = myFunctionForButtonClicking;
var root = new StackPane();
root.children.add(button);
$STAGE.scene = new Scene(root, 300, 250);
$STAGE.show();
function myFunctionForButtonClicking(){
  var text = "Click Counter: " + clickCounter;
  button.setText(text);
  clickCounter++;
  print(text);
}

For a more advanced post on using Nashorn to build a high-performing UI, see JavaFX with Nashorn Canvas example.

Interoperable with frameworks like Node, Backbone, or Facebook React

The major benefit of any language is the interoperability gained by people and systems that can read, write, and use it for interactions. Because Nashorn is built for the ECMAScript specification, developers familiar with JavaScript frameworks can write their code and then have system administrators deploy and monitor the applications the same as any other Java application.

A number of projects are also running Node applications on Nashorn through Project Avatar and the supported modules.

In addition to the previously mentioned Nashorn tutorial, Benjamin has also written a post about Using Backbone.js with Nashorn.

To show the multi-language power of the Java Runtime, there is another interesting example that unites Facebook React and Clojure on JDK 8’s Nashorn.

Summary

Nashorn provides a simple and fast way of executing JavaScript applications and bridging between the best of each language. By making the full range of Java libraries to JavaScript applications, and the quick prototyping style of JavaScript to Java applications, developers are free to work as they see fit.

Software Architects and System Administrators can take advantage of one runtime and leverage any work that they have done to tune, monitor, and certify their systems.

Additional information is available within:

Tuesday May 20, 2014

Compact Profiles: Space and Security

Compact Profiles provide a way for developers and device manufacturers to package and update Java SE on space-constrained devices. Teams building software for those devices can trim the size of the embedded JRE by choosing a Compact Profile without items that are not used by their application. Additional details are present in Java Magazine’s March Issue, as well as the Java SE 8 launch videos “Developing Embedded Applications with Java SE 8 Compact Profiles.”

By shrinking the size of the JRE, we enable developers to use their existing Java skills in new areas and take advantage of hardware like the Raspberry Pi, the BeagleBoard, and many others. This post will cover a few aspects of Compact Profiles:

  • Comparisons between complete JRE and each profile
  • Threat modeling of a Compact Profile
  • Identifying and creating your compact JRE
  • Configuring, installing, and updating your compact JRE
  • Summary of compact profiles

Comparisons between the complete JRE and each profile

To see the various areas that Java runs in, here is a chart of sizes:

 Version Approx. Size Installed
Used for
JDK 8
Most developers use this.
431MB
Developers building Java applications and/or profiling them with Mission Control.
JRE 8
Most client systems use this.
163MB
Clients running Java applications on their Windows/Max/Linux desktop.
Server JRE 8
136MB
Server systems, for running back-end processes or application servers. This JRE can run servlet containers and compile JSPs. It is smaller than the regular JDK because it does not contain the browser plug-in, Java Mission Control, or VisualVM.
Java SE Embedded 8

Embedded devices like the Raspberry Pi, BeagleBoard, etc.
Java SE Embedded compact 3
21MB
Embedded devices requiring Kerberos or remote monitoring like JMX, but not APIs like Swing, CORBA, and Java Sound.
Java SE Embedded compact 2
15MB
Embedded devices making use of SQL connectivity or XML processing, but not any functionality from compact3.
Java SE Embedded compact 1
11MB
Embedded devices requiring a minimal version of Java SE, but not any functionality from compact2.
Java ME Embedded
Varies based on highly constrained device.
Highly constrained embedded devices.

If you are working on an embedded device and wondering which profile you should use, please see the video “Choosing a Compact Profile for your Deployment.” It is also possible to mix-and-match certain items in different profiles through extensions.

Complete details for each profile, including API listing, are located on the Compact Profiles page and within JEP 161.

Threat modeling of a Compact Profile

Compact profiles also contain a different threat model than the typical JDK Conceptual Diagram. Although the runtime is similar from the application’s point of view, the profiles are defined by items that are NOT present. For example any risk or potential misuse associated with Java2D would be mitigated in the compact3 profile, which does not include that component.

The Server JRE is a similar example: by not even having the deployment components of RIAs and browser plugins, the risk is eliminated (servers typically do not use that functionality).

It is possible to reduce and mitigate other threats as well given the control that the device manufacturer or operator has over installation/updates of the JRE. For example after creating a compact profile, one could decrease the threat model’s scope of Spoofing and likely Information Disclosure by updating the default keystore to remove everything except known-needed roots and then requiring encryption.

Identifying and creating a Compact Profile

JDK 8 provides a new tool called JDeps that can look at a collection of JAR and CLASS files and report on which compact profiles are used. When using JDeps to evaluate profiles, the report is transitive: if all your code fits in compact1 but you require something else that needs the larger compact2, then you must either use compact2 or remove the offending component.

Example usage of this is:
jdeps -profile filename.jar

filename.jar -> C:\Program Files\Java\jdk1.8.0\jre\lib\jce.jar (compact1)
filename.jar -> C:\Program Files\Java\jdk1.8.0\jre\lib\rt.jar (Full JRE)
filename.jar -> AnotherPackage.jar
   your.package (filename.jar)
      -> com.sun.deploy.config   JDK internal API (deploy.jar)
      -> java.io                 compact1
      -> java.lang               compact1
      -> java.lang.invoke        compact1
      -> java.math               compact1

Additional details can be found in Jim Connors’ blog, Compact Profiles Demonstrated.

JDeps can also be used to identify reliance of non-spec internal JDK APIs that are subject to removal, so that you can move to the appropriate public replacement.

Creating, configuring, and updating your Compact Profile

Once you have identified the appropriate profile, you can create a compact profile that will run on the target device.

  1. Download the version of Java SE Embedded for your target platform.
  2. Unzip the version that you downloaded into its usual ejdk folder.
  3. Use the included bin/jrecreate command to create the profile.
    This step requires a JAVA_HOME variable, which should point to your system’s java installation and not anything related to the target device.

For non-embedded OpenJDK, the profiles must be built separately on Linux.

Examples:

  • To create the bare minimum compact1 profile:
    jrecreate -d ~/compact1 -profile compact1
  • To create the bare minimum compact1 profile that also has the sun elliptical curve extension:
    jrecreate -d ~/compact1WithEC -profile compact1 -x sunec

Once created, simply copy the newly created folder to your device and run it like any other application.

Configuring your Compact Profile

Once the compact profile has been created, it contains several noteworthy items beyond the JRE itself. One file in particular, called bom, lists the bill of materials for this compact JRE. By having that file, you and any subsequent users will be able to see precisely what went into this profile, when it was created, and other useful piece of information.

You may then customize the information as you would any other JRE. All configuration files are present, such as such as network configuration and proxy information, timezone data, etc.

Updating your Compact Profile

Any compact profile that you create is outside the scope of typical package management systems like RPM. For a device manufacturer, there are many commercial systems which exist to handle this. It is recommended to have a mechanism for patching devices, should the need arise.

Although devices may perform minimal operations, it is reasonable to plan ahead for software updates of your applications, the compact Java profile, as well as any underlying operating system and its libraries.

Summary

Compact profiles provide a way to trim down the Java runtime in order to fit on embedded devices, either as a system component or part of an application. Not only can compact profiles shrink the size of a Java runtime down to 11MB, it also decreases the potential attack surface.

About

Science Duke
This blog contains topics related to Java SE, Java Security and Usability. The target audience is developers, sysadmins and architects that build, deploy and manage Java applications. Contributions come from the Java SE Product Management team.

Search

Categories
Archives
« February 2015
SunMonTueWedThuFriSat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
18
19
20
21
22
23
24
25
26
27
28
       
       
Today