Sunday, 23 February 2014

JTail - Java Tail command with NIO 2

The old way


As far as I can tell every implementation of the UNIX tail command in java uses a variation of the following2 3:
open file
while (true)
{
    try
    {
        read file
        write file to output
        thread.sleep(1 second)
    } catch (InterruptedException) {}
}
close file

Now if you look at the source code of tail5 in UNIX, it checks for the existence of inotify1. Java 7 has something similar (but with less features) called the WatchService as part of the NIO.2.

The new way with NIO 2

The part containing the code interfacing with the WatchService of NIO.2 can be found in the FileSystemWatcher java class.

You can find the source code to FileSystemWatcher.java on my github account.

Here's the UML schema for the FileSystemWatcher class. (slightly simplified)

Examples

$ java -classpath jtail.jar;jopt-simple-4.5.jar com.tools.jtail.Jtail --help

$ java -classpath jtail.jar;jopt-simple-4.5.jar com.tools.jtail.Jtail -version

$ java -classpath jtail.jar;jopt-simple-4.5.jar com.tools.jtail.Jtail ipsum.txt

Notes

  • The WatchService, unlike inotify, can only watch directories. Otherwise you receive a java.nio.file.NotDirectoryException.
  • One of the things I like, is the fact that the watchservice, if the filesystem does not support filemonitoring, gracefully falls back to the polling.4
  • I could have used a Path.newByteChannel method of NIO.26, instead of relying on the old RandomAccessFile class. I'll rewrite it someday.
  • I have not done extensive testing, if you find a file and command line that does not work, please do notify me.
  • Where Linux seems to provide filesystem events regularly, Windows seems to be lazy in that regard. I've tried it with a JBoss logfile in Windows, but I only got sporadic events at best. Investigation ongoing.

References

[1] Wikipedia - inotify
http://en.wikipedia.org/wiki/Inotify
[2] Java tail implementation
https://gist.github.com/amelandri/1376896
[3] Java tail
http://melandri.net/2009/05/29/java-tail/
[4] WatchService (Java Platform SE 7)
http://docs.oracle.com/javase/7/docs/api/java/nio/file/WatchService.html
[5] GNU core utilities
http://www.gnu.org/software/coreutils/
[6] StackOverflow - Java reading strings from a random access file with buffered input
http://stackoverflow.com/questions/4305094/java-reading-strings-from-a-random-access-file-with-buffered-input
Manpage : tail
http://unixhelp.ed.ac.uk/CGI/man-cgi?tail
Oracle Tutorial - Reading and Writing Files by Using Channel I/O
http://docs.oracle.com/javase/tutorial/essential/io/file.html#channelio
Oracle Tutorial - Random access files
http://docs.oracle.com/javase/tutorial/essential/io/rafs.html
Oracle Tutorial - Watching a Directory for Changes
http://docs.oracle.com/javase/tutorial/essential/io/notification.html
JOpt Simple - a Java command line parsing library
http://pholser.github.io/jopt-simple/index.html

Sunday, 16 February 2014

package.html vs. package-info.java

Found a good reference1 on why you should use a package-info.java class.

Notes:
  • can contain (package) annotations
  • package-info is not a legal identifier for a class2. So there's no chance of mistakes from the compiler.
  • “It is recommended that package-info.java, if it is present, take the place of package.html for javadoc and other similar documentation generation systems.”2
  • you're not messing up your source files with .html files, which was in fact the case with the old package.html.

References

[1] Javadoc: package.html or package-info.java
http://stackoverflow.com/questions/3644726/javadoc-package-html-or-package-info-java
[2] The Java™ Language Specification - Java SE 7
http://docs.oracle.com/javase/specs/

Saturday, 8 February 2014

Feature Creep

From Wikipedia[1]:
“Feature creep, creeping featurism or featuritis is the ongoing expansion or addition of new features in a product, such as in computer software.”
It carries with it negative connotations of over-complicating the design, adding features that are unrelated to or go beyond the original function of the program, adding features that are of no additional value to the users because software developers thought it would be a 'good idea'™.

In a worst case scenario Feature creep could result in the original program becoming a 'platform' or 'framework'. Though, I doubt it not that many good frameworks originally started out this way.

An example


The example I wish to focus on today is the widget displayed in the upper-left corner of the article. We've recently installed a 'smart' electricity measuring device, which can be bolted onto the original Electricity meter.

Now, I have certain assumptions about the software that was included, namely that it would show me my consumption of electricity over time, possibly using nice colourful graphics.

And it does do that, make no mistake, and I am very happy with it.

But why, oh why, did they add an RSS Feed to nu.nl (a Dutch newssite) to the widget? Did the developers think it's a good idea? Did they have the implementation of the RSS feed lying around, and thought, 'hey, why not cram that in there as well?'. Did they think 'Oh, when someone wishes to check the news, they'll naturally check our energy widget?' Does it have any added value for me as a customer at all?

Why? Can someone please tell me?

References

[1] Wikipedia - Feature creep
http://en.wikipedia.org/wiki/Feature_creep