Posts

Showing posts from 2008

The week in review - 2008-52

I've just discovered that commons-transactions offers a transactional file service allowing atomic read and writes on a filesystem. Theres a good write up here about the evolution of Wordpress . I love stories like this, because it reinforces the fact that software doesn't have to be perfect when it is released. Releasing early and often can work, and when you do it this way, you can end up with a better product - one that is shaped by the community that uses it. Wow, notice the file size difference based on type here : 22MB mp3 format file 7MB ogg format file I wonder if they sound the same? If I get time I'll download and compare, but in the mean time I'll just hope that OGG gets more support over time. A new garbage collecto r is making its way into java 7. An interesting discussion about the direction of java . Should we ditch backwards compatibility? Releases: Grails 1.1 Beta 2 Oracle SQL Developer 1.5.3

SoundJuicer and MP3

I wanted to convert some CDs to MP3 - normally I'd use OGG, but you can't always rely on devices being able to play that format (i.e. DVD players). I was relieved to see it is easy in Ubuntu 8.10: enable multiverse and universe repos sudo apt-get install gstreamer0.10-plugins-ugly-multiverse  sound-juicer start sound-juicer and go to Edit/Preferences and switch the format to MP3 It was that easy. I seem to remember having to do a lot more with previous versions of Ubuntu.

Comment spam

I've been wondering for a while why people spam blogs with comments like: Your site is so cool, thanks it really helped me! Or any of the many variations. Its usually obvious for several reasons (spelling and just completely out of context) that this is spam. But why bother? It turns out that some blogging software is set up so that if a user has commented, and the administrator has approved that comment, then subsequent comments from that user will be published automatically (without requiring admin approval). That means, once approved, that user is trusted and can comment freely. So, if you accidentally approve this spam bait (innocently believing it to be a genuine complement) expect much more less innocent comments to appear. In Wordpress, this setting can be found in 'Discussion settings' under 'Comment author must have a previously approved comment'.

A better StringTokenizer

I've just been reminded how painful it can be splitting a string based on a token with StringTokenizer . The problem is that it gets messy when you have two tokens consecutively. Luckily commons-lang comes to the rescue with StrTokenizer - where empty tokens may be removed or returned as null.

The week in review - 2008-51

I've had to disable MemoKeys because it interferes with Intellij. I often use ALT-F1 to locate a file in the project tree, but this doesn't work because MemoKeys is intercepting the F1. There is some awesome goodness coming in Grails 1.1 - check out the release notes for the Beta . I just had a requirement to open an EPS file, but I found that GIMP (on Windows) doesn't natively support EPS. As documented , you need to install GhostScript and set an environment variable (i.e. GS_PROG=C:\Program Files\gs\gs8.63\bin\gswin32.exe). Restart GIMP and you should be right. Running a VPS costs money, so reducing the amount of ram required helps. Java applications have the disadvantage of using resources even when they are not being used, so I am interested to read about this strategy which may reduce not only the upload size but the memory footprint. I don't know if anyone has measured the effect on memory - I hope it helps.

MythFrontend for viewing media over the network

I've installed MythTV frontend on my laptop so now I can view TV and recordings, and play music across the network. I had to change the backend setup to serve from the ip address instead of 'localhost', and I also changed bind-address in /etc/mysql/my.conf to use the ip address. I'm not sure if I had to change mysql, but I assume so. I've also edited fstab to mount my media over the network so that the path on the frontend machine is exactly the same as on the backend (this was recommended in the post I found about setting the remote frontend up): //mythtv/media /home/paul/media/ cifs credentials=/etc/samba/user,noexec 0 0 My /etc/samba/smb.conf has a corresponding entry to share the directory: [media] path = /home/paul/media available = yes browsable = yes public = yes writable = no

mobiusly.com launches

A friend finally launched his company mobiusly.com - I expect great things to follow, so keep an eye on this space. I expect 2009 will be a good year for mobiusly. Keep up to date with mobiusly: Blog Feed Twitter

Upgrade to Mythbuntu 8.10 broke nuvexport

I didn't notice until now, but nuvexport has stopped working since my upgrade to 8.10. I found the solution here, but I needed to add the Intrepid Medibuntu repository first. The full solution: sudo wget http://www.medibuntu.org/sources.list.d/intrepid.list --output-document=/etc/apt/sources.list.d/medibuntu.list sudo apt-get update && sudo apt-get install medibuntu-keyring && sudo apt-get update sudo apt-get purge ffmpeg sudo apt-get install libavcodec-unstripped-51 libavdevice-unstripped-52 libavformat-unstripped-52 libavutil-unstripped-49 libpostproc-unstripped-51 libswscale-unstripped-0 ffmpeg sudo apt-get install mytharchive nuvexport

