May 29, 2009

Switching to Sun JDK/JRE/JVM in Ubuntu

Turns out, I've been using OpenJDK all this time. Apparently, this is not so bad, but when I tried to play with Ant from command line, I got BUILD FAILED kind of errors.

The symptoms are:

$ ant -version
Unable to locate tools.jar. Expected to find it in /usr/lib/jvm/java-6-openjdk/lib/tools.jar
Apache Ant version 1.7.1 compiled on November 10 2008


$ java -version
java version "1.6.0_0"
OpenJDK Runtime Environment (IcedTea6 1.4.1) (6b14-1.4.1-0ubuntu10)
OpenJDK Server VM (build 14.0-b08, mixed mode)

The easiest way to solve this for me was to force Sun's “original” JDK.

Apparently, once you've installed sun-java6-bin, -jre and -jdk packages, you have to
$ sudo update-java-alternatives -s java-6-sun

and then edit /etc/jvm so that it looks something like this, with /usr/lib/jvm/java-6-sun on top:


May 24, 2009

Configure Tomcat To Serve Static Files

Tomcat is often considered to be too slow to serve static content. That is why on production servers, static files are often served by a separate web server like Apache Server or lighthttpd.

In development, however, you sometimes might need a quick-and-dirty solution for serving large amounts of static files stored somewhere on hard disk. One example of such usage would be an service that stores and organizes image files.

Suppose you have a /var/project/images directory which stores a number of images for your project. If you want this directory to be exposed through http protocol, all you have to do is to add a <Context> parameter to the <Host> section of Tomcat's server.xml:

<Server port="8025" shutdown="SHUTDOWN">
<Service name="Catalina">
<Engine defaultHost="localhost" name="Catalina">
<Host appBase="webapps"
autoDeploy="false" name="localhost" unpackWARs="true"
xmlNamespaceAware="false" xmlValidation="false">
path="/project/images" />

Note that docBase parameter is set to the path on hard drive and path parameter is set to the context path for your files. Now, if you have a /var/project/images/sample.png file, it can be seen at http://localhost:8084/project/images/sample.png. Host name and port number may be different on your system, the ones listed here are default for the version of Tomcat bundled with NetBeans.

May 20, 2009

Add Syndication to symfony-driven Blog

If you have a standalone blog powered by symfony framework, and would like to add syndication with major blog services like Blogger or LiveJournal, you could use a PEAR “Services_Blogging” package.


First, you download it and then install following this tutorial.

Extract the archive and put the contents in your symphony's lib/vendor/serviceblogging directory. You will also have to add the XML-RPC PEAR package. Download it, extract, then put XML_RPC_x.x.x folder in the servicesblogging directory (there must be a Services folder there) and rename from “XML_RPC_x.x.x” to “XML


Now, install the package as a symfony plugin. For this, edit the config/ProjectConfiguration.php:

class ProjectConfiguration extends sfProjectConfiguration

static protected $sbLoaded = false;

static public function registerServicesBlogging() {
if (self::$sbLoaded) {

require_once sfConfig::get('sf_lib_dir').'/vendor/servicesblogging/Services/Blogging.php';
self::$sbLoaded = true;

public function setup()


Now in your php code you can do the following to add a new post:

$bl = Services_Blogging::factory(
"username", "password",

$post = $bl->createNewPost();
$post->title = $title;
$post->content = $text;

Disable Auto-formatting

A little something for livejournal users: you can disable auto-formatting if you pass a special parameter to livejournal XML-RPC service. To do this the dirty, way, edit Services/Blogging/Driver/LiveJournal.php file of the Services_Blogging package.

Specifically, in the the Driver.savePost() method, add props parameter to the RPC call value:

$value = new XML_RPC_Value(
'username' => $this->userdata['rpc_user'],
'auth_method' => new XML_RPC_Value('challenge', 'string'),
'auth_challenge' => new XML_RPC_Value(
$authdata['challenge'], 'string'
'auth_response' => new XML_RPC_Value(
$authdata['response'] , 'string'

'subject' => new XML_RPC_Value(
'event' => new XML_RPC_Value(
'lineendings' => new XML_RPC_Value('pc'),

'year' => new XML_RPC_Value(date('Y', $time), 'int'),
'mon' => new XML_RPC_Value(date('n', $time), 'int'),
'day' => new XML_RPC_Value(date('j', $time), 'int'),
'hour' => new XML_RPC_Value(date('G', $time), 'int'),
'min' => new XML_RPC_Value(date('i', $time), 'int'),

'props' => new XML_RPC_Value(
array('opt_preformatted' => new XML_RPC_VALUE(true, 'boolean')),


That's it.