Javachannel's interesting links podcast, episode 5

Welcome to the fifth ##java podcast. I’m Joseph Ottinger, dreamreal on the IRC channel, and it’s Monday, 2017 October 23.
This podcast covers news and interesting things from the ##java IRC channel on Freenode; if you see something interesting that’s related to Java, feel free to submit it to the channel bot, with ~submit and a URL to the interesting thing, or you can also write an article for the channel blog as well; I’m pretty sure that if it’s interesting enough to write about and post on the channel blog, it’s interesting enough to include in the podcast.

  1. First up, we have a DZone entry; DZone‘s actually really good at picking out content that’s interesting. However, sometimes you have to be fairly selective about what you read, because they end up like a lot of such sites and go for volume and consistency in publishing as opposed to being selective for stuff that’s truly relevant. That’s why you have things like this podcast, of course, because I clearly know what’s interesting and relevant more than they do! Anyhoo, the actual reference is for Eclipse: “Fifteen Productivity Tips for Eclipse Java IDE Users,” and they’re pretty good; none of them are what I would consider the most obvious (which is: “Use IDEA instead”). The truth is, Eclipse is very popular; anything that helps people use their tools more efficiently is a good thing. Some of the tips are fairly obvious (“use the most recent version of Eclipse”) and others are just things that experienced users might know and use already, but that’s the benefit of articles like this: they make sure that everyone has a baseline of competence. Other tips: switch editors with ctrl-tab; group related projects in working sets rather than using multiple workspaces (this is one of Eclipse’ better features, and I’m glad it’s here); download the sources of libraries; conditional breakpoints and watchpoints; leverage code coverage. There are more (nine more, making a total of fifteen, as the article title promises), and none of them are awful.
  2. Next up: Java 8 updates have an end-of-life: September 2018. Along the way, new versions of Java 9 and Java 8 have been released (9.0.1+11 and 8u151/8u152) – which is good, I suppose, although expected with a new major release – but the big news here is that Java 8 is going to see no more public updates after September 2018. Progress marches on, but I have a feeling this is going to be like the Java 7 migration – which is still ongoing. We aren’t seeing as many people saying they’re still on Java 7 – or Java 6 – as we used to, which is anecdotally a good signal that people are moving to Java 8 after all. So who knows? Maybe with such a recent mass migration to Java 8 there will be momentum to allow people to move to Java 9 – especially if they don’t have to use the module system yet – and people will stay more current.
  3. More DZone: they’re on a roll (and sneak preview: they have two more links after this one). The entry this time is “Artificial Intelligence: Machine Learning and Predictive Analytics.” It’s a fairly high-level guide, and being on artificial intelligence, it’s not just Java – and shouldn’t be. It’s a good reference, though. It’s well-done. I would love to see Java be more relevant in AI; it’s certainly relevant, and is a major player in the space, but the truth is that the starting point for AI is in Python, not Java. The same goes for natural language processing; you can find tools in Java, to be sure (Stanford NLP, for example), just like you can find AI resources in Java (WEKA, among others) but they’re typically trailing the cutting edge. Most data scientists would see a preference for Java as a bit of an affectation. (And I say that because I do prefer Java, and the data scientists I know think I’m a loon for that. They’re probably right.)
  4. This is an old link, but it showed up on my feeds recently, so I’m pretending the publication date of May 16, 2017, is badly inaccurate: Java 8u131 – and yes, 131, 151 is the current build – is transparently aware of Docker memory and CPU limits. Why is this important? It’s because older builds were, well, not aware of Docker‘s machine limitations. The idea is that Docker runs a constrained virtual machine; your actual machine might have 16Gb of RAM, but your Docker image might have 2Gb available to it, and only two of your eight cores. But if you ran an older build of Java in that Docker image, it would use the actual physical machine limits to gauge heap allocation limits and CPU core usage – which could obviously cause problems (your 2Gb image would allocate heap as if it were on a 16Gb machine, which would be incorrect). So… I guess, what with this information being fairly stale, it’s good that they fixed this. And if you happen to be running an older Java, update, please. Note that you do actually need to tell the JVM to use group memory for the heap. This is via two command line options: -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap.
  5. Another DZone article! This one is “Automata-Based Programming in Spring.” It really serves as a bare introduction for Spring Statemachine, which isn’t quite what the title led me to expect – I was thinking that I was going to get to read about how to apply cellular automata for problem solving, a la Wolfram Alpha, but instead it’s just a library that makes state transitions easy to manage. It’s a Finite State Machine, not Cellular Automata. This is on me for reading it wrongly, by the way; FSMs are automata, but not cellular in nature.
  6. Daniel Dietrich wrote an article called “Opinionated Database Access in Java” – because we all know that database access has no opinion involved at all, ever. In this case, he’s writing a library that provides yet another abstraction: this one leaves modeling to the database; complex queries are moved to the database; access should be simple and obvious. In other words, it’s one of the Java libraries that provides access to the database services, as opposed to backing up Java data structures with a database. It’s not mature yet (and he provides an example of the API using Scala, too, so it never will be mature.) The only thing is: the article doesn’t provide a reference to an actual project, so it’s all vaporware at this point. Plus, as the lively comment flow indicates, it’s another entry in a space that’s very crowded with possible implementations depending on what you want, from ORMs like Hibernate to JDBC layers like MyBatis and jOOQ.
  7. Java’s version numbers are likely to change. Java has generally followed a semantic versioning approach: you have a major version, a minor version, and a build number (sort of). However, there’s a proposal put together by Mark Reinhold (He Who Controlled Java 9’s Release) to go to a date-based release cycle, so the next release won’t be Java 10, but Java 18.3, meaning “released in the third month of 2018.” There are a few problems with this proposal, and I’m hardly alone in seeing them: one is that there’s not a “major release” associated with the build. With Java 8 versus Java 7, there’s a clear delineation of major versions; Java 8 is the one with streams. Java 9, likewise, has Jigsaw. But the next major feature – let’s say “value types” as an example – might be in Java 18.6 as opposed to Java 18.3, so we lose the ability to easily determine feature groups. Plus, Java applications will have a harder time determining the actual baseline versions they require; right now they can parse out the major version and say “Oh, I’m on Java 8 instead of Java 7” but now they’ll have to factor in the actual release year. Maybe it’s me being a curmudgeon, maybe it’s me resenting how Mark handled the Java 9 release, but I think semantic versioning is still better than the year/month release versioning. With Reinhold proposing it, it’s likely to be approved by fiat; I’m sure it’ll grow on me over time, like a fungus, but I still don’t have to like it. Now get off my lawn!
  8. Last week I highlighted Excelsior JET, which allows delivery of native binaries using Java 8 (so far). This week, we see Steve Perkins writing “Using Java 9 Modularization to Ship Zero-Dependency Native Apps“, using Java 17.10… yeah, the date-based versioning isn’t something I like at all yet. Anyway, it’s just a simple “Hello world” example, but it, like others, is a good start; I like seeing articles like this, because this is how we build a repository of knowledge concerning how to use these neat new features Java 9 provides.
  9. And now for the last of our links, this one also from DZone: “OpenLiberty.io: Java EE Microservices Done Right.” OpenLiberty is another microservice framework, like Spring Boot, DropWizard, or Vert.x, this one focusing fairly heavily on canonical Java EE APIs (as opposed to leveraging those APIs where appropriate as Spring Boot or DropWizard do.) It’s billed as a “deep dive into OpenLiberty,” but it’s really not; it’s really a cursory example with a single JAX-RS endpoint (although it does show live redeployment, which is neat.) The actual OpenLiberty sample application isn’t much to speak of; the redeployment is important, but the main thing the article shows is configuration of the OpenLiberty build, which is probably the most important thing it should want to show. It’s interesting; it’d be interesting to try out.

