Monday, August 27, 2018

Java 11 release candidate now available - time to try it out

The Java language development team has just released a release candidate build for Java 11, last week.

Java 11 release brings in good number of new features as noted at http://openjdk.java.net/projects/jdk/11/#Features. Personally, the TLS 1.3 and the HTTP client API are of special interest to me. Given the nature of changes in this version, it's important to try out this release candidate to make sure that these changes don't cause regressions or introduce change in semantics or features that your application or framework relies on. So this is a good time to try out this build and provide your feedback to the team.

The release can be downloaded from http://jdk.java.net/11/. Any issues, feedback and suggestions can be provided by following the process noted in the "Feedback" section on that downloads page.

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.

Friday, May 11, 2018

VMWare vijava - The curious case of "incorrect user name or password" exception

In one of the projects I have been involved in, we use yavijava (which is a fork of vijava) library to interact with vCenter which hosts our VMs. vCenter exposes various APIs through their webservice endpoints which are invoked through HTTP(s). The yavijava library has necessary hooks which allows developers to use a HTTP client library of their choice on the client side to handle invocations to the vCenter.

In our integration, we plugged in the Apache HTTP client library, so that the yavijava invocations internally end up using this HTTP library for interaction. Things mostly worked fine and we were able to invoke the vCenter APIs. I say mostly, because every once in a while we kept seeing exceptions like:

InvalidLogin : Cannot complete login due to an incorrect user name or password.

This was puzzling since we were absolutely sure that the user name and password we use to interact with the vCenter was correct. Especially since all of the previous calls were going through fine, before we started seeing these exceptions.

The exception stacktrace didn't include anything more useful and neither did any other logs. So the only option that I was left with was to go look into the vCenter (server side) event logs to see if I can find something. Luckily, I had access to a setup which had a vSphere client, which I then used to connect to the vCenter. The vSphere client allows you to view the event logs that were generated on the vCenter.

Taking a look at the logs, showed something interesting and useful. Every time, we had run into this "incorrect user name or password" exception on the client side, there was a corresponding event log on the vCenter server side at INFO level which stated "user cannot logon since user is already logged on". That event log was a good enough hint to give an idea of what might be happening.

Based on that hint, the theory I could form was, somehow for an incoming (login) request, vCenter server side notices something on the request which gives it an impression that the user is already logged in. Given my background with Java EE technologies, the immediate obvious thing that came to mind was that the request was being attached with a "Cookie" which the server side uses to associate requests against a particular session. Since I had access to the client side code which was issuing this login request, I was absolutely sure that the request did not have any explicitly set Cookie header. So that raised the question, who/where the cookie was being associated with the request. The only place that can happen, if it's not part of the request we issued, is within the HTTP client library. Reading up the documentation of Apache HTTP client library confirmed the theory that the HTTP client was automagically associating a (previously generated) Cookie against the request.

More specifically, the HTTP client library uses pooled connections. When a request is made, one of the pooled connections (if any) gets used. What was happening in this particular case  was that, a previous login would pick up connection C1 and the login would succeed. The response returned from vCenter for that login request would include a Cookie set in the response header. The Apache HTTP client library was then keeping track of this Cookie against the connection that was used. Now when a subsequent login request arrived, if the same pooled connection C1 gets used for this request, then the HTTP client library was attaching the Cookie that it kept track against this connection C1, to this new request. As a result, vCenter server side ends up seeing that the incoming login request has a Cookie associated with it, which says that there's already a logged in session for that request. Hence, that INFO message in the event logs of vCenter. Of course, the error returned isn't that informative and in fact a bit misleading since it says the username/password is incorrect.

Now that we know what's going on, the solution was pretty straightforward. Apache HTTP client library allows you to configure Cookie policy management. Since in our case, we wanted to handle setting the Cookie explicitly on the request, we decided to go with the "ignoreCookies" policy which can be configured on the HTTP client. More about this can be found in the HTTP client library documentation (see the "Manual Handling of Cookies" section). Once we did this change, we no longer saw this exception anymore.


There isn't much information about this issue anywhere that I could find. The closest I could find was this forum thread https://sourceforge.net/p/vijava/discussion/826592/thread/91550e2a/. It didn't have a conclusive solution, but it does appear that it's the same issue that the user there was running into (almost 7 years back!)

Wednesday, March 28, 2018