The week in review - 2008-50

A friend must have seen my comment about JDiskReport, and mentioned WinDirStat to me. I'd never seen it before. It's a similar product to JDiskReport but for windows only. I recently tried installing 64 bit ubuntu on a spare partition on my laptop - it already had Vista and 32 bit Ubuntu dual booted with Grub. For some reason the install wouldn't complete and left grub broken so I couldn't boot into any OS. Easy solution - I used the 32 bit Ubuntu alternative disk which has a re-install grub option. This worked a treat. It correctly restored my boot options and the laptop was back in action. I'm not sure why the 64 bit Ubuntu doesn't work on the laptop (Dell1525 Intel Core2 Duo Processor T5550). Looking at the comparison chart , I see that "All Intel® Core™2 Duo mobile processors feature: ... Intel® 64 architecture ... ". What gives? (The installer just fails part of the way through - no error, just freezes).

The week in review - 2008-49

I've been looking for a convenient way to re-use some old harddisks for backup purposes. I think this cable is just what I'm looking for. It appears to support both IDE drives as well as SATA so it means I can get some extra life out of the old disks while still using it for new disks. I'm really only going to be using it for backups so it should be just the thing. I've just upgraded my MythTV media center from MythBuntu 8.04 to 8.10. I downloaded the alternate CD rather than doing a network upgrade. The main reason for upgrading was to support my new Pinnacle Nano DVB tuner - support is built in to Ubuntu 8.10. Previously it required the drivers to be installed manually. I mounted the ISO file and ran: sudo /media/cdrom0/cdromupgrade Eventually it failed due to problems with flashplugin-nonfree and ia32-libs. I removed these packages and re-ran the upgrade and all was okay. After rebooting, the TV-out no longer worked - the NVIDIA drivers were not installed. I h

The week in review - 2008-48

I've installed Ubuntu 8.10 on my Dell 1525. I had 8.04 and I could have upgraded but I like having a clean install, and because with Linux its so easy! When I'm done I'll share my backup and re-install scripts via google-code. I've got /home on a separate partition so the installation really just means running the installer from CD, and then re-installing all of my favourite software. This is just one place where Linux is nifty - all the software is in a repository and installing it can be done from the command line so it can be scripted. And you get the latest versions automatically. No 'download and run setup.exe and click through the wizards'. I'm happy to report that suspend and resume is almost instant - even when disconnected from the network. I haven't installed any extra software yet, so we'll see if it regresses when I have the full compliment of wares (with 8.04 and all of my added software, resuming took ages when disconnected from the net

The week in review - 2008-47

It is a good time for releases: Ubuntu 8.10 Grails-1.0.4 Intellij IDEA 8.0 Netbeans 6.5 Looking around the train platform today I wondered when telecommuting is going to make a significant impact. Everyone needs to be somewhere else - and that puts a lot of strain on the public transport infrastructure. I've had few jobs I couldn't have done from home effectively with decent video, voice and remote control software. Being in an office *would* be far superior if teams were effective, but from my experience most of them are dysfunctional. I think part of the problem here is that managers measure productivity by the time spent at your desk, not by your actual achievements. Know any companies that have effective management, well run teams, good career path and its fun to work? Let me know, because I'm always looking. I was just listening to an episode of Agile Toolkit and it just makes agile seem like a whole different world. I'd love to spend some time at some of the

The week in review - 2008-46

Something was using a port on my windows machine and consequently I couldn't run one of our applications - I came across this article which shows how to identify what application is using a port. This was extremely quick and useful and let me know which processes to kill via task manager. It worked without having to install any software. Working with the ArcGIS Server 9.3 javascript REST apis is a breeze compared to the 9.2 JSF components. The Javascript API makes working with ArcGIS a simple Javascript exercise without huge proprietary knowledge required. To get started, you'll want to check out these resources: Javascript API samples API Reference Wow, SpringSource has acquired G2One ! If I thought I wanted to work for SpringSource before, this doubles that feeling! Spring, Groovy and Grails has made Java development more enjoyable for me, and a heck of a lot more productive. If you haven't seen StackOverflow yet, head over there and have a look. I like it a lot. Thi

The week in review - 2008-45

When Firefox 3 came out, I remember reading a lot of fuss about the AwesomeBar - a lot of people complained about it. Well, I loved it when I first saw it, and I still love it. Occasionally I have to fire up IE6 to check some rendering and thats when I really notice how much I like the awesome bar. Last week I mentioned disk performance and my attention has just been brought to this posting about kitting a developer machine out with SSD for great performance gains. The author compares several different machines and concludes that SSD is the way forward. Looking on the Dell site, it looks like 64GB SSD would add AUD$1000 - a bit rich for me, and for some reason you can't have both a hard disk and SSD. I'd be interested to know why, because it would be nice to combine cheap mass storage (7200 rpm hard disk) and expensive small fast storage. On my personal projects it has become obvious that it isn't just about one language anymore (java, groovy, python, javascript etc). It