Eclipse Neon will require Java 8

Excellent news from the Eclipse Foundation: the next version of Eclipse, called “Neon,” will require the Java 8 runtime. The announcement in email is underwhelming, but the actual project plan is a little more explicit and informative:

In general, the 4.6 release of the Eclipse Project is developed on Java SE 8 VMs. As such, the Eclipse SDK as a whole is targeted at all modern, desktop Java VMs. Most functionality is available for Java SE 8 level development everywhere, and extended development capabilities are made available on the VMs that support them.

Frank Vogella, in Eclipse Neon (Eclipse 4.6) will require a Java 8 runtime, says this:

Several Eclipse projects like m2e and Jetty have already moved to Java 8. This moves allows us in the Eclipse platform to use the improved Java 8 API to modernize and optimize our code base and will hopefully make the Eclipse project even more interesting for potential Eclipse contributors.
After all, who wants to work in his unpaid time with an outdated Java version?

Updating a JProgressBar

This is a “simple” example of how to update a progress bar in a Swing application.

package org.javachannel;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
 * Created by odinsbane on 9/22/14.
 *
 * This is a quick example of a progress bar that updates.
 *
 * This code is distributed as is; without warranty; or guarantee. It can
 * be freely used, modified and distributed without attribution.
 */
public class ProgressBarExample {
  ExecutorService service = Executors.newSingleThreadExecutor();
  /**
   * Sets up the gui, which is just a JFrame, JButton and a JProgressBar.
   */
  private void buildGui() {
    JFrame frame = new JFrame("progress bar example");
    final JButton start = new JButton("start");
    final JProgressBar progress = new JProgressBar();
    start.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent evt) {
            start.setEnabled(false);
            //starts long running task off of EDT.
            service.submit(new Runnable() {
              public void run() {
                for (int i = 0; i < 100; i++) {
                  //the portion of work.
                  try {
                    Thread.sleep(10);
                  } catch (InterruptedException e1) {
                    //this might be a good spot to quit working.
                    e1.printStackTrace();
                  }
                  //update the progress bar on the EDT.
                  final int j = i;
                  EventQueue.invokeLater(new Runnable() {
                    public void run() {
                      progress.setValue(j);
                    }
                  });
                }
                //work finished.
                EventQueue.invokeLater(new Runnable() {
                  public void run() {
                    progress.setValue(100);
                    start.setEnabled(true);
                  }
                });
              }
            });
          }
        }
    );
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLayout(new FlowLayout());
    frame.add(start);
    frame.add(progress);
    frame.pack();
    frame.setVisible(true);
  }
  public static void main(String[] args) {
    ProgressBarExample example = new ProgressBarExample();
    //ALL gui work should be managed on the EDT.
    EventQueue.invokeLater(new Runnable() {
      public void run() {
        example.buildGui();
      }
    });
  }
}

