Monday, July 16, 2018

Apache Ant 1.9.13 and 1.10.5 released - Supports Java 11 single-file source programs

We just released 1.9.13 and 1.10.5 versions of Apache Ant. As usual, you can download it from the Ant project download page.

Both these versions are mainly bug fix releases. The 1.10.5 version however has a new enhancement to the "java" task. As I blogged previously - Java 11 introduces a new feature where you can execute single-file Java programs without having to explicitly compile them first. Ant 1.10.5 release now supports this feature through a new "sourcefile" attribute in the "java" task. More about it can be found the manual of that task.

A simple usage example of this new feature of the "java" task is as follows:

<project default="launch-java" name="Java 11 - launch single-file source program">

 <target name="launch-java"
            description="Simple example of single-file source program execution,
             introduced in Java 11">

        <!-- Make sure Java 11 version is being used -->
        <condition property="java11">
            <javaversion atleast="11"/>
        </condition>    
        <fail unless="java11">Java 11 runtime version is necessary to run this example</fail>        

        <mkdir dir="${basedir}/javasource"/>
        <!-- Write out simple Java code into a file -->
        <echo file="${basedir}/javasource/HelloWorld.java">
            import java.nio.file.Files;
            import java.nio.file.Paths;
            import java.io.BufferedWriter;
            public class HelloWorld {
                public static void main(String[] args) throws Exception {
                    System.out.println("Hello world, " + args[0] + "!");
                }
            }
        </echo>
        <!-- launch the Java source file, using the "sourcefile" attribute -->
        <java sourcefile="${basedir}/javasource/HelloWorld.java" fork="true" failonerror="true" logerror="true">
            <arg value="Java 11"/>
        </java>
    </target>
</project>

As you'll notice, the build file uses the "java" task to set the "sourcefile" attribute to point to a Java source file. The rest of the usage details of the "java" task, including passing arguments to the program, continue to remain the same as before.

When you run "ant" on this build file, you should see the following output:

[java] Hello world, Java 11!

Of course, you will need to use a Java 11 binary to run this against. You can get the early accessible Java 11 binary from here.


Friday, July 13, 2018

Java 11 upcoming features - Launch Single-File source programs

Java 11 is nearing completion and it's entered the rampdown phase. It almost feels like a few weeks back that Java 9 was released and here we are, within a few months of Java 11 being released. Given the new release process and timelines for Java, this will become a common thing. Whether that's a good thing or not, we'll keep it aside.

The changes coming in Java 11 are listed here. These are some nice enhancements and features coming in this release. Two of them that I'm really excited about are:

    - HTTP client (standard) http://openjdk.java.net/jeps/321 which will bring in HTTP client APIs as part of the Java language.
    - Launch Single-File Source-Code Programs http://openjdk.java.net/jeps/330

In this article, I will go through the "Launch Single-File Source-Code Programs" feature. What this enhancement proposes to accomplish is to make it easy for running Java code which consists of a single file with the "main()" method in it.

Imagine you have a simple HelloWorld program as follows in a file HelloWorld.java under org/myapp directory:


package org.myapp;


public class HelloWorld {
    
    public static void main(String[] args) throws Exception {
        System.out.println("Hello World!");
    }
}


Right now, without the proposed feature, in order to run this program, the user has to first compile it using javac command:


javac org/myapp/HelloWorld.java

Once that succesfully compiles, you then run the java command to execute the program:


java org.myapp.HelloWorld


So it's a 2 step process. It looks trivial even for beginners, but it can still be made simpler not just for beginners but even developers who regularly work with Java.

Once Java 11 gets released (or if you want to try it now, you can get the early access builds from http://jdk.java.net/11/) we can run the above program as follows (as a single command):


java org/myapp/HelloWorld.java


Notice the difference here:
     1. one, we no longer use the javac command to explicitly compile the source
     2. The java command is now passed the path to the source file (org/myapp/HelloWorld.java) instead previously where we used to pass it the fully-qualified classname.

This difference is minor but important, since the java command now "understands" that it now has to internally do whatever it's necessary (like compiling the source) when it's passed a file path whose file name ends with the .java extension. Of course, such a file is expected to contain regular/valid Java code with a top level class exposing the "public static void main(String[])" method.

Furthermore, just like your regular Java programs you can continue to pass application specific arguments to the program as before. For example, for a calculator program which looks below, in a org/myapp/Calculator.java file:


package org.myapp;


public class Calculator {
 
 public static void main(final String[] args) throws Exception {
  final int sum = Integer.parseInt(args[0]) +  Integer.parseInt(args[1]);
  System.out.println(args[0] + " + " + args[1] + " = " + sum);
 }
}

you can pass the program arguments as follows:


java org/myapp/Calculator.java 2 4

where 2 and 4 are passed as the program arguments and you would see the output as follows:

2 + 4 = 6
This feature also adds support for "shebang" files, files which are expected to hava valid Java code plus a "shebang". Personally, I'm not too fond of this specific aspect of the feature. However, the good thing is, the JDK team took feedback from the community and made this additional aspect of a feature, non-intrusive (for tools/commands which already deal with Java source files) and something that some of us can ignore if we don't want to use it. The details of when/how to use the "shebang" files for this feature are explained in the linked JEP-330.

So far, although Java 11 hasn't been released, I have been using the early access builds and extensively using this feature for some of my regular work which sometimes involves coming up with short programs that help reproduce an issue. I usually don't use IDEs for things like these, so it's been a welcome enhancement to be able to issue a single command against such files and have them executed.