The week in review - 2008-44

I was happy to see ' Compile on Save ' added to Netbeans. This is a feature I've always appreciated in Eclipse, its always worked and always made for a good experience. This was one of the top items preventing me from moving away from Eclipse. I want to play with it in Netbeans, and see if it measures up. Speaking of Netbeans, the Maven plugin is awesome! It makes it easy to add a dependency to your project, through an easy to use autocompleteing dialog. With so many Java libraries around, this is the way we should have always been doing dependency management. The linked article doesn't really show how to add libraries, but try right clicking on the 'lib' directory in your project. Notice you can also download all javadoc and sources for your dependencies. So easy!! I'm enjoying using Netbeans 6.5 for Grails development now. I haven't explored the functionality all that much, but using just the basics is effective. Hopefully this support will grow quick

URI "file:./" is not hierarchical

Just recently I came across the following exception when deploying a simple Grails application to Tomcat : URI "file:./" is not hierarchical The application was so simple and ran locally on tomcat-6.0.16 - it had to be something environmental. Comparing the differences between machines showed that it was the JVM that was different. The JVM that produced the error was: java version "1.5.0" gij (GNU libgcj) version 4.2.4 (Ubuntu 4.2.4-1ubuntu3) while the Sun JRE 1.6 was okay: java version "1.6.0_03" Java(TM) SE Runtime Environment (build 1.6.0_03-b05) Java HotSpot(TM) Client VM (build 1.6.0_03-b05, mixed mode) Note that this occurred on Ubuntu 8.04 64 bit Linux: Linux dev 2.6.24-21-generic #1 SMP Mon Aug 25 16:57:51 UTC 2008 x86_64 GNU/Linux

Somewhere to put the code

I've written a lot of code in the past, and lost a lot of code over the years too. To prevent losing anymore and to help organise things, I've set up a repository at http://code.google.com/p/javathinking/source/browse/#svn/trunk . There's not a lot there at the moment, just a linux script to extract the audio from an MP4, and a groovy script to extract a specified database from a mysqldump file: makemp3.sh splitdb.groovy I've tried to keep everything self contained - documentation is in the code - and hopefully someone else will find the contents useful. I also hope it will grow and become more useful over time, but time is the problem - there is so little of it...

ST_Intersects performance

I was just using a query which made use of the ST_INTERSECTS function: select * from table1 where st_intersects(st_point( ?, ?, 1),shape)=1 With the data I had, this query took 30 seconds! Before launching into an investigation to find out why, I just decided to swap the parameters - this made all the difference: select * from table1 where st_intersects(shape, st_point( ?, ?, 1))=1 Now the query returns instantly! I'm no database expert, so investigating why the first version of the query took so long would have been a waste of valuable time - when such a simple solution was at hand.

Finding table differences in Oracle

Often there is a need to compare two databases and see the differences. I come across this a lot when releasing a new build into an existing environment - the new code runs on the development database, but the test environment needs a schema upgrade before the code will run. There are tools that will compare schemas for you, but sometimes I just need to quickly find out what columns are missing from the target schema (this is particularly useful when comparing different development schemas and you want to quickly implement changes - production releases need much better quality control than this). The sql below provides one solution - showing the columns that are missing from 'owner1' when compared to 'owner2' for tables that match the prefix: This will ofcourse identify missing tables. It's primative, but its an easy way to see basic structural differences using SQL - without the need for expensive tools. Since it is basic sql, you could include this as part of an e

grails-jsunit-0.3

I've just released grails-jsunit-0.3 - a plugin which adds jsunit support to grails applications. This release changes the download url for the jsunit binaries to http://internode.dl.sourceforge.net/sourceforge/jsunit/jsunit2.2alpha11.zip, and is upgraded to grails-1.0.3. When you install the plugin, it will download the jsunit binaries from the url above to $GRAILS_HOME/downloads - if it fails, you can manually download it and put it there. Hopefully this release fixes some problems described on the forums . Note though, that I haven't had any luck running jsunit with FireFox 3 - a problem that is referenced here .

Built with AppEngine and Groovy