In this example, the ‘start’ button begins a ‘long-running’ task. The task is started using an ActionListener, which starts the task on the Event Dispatch Thread (EDT). So the first thing to do is to ‘send’ the task to another thread, this is done by creating a Runnable and submitting the Runnable to the ExecutorService service.
As the task runs the progress bar needs to be updated; this should be performed on the EDT. By creating a new Runnable and submitting via EventQueue.invokeLater(), the task will be executed when Swing gets a chance, and the working thread will continue without waiting.
A small caveat is that the ‘start’ button is disabled during execution, and enabled when the task is completed. This is because when we fire the task on another thread, the EDT is not blocked and you could press the button again rather than waiting.
These concepts can still be applied to JavaFX type applications, although the environment’s obviously different and will involve some important changes – for example, you’d use Platform.runLater() instead of EventQueue.invokeLater().
Here’s an example of an equivalent program, using JavaFX instead. The layout isn’t an exact match, even with the equivalence of controls, thanks to the Scene not being packed like the JFrame is.
This example code relies on Java 8 and the use of lambdas, which shortens the code but remains equivalent:

package org.javachannel;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.FlowPane;
import javafx.stage.Stage;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class JavaFXProgressBarExample extends Application {
  ExecutorService service = Executors.newSingleThreadExecutor();
  public static void main(String[] args) {
    launch(args);
  }
  @Override
  public void start(Stage primaryStage) throws Exception {
    primaryStage.setTitle("progress bar example");
    ProgressBar progress = new ProgressBar();
    progress.setProgress(0.0);
    Button start = new Button();
    start.setText("start");
    start.setOnAction(event -> {
      service.submit(() -> {
        Platform.runLater(() -> start.setDisable(true));
        for (int i = 0; i < 100; i++) {
          //the portion of work.
          try {
            Thread.sleep(10);
          } catch (InterruptedException e1) {
            //this might be a good spot to quit working.
            e1.printStackTrace();
          }
          final double j = i / 100.0;
          Platform.runLater(() -> progress.setProgress(j));
        }
        Platform.runLater(() -> progress.setProgress(1.0));
        Platform.runLater(() -> start.setDisable(false));
      });
    });
    FlowPane root = new FlowPane();
    root.getChildren().add(start);
    root.getChildren().add(progress);
    primaryStage.setScene(new Scene(root, 250, 40));
    primaryStage.show();
  }
}

How to execute a group of tasks

Someone on the channel today asked about how to run a series of tasks, with a terminal condition of sorts. Basically, they wanted to run a number of tasks, and know when they were done.
The question was originally built around having a List of results (List<integer>, maybe?), counting the number of results until the number of results matched the number of tasks.
The channel suggested using an ExecutorService, particularly the shutdown() and awaitTermination() methods, with another suggestion being invokeAll() – which seemed particularly apt because the person asking didn’t want to have to build a new ExecutorService over and over again (which the shutdown() call would necessitate, although the cost of doing this shouldn’t be very high.)
Here’s an example with Java 8, of using the invokeAll() to execute a series of tasks; the task is made-up (it basically rolls three six-sided dice to determine a histogram of results, as a callback to Dungeons and Dragons). It has one dependency, on Apache’s commons-lang3.

package org.javachannel.examples.executors;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.LockSupport;
import java.util.stream.IntStream;
class Worker implements Callable {
    int roll() {
        LockSupport.parkNanos((long) (Math.random() * 10000000));
        return (int) (Math.random() * 6) + 1;
    }
    @Override
    public Integer call() throws Exception {
        return roll() + roll() + roll();
    }
}
public class Main {
    public static void main(String[] args) throws InterruptedException {
        List workerList = new ArrayList<>();
        IntStream.range(0, 100000).forEach(i -> workerList.add(new Worker()));
        ExecutorService service = Executors.newCachedThreadPool();
        int[] count = new int[19];
        service.invokeAll(workerList).stream().map(f -> {
            try {
                return f.get();
            } catch (Throwable e) {
                return 0;
            }
        }).forEach(m -> count[m]++);
        IntStream.rangeClosed(3, 18).forEach(r -> {
            System.out.printf("%02d %s%n", r, StringUtils.repeat("*", count[r]/100));
        });
    }
}

This code creates a list of tasks, populates it, and then submits all of them in one call (service.invokeAll(workerList)), then uses the Stream API to populate the array of results. It looks a little more complicated than it should because of the lambda to pull the int out of the Future</integer><integer>, which is what return value for call() becomes when it’s submitted to the Executor.
It’s not a perfect example; surely others can come up with better examples. Feel free to submit them!