Saturday, September 28, 2013

Guava 15 - New features

A new version of the Guava library was released earlier this month and contains several new features and improvements.

Here is an overview of some of the significant API additions in this release:

1. Escapers
Escapers allow you to "escape" special characters in a string in order to make the string conform to a particular format. For example, in XML, the < character must be converted into &lt; for inclusion in XML elements. Guava provides the following Escapers:

You can also build your own Escaper. Here is an example of various Escapers in action:
// escaping HTML
HtmlEscapers.htmlEscaper().escape("echo foo > file &");
// [result] echo foo &gt; file &amp;

// escaping XML attributes and content
XmlEscapers.xmlAttributeEscaper().escape("foo \"bar\"");
// [result] foo &quot;bar&quot;

XmlEscapers.xmlContentEscaper().escape("foo \"bar\"");
// [result] foo "bar"

// Custom Escaper
// escape single quote with another single quote
// and escape ampersand with backslash
Escaper myEscaper = Escapers.builder()
                            .addEscape('\'', "''")
                            .addEscape('&', "\&")
                            .build();

2. StandardSystemProperty
StandardSystemProperty is an enum of Java system properties such as java.version, java.home etc. The great thing about this is that you no longer need to remember what the system properties are called because you simply use the enum! Here is an example:

StandardSystemProperty.JAVA_VERSION.value();
// [result] 1.7.0_25

StandardSystemProperty.JAVA_VERSION.key();
// [result] java.version

3. EvictingQueue
The EvictingQueue is a non-blocking queue which removes elements from the head of the queue when it is full and you attempt to insert a new element. Example:

// create an EvictingQueue with a size of 3
EvictingQueue<String> q = EvictingQueue.create(3);
q.add("one");
q.add("two");
q.add("three");
q.add("four");
// the head of the queue is evicted after adding the fourth element
// queue contains: [two, three, four]

4. fileTreeTraverser
As its name suggests, Files.fileTreeTraverser allows you to traverse a file tree.

FluentIterable<File> iterable = Files.fileTreeTraverser().breadthFirstTraversal(new File("/var/tmp"));
for (File f : iterable) {
    System.out.println(f.getAbsolutePath());
}

(Note: Java 7's Files.walkFileTree also traverses a file tree and I showed you to use it in one of my earlier posts: Java 7: Deleting a Directory by Walking the File Tree. I'd recommend this approach if you are using Java 7.)

The full release notes of Guava 15 can be found here.

Sunday, August 25, 2013

Executing a Shell Command with a Timeout

Sometimes you may want to kill a command if it has been running for more than a specific time limit. For example, a shell script connecting to a network resource may hang for a long period of time if the resource is unavailable and it would be desirable to kill it and send out an alert.

This post describes different ways of running commands with time limits.

1) GNU coreutils timeout command
The easiest way to run a command with a time limit is by using the timeout command from GNU coreutils. For example, to run a command with a timeout of 2 minutes:

$ timeout 2m /path/to/command with args
$ echo $?
124
If the command has not completed within the specified time limit, the timeout utility will kill it (by sending it a TERM signal) and then exit with status 124.

2) The expect command
Another way to run a command with a timeout is by using expect as shown below:

$ expect -c "
    set echo '-noecho';
    set timeout 10;
    spawn -noecho /path/to/command with args;
    expect timeout { exit 124 } eof { exit 0 }"
$ echo $?
124
In the example above, the timeout is set to 10 seconds and expect will exit with a status of 124 when the command exceeds this time limit. Otherwise, it will exit with a status of 0. Unfortunately, you lose the exit code of the command you are running.

3) Using a custom timeout script
If you cannot use the two approaches above, you can write your own timeout script. Mine is shown below. It first starts a "watchdog" process which keeps checking to see if the command is running by executing kill -0 periodically. If it is still running after the time limit has been exceeded, the watchdog kills it.

#!/bin/bash
while getopts "t:" opt; do
  case "$opt" in
      t) timeout=$OPTARG ;;
  esac
done
shift $((OPTIND-1))

start_watchdog(){
  timeout="$1"
  (( i = timeout ))
  while (( i > 0 ))
  do
    kill -0 $$ || exit 0
    sleep 1
    (( i -= 1 ))
  done

  echo "killing process after timeout of $timeout seconds"
  kill $$
}