I've just released http://blogs.morehappydogs.com/ - this is a AppEngine / Groovy blend - the application aggregates blog posts about dogs. If you are interested in dogs, check it out. The web tier is build with AppEngine in Python . AppEngine supplies the database via Datastore. Since you can't run jobs within appengine, I wrote services in Groovy which process the feeds and upload new entries. This groovy code runs as a script on my linux server, scheduled with cron . This approach suits me well, since I'm no Python expert, and I do like groovy. This keeps the appengine (python) minimal and essentially just the web/presentation layer. Using groovy for the backend services means I can use my Java experience and benefit from the productivity of groovy.

grails-selenium-0.5

I've just released a new version (0.5) of the selenium plugin , which fixes compatibility problems with Grails 1.0.3. Hopefully all is well now and I'd like to apologise to all the users out there who ran into problems. If you encounter any more issues, you can email me at paul@javathinking.com. On another note, it would be cool to know how much a plugin is being used. For example, I've got no way of knowing if anyones actually using any of the plugins I've written so its hard to prioritise work. Perhaps we need a download counter to give a rough indication... ?

Displaying dates and times with Oracle

I use SQLDeveloper when interacting with Oracle . When viewing tables with date columns it can be frustrating that the default display does not show time (just day, month and year). To change this behaviour, you can set the date format for your current session: alter session set NLS_DATE_FORMAT='DD-Mon-YYYY HH24:MI:SS' Now, when you view tables or resultsets, you'll have a more precise view of the data: 04-Sep-2008 09:07:51

MyOnlineProfile.net launches

MyOnlineProfile.net  has launched - as a Google  AppEngine  application. MyOnlineProfile lets you catalog your public online profiles in one place - leaving you with just one link to give your friends and one link in your email signature. I first wrote MyOnlineProfile as a  Grails  application - its a small application at the moment, so it didn't take long. However I did over-engineer it. I made the classic mistake of trying to solve the wrong problems and over-optimising. Luckily with being a small application and written with such a productive framework, I'm only talking about wasting hours rather than months. I deployed it to my Linux VPS, but unfortunately,  Java  based applications take up quite a bit of resources just starting up and memory on a VPS costs money (recurring money). So there just wasn't room for it. Hence re-writing it in  Python  for AppEngine. Being exposed to Python has been good for me - and relatively easy since  Groovy  opened my mind signi

Converting from Flash to AVI

If you want to convert from Flash to AVI (on linux) there is a good script here . It uses mencoder to convert files specified on the command line to XVID or DIVX - files are created using the same filename, but with an avi extension.

Prototype, JSON and Appengine

I am using prototype in a Google Appengine project, and while it worked on my development machine, after deploying it onto the Google infrastructure prototype wasn't parsing the JSON responses anymore. In my code, I was returning the JSON in the response text (as opposed to using X-JSON response header). The Content-Type response header was set as application/json and my javascript code used Ajax.Request() with the parameter evalJSON:true so as to parse the response text. Running locally with the dev_appserver.py everything worked okay. However when running the deployed app, the Content-Type header was no longer being set - meaning that prototype would never parse the response text. I'm not sure why Content-Type doesn't get set when running on the Google infrastructure yet it works on the development server. But, luckily when using Ajax.Request, you can specify evalJSON:'force' so that prototype parses the response regardless of the content-type. Server ajax respons

Oracle types

It frequently surprises me when seemingly simple things are missing from mature products. For example, Oracle doesn't have a boolean type. Strange but apparently true. Never mind, this article describes how to work around this.

Rename mythtv recordings

The files Mythtv records are saved with a timestamp as a file name, making it pretty hard to figure out which file is which. To easily identify the files, you can use mythrename.pl - I couldn't find it in my Mythbuntu installation, so I had to download it from http://svn.mythtv.org/svn/trunk/mythtv/contrib/user_jobs/ . It ran okay, without any dependency problems. This post has some useful comments on how to run it. The idea is that you can schedule it with cron to run at regular intervals so as to stay current. I'm running it so it doesn't actually rename the original files, but it makes sensibly named symbolic links to the originals: mythrename.pl --format "\%T/\%Y-\%m-\%d \%H\%i \%- \%T \%-\%S" --link /home/paul/TVShows For help with the options, see the wiki page or run with the --help option.

Oracle version information

When making support requests it is always helpful to include version information about the product in question. Rather than just stating 'version X' I like to get the software to display the version information and just copy and paste it - this way there can be no confusion, and there may even be extra useful information. So, how to display the oracle version information? I came across this useful post which suggests: select banner from v$version; which on the instance I'm looking at produces: BANNER---------------------------------------------------------------- Oracle10g Enterprise Edition Release 10.2.0.3.0 - Production PL/SQL Release 10.2.0.3.0 - Production CORE    10.2.0.3.0       Production TNS for Solaris: Version 10.2.0.3.0 - Production NLSRTL Version 10.2.0.3.0 - Production Being an SQL query is even more useful than a command line, since you can run this within your applications if you need to display such data.