Ant 1.10.3 released with JUnit 5 support

We just released 1.9.11 and 1.10.3 versions of Ant today. The downloads are available on the Ant project's download page. Both these releases are mainly bug fix releases, especially the 1.9.11 version. The 1.10.3 release is an important one for a couple of reasons. The previous 1.10.2 release, unintentionally introduced a bunch of changes which caused regressions in various places in Ant tasks. These have now been reverted or fixed in this new 1.10.3 version.

In addition to these fixes, this 1.10.3 version of Ant introduces a new junitlauncher task. A while back, the JUnit team has released JUnit 5.x version. This version is a major change from previous JUnit 3.x & 4.x versions, both in terms of how tests are written and how they are executed. JUnit 5 introduces a separation between test launching and test identification and execution. What that means is, for build tools like Ant, there's now a clear API exposed by JUnit 5 which is solely meant to deal with how tests are launched. Imagine something along the lines of "launch test execution for classes within this directory". Although Ant's junit task already supported such construct, the way we used to launch those tests was very specific to Ant's own implementation and was getting more and more complex. With the introduction of this new API within the JUnit 5 library, it's much more easier and consistent now to launch these tests.

JUnit 5, further introduces the concept of test engines. Test engines are responsible for "identifying" which classes are actually tests and what semantics to apply to those tests. JUnit 5 by default comes with a "vintage" engine which identifies and runs JUnit 4.x style tests and a "jupiter" engine which identifies and runs JUnit 5.x API based tests.

The "junitlauncher" task in Ant introduces a way to let the build specify which classes to choose for test launching. The goal of this task is to just launch the test execution and let the JUnit 5 framework identify and run the tests. The current implementation shipped in Ant 1.10.3, is the basic minimal for this task. We plan to add more features as we go along and as we get feedback on it. Especially, this new task doesn't currently support executing these tasks in a separate forked JVM, but we do plan to add that in a subsequent release.

The junit task which has been shipped in Ant since long time back, will continue to exist and can be used for executing JUnit 3.x or JUnit 4.x tests. However, for JUnit 5 support, the junitlauncher task is what will be supported in Ant.

More details about this new task can be found in the junitlauncher's task manual. Please give it a try and report any bugs or feedback to our user mailing list.

Tuesday, February 20, 2018

WildFly 12.0.0.Beta1 tagged and available

WildFly 12.0.0.Beta1 has been tagged and has been (I think) officially released. The announcement happened a few days back in the dev mailing list and unlike the previous releases, this time the release binaries seem to be only available in Maven repository and can be obtained from here - WildFly 12.0.0.Beta1 distribution (the .tar.gz and .zip are the relevant ones). The list of changes for this release can be found in the JIRA release notes.

As you'll notice in the release notes, there's some initial support for EE 8 specs, including Servlet 4.0 among others. Plus there's also numerous bug fixes in this release from the previous 11.0.0.Final version which was released some months back. As usual, please give this version a try and if there are any issues or feedback that you would like to report, please start a discussion in the WildFly user forum

If you haven't been following the WildFly dev mailing list, there's also a discussion which outlines the release plans for WildFly going forward. You can find that discussion here

Finally, there's been major changes to Java EE processes and committee and even the name, over the past year. If you haven't been following those changes, then you can read through Mark Little's recent blogs including the most recent ones which talk about the new brand name for Java EE  and setting up of the working group.

Wednesday, February 07, 2018

Apache Ant new versions (1.9.10 and 1.10.2) released

This past year has been pretty hectic, so I haven't had a chance to update this blog more often.

In my limited spare time last year, I started contributing to Apache Ant project. Although Ant probably isn't as widely used as some years back, it still is used in many projects, as the build tool. Some of the products I'm involved in, does use Ant and that motivated me to contribute to some bug fixes in Ant. After a period of time, last year, I was invited to be a committer and a few weeks back, to be part of the Ant project management committee (PMC), which I consider a honour.

Just today, we released a couple of new versions of Ant - 1.9.10 and 1.10.2. These are essentially bug fix releases but do contain some new enhancements. The complete release notes, for each of these releases, can be found  here and here.

The downloads are available from the project's download page and the full announcement, in the mailing list, can be read here

If you have any issues/suggestions/feedback about the project, feel free to report it in the user mailing list which is listed on this page.