start_watchdog "$timeout" 2>/dev/null &
exec "$@"
Example:
$ timeout.sh -t 2 sleep 5
killing process after timeout of 2 seconds
Terminated

Saturday, July 20, 2013

stackoverflow - 60k rep

Last week I crossed the 50k milestone and have now reached a reputation of 60k on stackoverflow!

The following table shows some stats about my journey so far:

0-10k 10-20k 20-30k 30-40k 40-50k 50-60k Total
Date achieved 01/2011 05/2011 01/2012 09/2012 02/2013 07/2013
Questions answered 546 376 253 139 192 145 1651
Questions asked 46 1 6 0 1 0 54
Tags covered 609 202 83 10 42 14 960
Badges
(gold, silver, bronze)
35
(2, 10, 23)
14
(0, 4, 10)
33
(2, 8, 23)
59
(3, 20, 36)
49
(0, 19, 30)
65
(2, 26, 37)
255
(9, 87, 159)
I have really enjoyed being a member of stackoverflow. For me, it has not simply been a quest for reputation, but more about learning new technologies and picking up advice from other people on the site. I like to take on challenging questions, rather than the easy ones, because it pushes me to do research into areas I have never looked at before, and I learn so much during the process.

70k, here I come!

Saturday, June 29, 2013

Java 7 Swing: Creating Translucent and Shaped Windows

Java 7 Swing supports windows with transparency and non-rectangular shapes.

The following screenshot shows a circular window created with 75% opacity.

You can create a translucent window by altering its opacity using the setOpacity method on a JFrame. Note that you can only create translucent windows if the underlying operating system supports them. Also, ensure that the window is undecorated by calling setUndecorated(true).

To change the shape of the window, call the setShape method inside the componentResized method, so that if the window is resized, the shape is recalculated as well.

Sample code to create a translucent, circular window is shown below:

import java.awt.Color;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.GridBagLayout;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.geom.Ellipse2D;

import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

public class TranslucentCircularFrame extends JFrame {

  /**
   * Creates a frame containing a text area and a button. The frame has a
   * circular shape and a 75% opacity.
   */
  public TranslucentCircularFrame() {
    super("Translucent Circular Frame");
    setLayout(new GridBagLayout());
    final JTextArea textArea = new JTextArea(3, 50);
    textArea.setBackground(Color.GREEN);
    add(textArea);
    setUndecorated(true);

    // set the window's shape in the componentResized method, so
    // that if the window is resized, the shape will be recalculated
    addComponentListener(new ComponentAdapter() {
      @Override
      public void componentResized(ComponentEvent e) {
        setShape(new Ellipse2D.Double(0, 0, getWidth(), getHeight()));
      }
    });

    // make the window translucent
    setOpacity(0.75f);

    setLocationRelativeTo(null);
    setSize(250, 250);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setVisible(true);
  }

  public static void main(String[] args) {

    // Create the GUI on the event-dispatching thread
    SwingUtilities.invokeLater(new Runnable() {
      @Override
      public void run() {
        GraphicsEnvironment ge = GraphicsEnvironment
            .getLocalGraphicsEnvironment();

        // check if the OS supports translucency
        if (ge.getDefaultScreenDevice().isWindowTranslucencySupported(
            GraphicsDevice.WindowTranslucency.TRANSLUCENT)) {
          new TranslucentCircularFrame();
        }
      }
    });
  }
}

Sunday, May 26, 2013

Guava Joiner: Converting an Iterable into a String

Guava's Joiner makes it really easy to convert an Iterable into a String, so you no longer have to iterate over it and build the String manually. Here is an example:
// joining a list
final List<String> fruits = Lists.newArrayList("apple", "banana", null, "cherry");
System.out.println(Joiner.on(", ").skipNulls().join(fruits));

// joining a map
final Map<String, Integer> people = ImmutableMap.of("Alice", 21, "Bob", 19);
System.out.println(Joiner.on("\n").withKeyValueSeparator(": ").join(people));
prints:
apple, banana, cherry
Alice: 21
Bob: 19