Media center with MythTV

Last November I upgraded my desktop PC. Recently I've repurposed it as a media center running MythTV (and also for print serving/file serving etc). The hardware is as follows: Sonata III 500 W case Gigabyte GA965P-S3 motherboard Core2 Duo E6550 CPU Gigabyte 8400GS Nvidia video card WinFast DTV1000 digital tuner card 320MB SATA disk Kingston 1Gig DDR2 800MHz memory Since then, I've added a 1Terabyte SATA disk - prices keep coming down every week. You can get a 1T disk for just over AUD200 now. I installed MythBuntu 8.04 and found it a very simple process. I had to configure it for TwinView (Clone) so I've got the same output on my TV as I have on the LCD monitor. Then I had to get sound via the SPDIF optical output. To do this you have to: Unmute the ICE958 channel via alsamixer Configure MythTV to use ALSA:SPDIF and AC3 + DTS to SPDIF passthrough I also had to change my video player command to 'mplayer -ao alsa:device=spdif -fs -zoom -quiet so -vo xv

Grails, favicon, and urls

I've just spent a little too much time trying to get my favicon working properly on a new grails application. The issue I encountered was due to the fact that I wanted users to be able to access their accounts using '/[username]' - i.e. /paul To accomodate this, I used a UrlMapping: "/$id" { controller='display' action:'index' } Now, this meant that /favicon.ico would hit the controller, and not server the icon file. I first thought I could get around this by constraining the above mapping - so I tried: "/$id" { controller='display' action:'index' constraints { id(notEqual:'favicon.ico') } } It seems though that the only constraint you can use is 'matches'. At least 'notEqual' resulted in a compile error, and all of the examples use 'matches'. So I thought I'd use matches with a regular expression of to exclude the word 'favicon.ico' - turns out that ma

Firefox 2 on Ubuntu 8.04

I've been a little frustrated with the lack of my usual Firefox plugins due to most of them not being available for Firefox 3, so I've decided to install Firefox 2. It seems apparently easy: sudo apt-get install firefox-2 Now, I can run Firefox 2 from the command line with firefox-2 Firefox 3 still works, by running 'firefox' - so while I can use 3 for browsing, I can use 2 for developing. Note, I had to create a new profile for FireFox 2, because it didn't seem right to run it with the version 3 profiles (and the extensions had a few issues) - but this is fair enough. See Firefox Profiles for more information.

No Dialect mapping for JDBC type: -1

This Hibernate error came at me out of the blue while working on FilmSuggestions.com - I innocently added a constraint to one of my Grails domain models, setting the maxSize of one of the fields to 2000. This changed the table schema making the column type TEXT instead of VARCHAR. The problem came from a native query: sessionFactory.getCurrentSession().createSQLQuery(mostPopularFilmsSQL).list() This selects the TEXT column which results in the error (as described here ). Setting the dialect didn't seem to make any difference, so for now I've changed the constraint so it's back to being a VARCHAR.

Recycling electronic waste - www.thegreenpages.com.au

I've got a couple of old computers and a collection of components that are good for nothing in todays world. But I've had trouble finding somewhere that will take it off my hands and dispose of it in an environmentally friendly way. Imagine my surprise when I saw a google advert on my own blog for  http://www.thegreenpages.com.au/  - a directory of Eco friendly organisations which includes a category on recycling. Hopefully it won't be long before I can clean out some of the rubbish.

Rhythmbox

I've just been playing with RhythmBox for the first time, and am very pleasantly surprised. This application so far takes care of my music and podcast requirements, and also supports the iTunes links you see on so many sites. You can either copy the iTunes link and add it manually, or in FireFox, clicking on the link pops up a dialog asking what application should be used - specifying /usr/bin/rhythmbox achieves the desired result, and the podcast is added just like that. Rhythmbox also supports my wifes ipod, which is great for managing that. Although I don't use internet radio, I'd like to and it takes care of that too. I've still got more to play with, but so far I'm happy and will be sticking with it for the foreseeable future. (Ubuntu 8.04Beta, Linux Dell Inspiron 1525 Laptop, 2.6.24-16-generic #1 SMP Thu Apr 10 13:23:42 UTC 2008 i686 GNU/Linux)

Wordpress error - Allowed memory size of ## bytes exhausted

I just came across a problem using wordpress that stopped everything working - any request to the Wordpress site resulted in a blank page. In the log file for the host, I could see: PHP Fatal error:  Allowed memory size of 8388608 bytes exhausted (tried to allocate 14592 bytes) in <path to a plugin php file> Removing the plugin specified just meant that the error was reported for the next plugin. Searching Google showed many discussions about this problem. Luckily the solution for me was easy enough - as described in this topic : In <wordpress root>/wp-includes/cache.php I just added: ini_set("memory_limit","12M");

grails-selenium-0.4

This information is out of date - please see http://www.grails.org/Selenium+plugin Version 0.4 of the grails selenium plugin is now available. This version adds: scripts to create and run tests a postResults url for displaying the final test results Details are as follows: run-selenium Runs Selenium in the specified browser. Specify the path to your browser as a command line parameter i.e. grails run-selenium /usr/bin/firefox or, if the executable is on the path you would just need grails run-selenium firefox In your application.properties, you can specify: selenium.auto=true selenium.close=true selenium.multiWindow=true selenium.highlight=true selenium.resultsUrl=/your/url/here (defaults to ${appContext}/selenium/postResults) selenium.runInterval=1000 selenium.baseUrl= See http://selenium.openqa.org/installing.html (section titled Continuous Integration) for more information on selenium and continuous integration. create-selenium-test Generates a new empty selenium test. Supply th

grails-jsunit-0.1

This information is out of date - please see http://www.grails.org/jsUnit+plugin grails-jsunit provides an easy and convenient way to utilize the JsUnit framework to your grails application. JsUnit allows you to unit test JavaScript functions in a similar way to using JUnit for Java. To install the plugin, use: grails install-plugin http://www.javathinking.com/grails/grails-jsunit-plugin/0.1/grails-jsunit-0.1.zip This plugin adds the following new scripts: create-jsunit-test Generates a new empty jsunit test. Supply the path of the test you want to create, relative to 'test/jsunit/tests'. Example use: grails create-jsunit-test registration/mytest creates ${basedir}/test/jsunit/tests/registration/mytest.html run-jsunit Runs JsUnit in the specified browser. Specify the path to your browser as a command line parameter i.e. grails run-jsunit /usr/bin/firefox or, if the executable is on the path you would just need grails run-jsunit firefox In your application.properties, you can s

Firefox profiles

If you share a login with someone else (ie. family) Firefox profiles can be very useful. Likewise, if you are a developer and you have several different contexts or modes of operation, profiles can make life a lot easier. I use them at home with family members - you can set each person up with their own profile, so all you have to do is restart Firefox (rather than logging out out of the operating system and then back on as someone else). Firefox will prompt you - asking who you want to be right now. At work, how many times have you cleared all of your private settings while debugging, just to see if the problem is related to caching or some other previous state. Creating a profile is much easier - especially since you probably want to stay logged in to all of those websites you use every day. Just start firefox from the command line with the parameter '-profilemanager' - you'll be prompted with a dialog so you can mange your profiles. Read more about it here : http://www.

Looking for IT work in Australia? JobReel.com.au!

I'm currently looking for contract work, and all of the usual places offer vague job descriptions that makes it hard to differentiate one from the other. This makes it hard to decide which ones to apply for, and almost always mean that you end up applying for jobs that are totally inappropriate. Now there is JobReel.com.au - much along the lines of jobs.joelonsoftware.com , positions must display the employer. I'm still looking for a site that lets me specify location, price range, responsibilities and technologies - but JobReel is closer than any of the others, and from what I've seen so far, the job descriptions are more useful and realistic. It looks relatively new to the scene - good luck!

Ohloh.net

I just discovered http://www.ohloh.net/ - this is a great site, I think the easiest way I can describe it is by saying it is like linkedin.com , but based on opensource projects. You can create an account, and then add opensource projects to your 'stack'. You can: see geographically where people with a particular project on their stack are located add your experience to your profile to build your resume view statistics for different languages and projects. This is a very interesting site, and it will be interesting to see where it goes. Check out my profile .

grails-selenium-0.3

Version 0.3 of the grails selenium plugin is now available. This version: Adds GSP support for writing tests Fixes bug where hidden directories were shown as suites Fixes bug on windows with invalid URIs to html tests To use GSP to generate the tests, use the <sel:test> tag, followed by nested <sel:row> tags. <sel:row> can take either: one 'line' attribute where the command, target and value are pipe separated as per the pipe separated value files or separate 'command', 'target', and 'value' attributes. Because this is a normal GSP file, you have full access to the normal variables and you could call other classes for utility methods. An example GSP test: <g:set var="bookTitle" value="book0d"/> <sel:test name="MyTest"> <sel:row command="open" target="${request.contextPath}"/> <sel:row line="clickAndWait|link=BookController"/> <sel:row line="

grails-jttaglib-0.1

