Andy Grove's Blog

Sunday, 20 July 2008

Spring DAO

Spring DAO support has been improved in the latest FireStorm 4.0 beta, which is now available for download. Each Spring DAO method is now annotated as @Transactional and the spring configuration file specifies a DataSourceTransactionManager. By default the DAO finder methods now return typed lists e.g. List<Customer> rather than arrays.

There are some improvements to Spring MVC support as well. FireStorm now generates a single controller per table which extends MultiActionController.

Labels:


Sunday, 29 June 2008

The generated script approach to running shell commands from Java

Running external process from Java is simple enough using Runtime.exec() but there are some well documented limitations which are covered in detail in an old but still relevant JavaWorld article entitled When Runtime.exec() won't.

I recently needed to launch a MySQL backup from Java but needed to redirect stdout and stderr to file. Unfortunately, Runtime.exec() can only be used to run an executable file and pass parameters in. It does not support more complex operations such as piping the output of one process into another process or even redirecting stdout or stderr. In other words, Runtime.exec() can’t be used as a linux command line replacement.

For example, this works correctly:
Runtime.getRuntime().exec( “/usr/bin/mysqldump mydb --result-file=mydb.dump” );


But this will not work:

Runtime.getRuntime().exec( “/usr/bin/mysqldump mydb --result-file=mydb.dump >stdout.txt 2>stderr.txt” );


This last code fragment runs without error but the stdout.txt and stderr.txt files are not created.

The standard solution to this problem is to write Java code to launch two threads, one to read the output stream from the process and one to read the error stream and then write the output from those streams to disk from within Java, but this seems like a heavyweight solution in this instance. There is also a risk of the subprocess hanging if the Java code does not read the output from the process quickly enough, as outlined in the javadocs:

“Because some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the subprocess may cause the subprocess to block, and even deadlock.”

A simpler solution to allow arbitrary linux command lines to be run from Java is to write the command to a shell script and then execute the shell script. For example:


private static void runCommand(String cmd) throws IOException, InterruptedException {

// generate a script file containg the command to run
final File scriptFile = new File("/tmp/runcommand.sh");
PrintWriter w =
new PrintWriter(scriptFile);
w.println(
"#!/bin/sh" );
w.println( cmd );
w.close();

// make the script executable
Process p = Runtime.getRuntime().exec(
"chmod +x " + scriptFile.getAbsolutePath() );
p.waitFor();

// execute the script
p = Runtime.getRuntime().exec( scriptFile.getAbsolutePath() );
p.waitFor();
}


Using this approach, I can now simply run:

runCommand(“/usr/bin/mysqldump mydb --result-file=mydb.dump >stdout.txt 2>stderr.txt”);


This approach works fine for my requirement, without the overhead of creating additional Java threads. However, this approach is not suitable if the Java application needs to read the output of the process before the process has completed, in which case the standard approach of launching threads to read the output streams should be used.

The generated script approach is very convenient for enabling general purpose linux command line usage from Java.

Labels:


Wednesday, 18 June 2008

Skype 4.0 promises high definition full screen video

I'm looking forward to getting my hands on Skype 4.0. I wonder how well full screen video will really work on standard broadband connections. Sounds a little too good to be true. You can do full screen video with the current Skype version but the picture quality is pretty poor.

Labels:


Thursday, 12 June 2008

Database sharding with Python

I just read an interesting post over on highscalability.com. There is an early stage open source project called Pyshards that provides database sharding for Python developers. It's interesting to see sharding toolkits emerge for languages other than Java.

I've been working extensively with database sharding for around 9 months now and it's an exciting area of technology that offers a very cost-effective way to implement near-linear database scalability using commodity hardware.

Wednesday, 4 June 2008

Is Maven the right choice for your project?

Over the past 6 months or so I have been working with some projects that have a Maven2 build system and other projects that use plain Ant build systems. I love the concepts behind Maven and see tremendous value in standardizing the build process across projects as well as having a better way of managing dependencies on third party jars without storing them in each project's source repository.

However, there are some pitfalls to be aware of before adopting Maven which may or may not be issues depending on your requirements.

First of all, adopting Maven will typically require a Maven server (repository) to be set up and maintained. For some smaller development departments this creates an extra IT support burden that can be avoided with an Ant build system.

Another potential issue is that third party projects might not have good support for Maven. For instance, another Apache project, Axis2, recently released version 1.4 but there is an open support ticket AXIS2-3069 regarding the Maven2 java2wsdl plugin which does not seem to be in a working state yet. The ticket has not been updated since 2007. Sure, the problem can be worked around by calling Ant from within the Maven2 project, but that's adding another layer of complexity compared to a standard Ant project.

Another issue that I have hit is that Maven2 has poor error reporting when it is unable to resolve a dependency. I eventually tracked my issue down to a java keystore / server certificate error but Maven didn't provide any hints that this was the problem, even with debug flags set.

Overall, I'm still a fan of Maven2 and I think the combination of Maven and Ant is extremely powerful but in my recent experience it does add extra cost to the development process.

Labels: