Showing posts with label utility. Show all posts
Showing posts with label utility. Show all posts

Tuesday, March 8, 2011

Create and Initialize a Utility Class with Spring

Let's say we want to encapsulate a collection of read-only configuration parameters into a class (so, we want immutability). There are numerous parameters in the configuration, perhaps dozens - so we don't want to provide some ugly multi-parameter constructor or factory method. In fact, we want to provide clients with the convenience of static getters, so we know this will be a utility class (i.e. no instances needed or desired). While we could initialize a list of static fields with their configuration values to facilitate this, we would rather factor these value out into some external file.

We'd like to use Spring - but Spring works on instances, and we don't have a constructor for Spring to use, nor do we want or need an instance anyway, nor do we want to provide setters on this class (since we would like to stay immutable). So, how to use Spring?

One solution is to use a variation on the Builder pattern - the recipe goes like this:

  1. create the utilty class with static fields for each configuration parameter
  2. give it a private constructor
  3. provide static getters for each parameter
  4. add a static inner class with the same fields, although these will be instance fields (not static)
  5. this inner class also has a private constructor
  6. provide setters for each field - although here we deviate from the standard Builder pattern: these are true setters, returning void
  7. the utility class now provides a static "init" method that accepts an instance of the inner class as an argument - and this behaves just like the regular Builder pattern, where the top-level class initializes its fields from the correspond fields in the argument object
  8. the inner class provides its own "init" method which calls the utility class init method with itself

Spring wires all of this together like this:


<bean id="builder-variant" class="com.mybiz.MyUtilityClass$MyInnerClass"
init-method="initUtilityClass">
<property name="foo" value="bar"/>
<property name="bar" value="foo"/>
</bean>

Using this, Spring will create an instance of the inner class, setting its properties as given, and then call the inner class' initializer. As mentioned in the above recipe, that initializer will then call the utility class' initializer with itself as the argument. That facilitates initializing the utility class properties, and we're done.

Thursday, January 27, 2011

Schedule a Periodic Task with a Watchdog

This demonstrates a simple mechanism to start up a thread that executes some task periodically, with a watchdog to ensure it keeps running. It is assumed that the periodic task involves some kind of I/O or remote communication that can result in an exception. The watchdog is needed because the java.util.concurrent class used for the task will not proceed with subsequent executions after one of its executions encounters an exception.

Monday, August 23, 2010

Monitor Changes to a File

There are undoubtedly many options out there for file-system change monitors - i.e. a component that will notify your Java object when a given file or directory has changed, among many others I'm sure: jnotify and jpathwatch, the latter of which is based on upcoming Java 7 NIO enhancements.

I gave jpathwatch a try recently, at a time when I was under a tight deadline and didn't want to reinvent a wheel. This presents a perfectly fine API that worked out quite well and quite quickly for me in my Windows environment, but alas when I deployed to Linux, I bumped into an unsatisfied link error. The problem was around libc.so.6 and GLIBC_2.4, and I gave it a reasonable first effort to try quickly finding the resolution - assuming I'd deployed incorrectly, or my Linux box was out of date, etc. It was neither of these - OK, in fairness, it could be an out-of-date Linux box, but my experiment was to just try it out on our customers' target system - and the same problem occurred. So out-of-date becomes a moot point.

As I mentioned, I was under a tight deadline, so I began some quick prototyping to see if I could reinvent something but without relying on native libraries (as jpathwatch did). That would give me the added advantage of a smaller runtime footprint, which was another customer requirement. Since we are really talking about an Observer pattern, here's how I started:

public interface FileChangeListener {

void fileModified(String file);

void fileDeleted(String file);

void fileCreated(String file);
}

That specifies the observer. Here's a simple monitor interface:

public interface AbstractFileChangeMonitor {

void watch(FileChangeListener listener, final String filename);
}

This one is a bit limited, since it supports just one listener (observer) for one file. But my goal is not (yet) to provide a full-featured framework - I just need to knock out the problem at hand without any gold-plating. I'm a firm believer in doing the least I have to for a given problem - first make it work, then make it fast, then extend it, ... etc., but only if subsequent steps are called for. In either event, here's an implementation of the monitor - this one polls the file in question to detect changes, running in a thread so the client process isn't blocked:

public class PollingFileChangeMonitor implements AbstractFileChangeMonitor
{
private final Logger logger = LoggerFactory.getLogger(getClass().getSimpleName());
private FileChangeListener listener;
private boolean done;
private Thread watch;
private int pollingInterval;

public PollingFileChangeMonitor(int interval) {
pollingInterval = interval;
}

public void watch(FileChangeListener theListener, final String filename)
{
if (watch == null) {
listener = theListener;
watch = new Thread() {
public void run() {
try {
init(filename);
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
};
watch.start();
}
}

private void init(String filename) throws Exception
{
boolean exists = false;
long modTime = -1;
File file = new File(filename);
if (file.exists())
{
exists = true;
modTime = file.lastModified();
logger.info("====> File '" + filename + "' exists; change monitor is running...");
} else
{
logger.info("====> File '" + filename + "' does NOT exist; change monitor is running...");
}

while (!done) {
try {
watch.sleep(pollingInterval);
} catch (InterruptedException e) {
// ignore for now
}

if (!exists && file.exists()) {
exists = true;
logger.info("====> File '" + filename + "' has been created; notify listener...");
listener.fileCreated(filename);
} else if (exists && !file.exists()) {
exists = false;
logger.info("====> File '" + filename + "' has been deleted; notify listener...");
listener.fileDeleted(filename);
} else if (exists && file.exists()) {
long timestamp = file.lastModified();
if (timestamp > modTime) {
modTime = timestamp;
logger.info("====> File '" + filename + "' has been modified; notify listener...");
listener.fileModified(filename);
}
}
}
}
}

What the listener does when notified is not really important in the context of this post; it can be anything. While I've to a certain extent "reinvented" something here, I've gotten away from reliance on native code and the potential deployment headaches around that, I've reduced my runtime footprint, and for that matter I've solved the problem with about the same amount of code I needed for the boiler-plate suggested by jpathwatch.