grails-jttaglib plugin is a small collection of convenience tags. The sample code below assumes you have a domain class that looks like this: class Book { String title="my new book" String content static def constraints = { title(maxSize:20) content(maxSize:200) } } When using these tags, you must have the following in the page - normally in the head block: <g:javascript library="prototype"/> <jttext:script /> textArea Creates a TextArea HTML element, where the maximum number of characters is limited by the constraints on the domain object, and tabs can be allowed if desired. Sample use: <jttext:textArea object="${new Book()}" name="content" allowTabs="true"/> <jttext:statusDiv for="content" /> The number of remaining characters available are displayed in the status div. If allowTabs is set to true, tabs can be entered in the text area. textField Creates a text input type usi

Regression testing grails plugins

For regression testing the grails plugins I've released, I have a shell script that: cleans up any previous runs packages the current code for the plugin OR downloads a release from my web site creates a new grails app copies preprepared resources into this new grails app installs the plugin Now all I have to do is run the application and test it through the browser (potential for selenium to help here?). This is great for testing the plugin against a new grails version, or just for testing code changes to the plugin itself. I put the script in <project_home>/test/regression/run.sh and the resources in <project_home>/test/regression/resources. The resources directory contains files like domain objects etc in the same directory layout as a normal grails project. This way I just need to copy the contents of the resources directory over the top of my newly created project. I should have written it as an ANT script though (what was I thinking?) - then it would be platf

Regression testing grails plugins

For regression testing the grails plugins I've released, I have a shell script that: cleans up any previous runs packages the current code for the plugin OR downloads a release from my web site creates a new grails app copies preprepared resources into this new grails app installs the plugin Now all I have to do is run the application and test it through the browser (potential for selenium to help here?). This is great for testing the plugin against a new grails version, or just for testing code changes to the plugin itself. I put the script in <project_home>/test/regression/run.sh and the resources in <project_home>/test/regression/resources. The resources directory contains files like domain objects etc in the same directory layout as a normal grails project. This way I just need to copy the contents of the resources directory over the top of my newly created project. I should have written it as an ANT script though (what was I thinking?) - then it would be

Allowing tabs in a text area

In addition to controlling the maximum number of characters in a text area , I also want to allow the user to enter tabs. But default, hitting tab would move out of the text area to the next control on the page. Overriding this behavior can be done by using the onKeyDown event controller so you can: check if the tab key has been pressed if it has, insert a tab at the current cursor location put focus back into the text area I've extended my little TextAreaTagLib to handle an 'allowTabs' attribute. Now you can allow tabs to be entered just by using allowTabs="true". I've also incorporated the work from the TextField modification so that the number of characters can be limited based on the maxSize constraint on the object. Sample use: <g:javascript library=”prototype”/> <jttext:script /> ... <jttext:textArea object="${new Book()}" name="content" allowTabs="true"/> <jttext:statusDiv for="content&quo

Allowing or denying self registration with grails-acegi plugin

The grails-acegi-0.2 plugin is great - it adds login, user management, and user registration capabilities to your application in seconds. However, I'm building a web application where I want to be able to let the deployment team decide whether users can register themselves or alternatively, have an administrator create users. I want provide these settings without the deployment unit (the WAR file) having to be modified. I currently have a properties file for each server (DEV, STAGE, PROD) which defines properties specific to the environment - such as the email server and username/password etc. In this properties file, I also have application settings which are relevant to that environment. So, this is a good place to define a property: myapp.registration.enabled=false Grails has an excellent configuration strategy, and in my applications Config.groovy all I have to do is specify the external config locations: grails.config.locations = ["file:${System.getProperty('myapp.pro

Maxlength HTML attribute for domain objects

With Grails domain classes, constraints can be specified - including the maximum size of a String. For example: class Book { String title static def constraints = { title(maxSize:20) } } When using 'grails generate-all' to create scaffolding, you'll notice that create.gsp and add.gsp hardcode the maxlength attribute: <input type="text" maxlength="20" id="title" name="title" value="${fieldValue(bean:book,field:'title')}"/> It is possible to directly reference the constraint, meaning that the maxlength attribute is not hardcoded - and thus only defined once (in the domain object): <input type="text" maxlength="${Book.constraints.title.getMaxSize()}" id="title" name="title" value="${fieldValue(bean:book,field:'title')}"/> In fact, we can go even further and create a tag where we pass in the object itself, and

Limiting the content of a TextArea

Being able to limit the length of the content entered into a TextArea can be useful for various reasons. Although not supported natively by HTML, you can achieve the same effect using Javascript - on KeyUp and KeyDown events, check the length of the textarea value and truncate if necessary. We can also display how many characters are remaining if we want to provide user feedback. Because I've used this technique in several Grails applications, I've created a simple TagLib - you may want to customize it to your requirements. To use it: include the prototype library with <g:javascript library="prototype"/> use <jttext:changeScript /> once on your page for the utility script define your textarea including the maxlength attribute with <jttext:textArea id="messageField" maxlength="20" /> use <jttext:statusDiv for="messageField" /> to display the status message showing how many characters are left So, a simple GS

