Interesting Links podcast, episode 3

Welcome to the third ##java podcast. I’m your host, dreamreal on the IRC channel, and it’s Monday, 2017 October 9.
As usual, this podcast is built from interesting content submitted to the channel bot, using the ~submit command. If you’re on the channel, it’s very easy to use: ~submit and a URL is all you need, although it’s very helpful if you include a comment about what makes the content interesting. That saves your host – me – a lot of work trying to figure out why something was submitted.

  1. First up, we have “Reverse Engineering an Eclipse Plugin,” a long (but good) post from someone trying to figure out a security issue in the a popular Eclipse plugin – I don’t use it, but he says that apparently the Eclipse Class Decompiler Plugin as deployed on the Eclipse Marketplace has a “phone home” feature that isn’t shown in the github repository for the plugin. The author did some basic security auditing and found that the plugin apparently does something after a number of classes have been decompiled, and that the open source version of the plugin does not show this functionality. Good call by the author; he doesn’t actually reverse engineer the plugin, but actually dives into the security aspects of it, but it’s an excellent walkthrough nonetheless.
  2. Common Excuses Why Developers Don’t Test Their Software, as the title might suggest, walks through some of the reasons software tests don’t get written and run. For the most part, it’s laziness and self-deception; headings include “My code runs perfectly, why do I need to test,” “I don’t know what to test,” Barbie’s favorite excuse of “testing is hard!,” “testing increases development time.” Well worth checking out – and sending to your co-workers.
  3. Zircon is an extensible text UI library that targets multiple platforms and was designed specifically for game developers. It actually looks neat – you could imagine Dwarf Fortress or Nethack‘s user interface with something like this. I still content that while Nethack lacks the twitchy adrenaline rush of first person shooters and other such games with high frame rates, it’s still one of the best – if not THE best – computer game ever written. And yes, I know, I sound old. Now get off my lawn.
  4. Sticking to the user interface theme, Say no to Electron! Using JavaFX to write a fast, responsive desktop application, addressing the growing use of Electron. Electron is a web browser that hosts only your web application, leveraging a common approach these days that uses Java for a backend and renders the front end with HTML and Javascript. Electron isolates your app into its own browser window. While this gets you a lot of capabilities (people are used to how the web renders things, and it’s easier) it mostly reflects a failure on the part of Java to render cleanly and consistently on every platform – you can usually smell a pure Java application by the user interface features and feel it has. So people use other technologies for the user interface, which makes the apps feel more “native,” I guess, even though that’s an abuse of that term. This article actually walks through some of the alternatives to the HTML user interface in Java, and settles on JavaFX for an example. It doesn’t go very deep, but it hits the beginning aspects pretty well.
  5. The Atlantic – a hotbed of coder information, I’m sure we’ll all agree – has “The Coming Software Apocalypse,” an article going into how programmers construct code. There are people out there for whom 4GL is not dead; they want to snap things together to program. It’s not a bad idea, really, and done well it even works – like everything done well. But the problem is that it’s not easy to do well; maybe they have a solution that’ll work this time. The JavaBeans specification was actually meant to enable this sort of thing, even, but nobody uses it that way because it’s hard to do properly, and let’s face it, we as programmers tend to be conservative in our methods; we like writing code, we don’t care for connecting boxes to each other very much.
  6. Announced at JavaOne – or, well, exposed better at JavaOne, more like, was FN, aan equivalent to Amazon’s Lambda functionality. As a really poor summary of both Lambda and FN, what you would do is write a simple function that accepted input – presumably – and wrote output, and you’d connect these functions to build more complex functionality – almost like programming, you might say. It tends to have determinate latency (it’s not fast) and indeterminate scalability (it will scale out) – and with Java 9 potentially being far lighter on resources than prior JVMs thanks to things like JLink, this could be really nice to have on hand.
  7. Lastly, we have Oracle. The United States Government asked for commentary on how to modernize government IT, and Oracle responded – with a long PDF. It’s an interesting paper, for various reasons, but what’s really interesting is how… outdated and self-serving it sounds. It comes off as telling the government “you need people like us and not those silly hippies from Silicon Valley!” even though Oracle is based in Silicon Valley. Basically their paper is a repudiation of modern software practices, even though the older methods of coding are the whole reason the government is asking for how to modernize in the first place. (Techdirt‘s article on the Oracle comment points out a number of failures given us by what Oracle is propositioning.) Actually, the TechDirt article does a good job of decomposing Oracle’s commentary altogether – it’s a worthwhile read, too. Oracle comes across as whining about new-fangled, agile methodologies, saying “That’s now how we made our money back in the day! We earned it like real men, by crushing our competition because we could absorb losses they couldn’t and making sure they were iced out of big contracts. Let’s go back to that, shall we?”

Interesting Links, 25 Jan 2016

  • From ##java itself, Hot deploy to Jboss from Intellij using deployment scanner documents a problem someone had while trying to deploy from IDEA into JBoss, and discusses how to get it working. Of particular note: “The Intellij deployment options for ‘upload external changes’ (turn it on!) and ‘preserve file timestamps’ (turn it off!) have given me particular grief in the past; if you find that Intellij doesn’t seem to be picking up changes and uploading them, look at the former.”
  • J2ObjC 1.0 has been released. From the project website: “J2ObjC is an open-source command-line tool from Google that translates Java source code to Objective-C for the iOS (iPhone/iPad) platform. This tool enables Java source to be part of an iOS application’s build, as no editing of the generated files is necessary.” The UI for each platform is still written in code for that platform, but this might make porting code to iOS easier for Java coders.
  • A user on ##java posted a link to a free app he’d written for iOS devices: Trident. It’s an app that interacts with Gitlab (and Github, in early preview form), with a primary focus on discussing issues, pull requests, and files from a mobile device. This isn’t an endorsement (your author doesn’t have an iOS device) but it might be worth watching.
  • We’ve seen a lot of JavaFX questions lately – mostly they’re from a small cluster of users (therefore: a few JavaFX users, each with a lot of questions, and yes, this is anecdata.) Gluon maintains SceneBuilder, which, well, builds scenes for JavaFX, and just had a new release, version 8.1.0 of Scene Builder.
  • Feature Flags are a way to release features to specific users. Turns out there’s a hub dedicated to the method, including a reference to multiple libraries that enable limited releases in wide-area deployments. (The hub itself looks like it’s provided by the authors of Launch Darkly, but that’s okay.) It’s not a new idea, I think, but it’s written up pretty well here and it’s nice to have a hub for the capability.

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();
  }
}