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.



Monday, May 14, 2018

Apache Ivy 2.5.0-rc1 released - Now allows timeouts on resolvers

A few weeks back, we released the 2.5.0-rc1 version of Apache Ivy. Apache Ivy is a dependency management build tool, which usually is a used in combination with Apache Ant. The download is available on the project download page

This release is significant since the last release of Apache Ivy was way back in December 2014. So it's more than 3 years since the last official years. During these past few years, the project development stalled for a while. I use Apache Ivy in some of our projects and have been pretty happy with the tool. It's never a good sign to see one of your heavily used tools to be no longer under development or even have bug fixes. So a year or so back, I decided to contribute some bug fixes to the project. Over time, the project management committee invited me to be part of the team.

We decided that the first obvious, immediate goal would be to revive the project and do a formal release with bug fixes. This 2.5.0-rc1 is the result of that effort which started almost a year back. A lot of changes have gone into this release and also a good number of enhancements have made it into this release. This release has been a result of contributions from various different members from the community. The complete list of release notes is available here

We intentionally named this release 2.5.0-rc1 (release candidate) since it's been a while we have done an official release and also given the nature of changes. Please give this release a try and let us know how it goes. Depending on the feedback, we will either release 2.5.0 or 2.5.0-rc2. As usual, some of us from the development team keep an active watch in the ivy user mailing list. So if you have any feedback or questions, please do drop a mail to us, there.

Now coming to one of the enhancements in this release - there's been more than one. One of the issues I personally had was if the repository, backing a dependency resolver configured for Ivy, had some connectivity issues, the build would just hang. This was due to the inability to specify proper timeouts for communicating with these repositories through the resolver. As of this release, Ivy now allows you to configure timeouts for resolvers. This is done through the use of (the new) timeout-constraints element in your Ivy settings file. More details about it are here. Imagine you have a url resolver which points to some URL. The URL resolver would typically look something like:

<url name="foo">
  <ivy pattern=.../>
  <artifact pattern=.../>
  <artifact pattern=.../>
</url>



Let's now try and configure a connection timeout for this resolver. The first thing you would do is define a named timeout-constraint, like below:

<timeout-constraints>
        <timeout-constraint name="timeout-1" connectionTimeout="60000" />
</timeout-constraints>


The value for the name attribute can be anything of your choice. The value for connectionTimeout attribute is represented as a timeout in milli seconds. In the above example, we configure the "timeout-1" timeout-constraint to be of 1 minute. You can even specify a readTimeout which too is in milli seconds. More about this element can be found in the documentation.

As you might notice, we have just defined a timeout-constraint here but haven't yet instructed Ivy to use this constraint for some resolver. We do that in the next step, where we set the "timeoutConstraint" attribute on the URL resolver that we had seen before:


<url name="foo" timeoutConstraint="timeout-1">
  <ivy pattern=.../>
  <artifact pattern=.../>
  <artifact pattern=.../>
</url>


Notice that the value of "timeoutConstraint" attribute now points to "timeout-1" which we defined to have a 1 minute connection timeout. With this, when this URL resolver gets chosen by Ivy for dependency resolution, this connection timeout will be enforced and if the connections fails to be established within this timeout, then an exception gets thrown instead of the build hanging forever.

Although the example uses a URL resolver to setup the timeout constraint, this feature is available for all resolvers that are shipped out of the box by Ivy. So you can even use it with the ibiblio resolver (which communicates with Maven central) too.


Like I noted earlier, please do give this release a try and let us know how it goes.