mappings closure does not exists for class UrlMappings

I've just started working on a new grails application, and early in the piece I hit this error: 2008-03-05 18:39:20.715::WARN: Failed startup of context org.mortbay.jetty.webapp.WebAppContext@1fcb845{/jtchat,/home/prule/workspace/jtchat/web-app} org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.codehaus.groovy.grails.plugins.web.taglib.ApplicationTagLib': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'grailsUrlMappingsHolder': Cannot resolve reference to bean 'urlMappingsTargetSource' while setting bean property 'targetSource'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'urlMappingsTargetSource': Cannot resolve reference to bean 'grailsUrlMappingsHolderBean' while setting constructor argument; nested exception is org.springframework.beans.

Sun Tech Days 2008

I'm currently attending the Sun Tech Days conference in Sydney. These events can be good for exposure to things not already on your radar, and also for catching up with colleagues you haven't seen for a while. Some of the presentations are online if you are interested. There is a session on 'Grails as an application framework: pros and cons' tomorrow - but so far there has no mention of Groovy or Grails (but plenty of references to JRuby, Ruby, Python, PHP, Javascript). Update 1 : Mike Cannon-Brookes presented Grails - this was a good introduction for anyone new to Grails. It appears he is very enthusiastic about it and Atlassian are using it to some extent internally.

grails-selenium-0.2

I've just uploaded a new version of my Selenium plugin for Grails . You can download it from http://www.javathinking.com/grails/grails-selenium-plugin/0.2/grails-selenium-0.2.zip . The only significant enhancement is to support tests nested in directories. Now, the suite page displays a list of all of the directories in the tests location. The default (top level) suite shows all tests in all directories. You can click anywhere in this suite heirarchy to load only those tests in that directory. Let me know what you think of this implementation. There are probably several different ways to go about handling the directory structure, and this is just one implementation. I hope you find it useful! (for more complete information about this plugin, see grails-selenium-0.1 .

grails-selenium-0.1

This release has been superseded - Please see http://grails.codehaus.org/Selenium+plugin for the latest release information. I'm a big fan of Selenium - it lets me test my web applications easily, quickly, and inside the browser. Now I've created a Grails plugin to bring the efficiency of Selenium to Grails projects easily. When you install this plugin, it will download the Selenium-Core distribution (currently version 0.8.3 - 1.5MB) and extract it into your grails application (into <grails project>/web-app/selenium/core). Now you simply create your Selenium tests - putting them in <grails project>/web-app/selenium/tests. This plugin will automatically generate your test suite by listing all of the files in the selenium/tests directory. You can create tests as standard HTML as per the selenium documentation (and easily created using SeleniumIDE ). Or, you can for-go the HTML for pipe delimited text files (*.psv) - this plugin will convert the pipe delimited fil

Installing Grails on Linux

I run Linux ( Ubuntu 7.10) as my desktop operating system, and it's working out well. However, every time I upgrade Grails I forget to make the script in $GRAILS_HOME/bin executable and get this error: prule@dev2:~/workspace/film-suggestions-grails$ grails clean Exception in thread "main" java.lang.NoClassDefFoundError: org/codehaus/groovy/grails/cli/support/GrailsStarter So, if you find yourself with this cryptic message, it is time to RTFM - the installation instructions actually point out: If you get an error message, try to chmod +x the grails script inside the bin directory. When I googled this exception I got unrelated stuff. Hopefully now if you search for this you'll find this post and be up and running fast. Note:  I experience this problem because I always download the zip distribution. If you get the tar.gz binary, extracting this will preserve the correct file permissions.

Linux VPS - RimuHosting.com

Image
Looking to host an application on the web? The most flexible solution is to have a virtual server - JavaThinking.com and FilmSuggestions.com are hosted on a Linux VPS from RimuHosting.com . This gives me root access to my very own Linux installation where I can install anything I want and configure it any way I want. I can recommend RimuHosting (although they are the only provider I've tried) - they have been very helpful and quick to respond to questions. Their services seem complete and appropriately priced, and the service is excellent. They've got very useful information about Linux and Java hosting on their Bliki and in their HOWTOs . Our VPS Hosting By RimuHosting

Ubuntu mysql update

I recently tried a system update (Ubuntu 7.10), and everything but mysql get updated. Every time I tried, Update Manager reported that the mysql update failed. I found this post , which essentially says that you need to stop mysql before trying the update. I've successfully done this, and now my update has been applied successfully.