Friday, December 30, 2005

bug in Tomcat 5.0.16

I discovered that the reason my sessionDestroyed() handler is called twice is, for a change, not due to my rauceus programming but because of the Tomcat version (5.0.16) I was using. The standard sessions manager expires timed out sessions twice, once when checking whether they have expired and again when, well, is on the job. Of course I'm sure you're not using that old a Tomcat version but just in case. See bugzilla issues 25234 and 27273 for more info. There's actually at least a couple more duplicate issues there.

Friday, April 01, 2005

What happened to the Opencola?

I wasn't aware that the Opencola softdrink formula was just a marketing promotion to support the OpenCola company's open source product. Apparently the Toronto based company fell victim to its own promotion: no one really remembers or even knows that OpenCola actually wrote software. The GNU licensed open cola formula was removed from public availability as of October 31, 2002. Back then though, open cola was even consumed at student parties and sold over the internet. Now the only thing you can buy from the domain seems to be cheap bedding...

Sunday, February 13, 2005

javascript compactor in java

To my astonishment I found out that there are very few free javascript compressors out there, and most of them don't actually work. I came across Mike Hall's Javascript Crunchinator, a javascript compressor which, being written in Javascript, is very slow and didn't work for my sample complex script. The other worth mentioning compressor was a Perl snippet written by Mihai Bazon. I decided I wanted one written in Java instead, so I sat down and cranked out the following just so that you have yet one more option...

import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

 * The compactor can be used to compact java scripts by removing comments, 
 * leading and trailing whitespaces, newlines, and condense any spaces between
 * operators, parentheses, brackets etc. It only works if all statements 
 * (including classes and simple functions) are properly
 * terminated by semicolons. If you read the script from a file using 
 * readLine() method make sure you put the new line character back at the end 
 * of the line, as readLine() consumes it.
public class JavascriptCompactor {
    public static String compactJSCode(String sCode) {
        // Protect single and double quoted strings.
        Pattern strings = Pattern.compile("\"(\\\\.|[^\"\\\\])*\"

        Matcher m = strings.matcher(sCode);
        StringBuffer sb = new StringBuffer();
        HashMap theStrings = new HashMap();
        while (m.find()) {
            String sReplacement = "__STR_" + theStrings.size();
            m.appendReplacement(sb, sReplacement);
        sCode = sb.toString();

        // remove C style comments
        Pattern pattern = Pattern.compile("/\\*.*?\\*/", Pattern.DOTALL);
        sCode = pattern.matcher(sCode).replaceAll("");

        // remove C++ style comments.
        sCode = sCode.replaceAll("//.*?\\n", "");

        // remove leading/trailing whitespaces.
        sCode = sCode.replaceAll("(?:(?:^|\\n)\\s+|\\s+(?:$|\n))", "");

        // remove newlines.
        sCode = sCode.replaceAll("\\r?\\n", "");

        // remove spaces around operators etc.
        sCode = sCode.replaceAll("\\s+", " ");
        sCode = sCode.replaceAll("\\s([\\x21\\x25\\x26\\x28\\x29 \                
              \\x5b\\x5d\\x5c\\x7b\\x7c\\x7d\\x7e])", "$1");
        sCode = sCode.replaceAll("([\\x21\\x25\\x26\\x28\\x29
              \\x5b\\x5d\\x5c\\x7b\\x7c\\x7d\\x7e])\\s", "$1");

        // Put back strings.
        m = Pattern.compile("__STR_\\d+").matcher(sCode);
        StringBuffer result = new StringBuffer();
        int iLastEnd = 0;
        while (m.find()) {
            result.append(sCode.substring(iLastEnd, m.start()));
            result.append((String) theStrings.get(;

            iLastEnd = m.end();

        return result.toString();

Friday, January 28, 2005

gmail and K700i bug

I was invited by a friend to try out the new beta version of Google's email service. Invitations get distributed randomly on a limited basis, as a means of throwing in a bit of exclusivity to it. Meaning, if you're not invited by someone, you can't get an account. So I got mine -, what else? - and started playing around with it. The good stuff:
  • 1G of space at 10MB per message
  • seamless contacts importing from Outlook
  • a reasonably 9 months allowance for dormant accounts before you get thrown out
  • atom 0.3 support
  • free POP access
  • keyboard shortcuts
So far so good. Unfortunately, I've had no luck accessing the account from my newly bought SonyEricsson K700i due to a hideous ssl bug. Basically, the last m in the outgoing ssl domain disappears during connection and the phone hungs up while "Receiving messages"! How dissapointing. For those of you that happen to have a Vodafone GR connection, here's the steps for setting up the data connection (pop settings can be found in gmail's help center).
Go to Connectivity, Data Comm., Data Accounts and select New Account. Pick the Gprs data type and enter a name for the connection. Use as APN, Username user and Password pass. Save and you're done.

If you manage to get it working for gmail, let me know, will ya?

Wednesday, January 26, 2005

extensionless files in windows

Another geeky post I'm afraid. There's loads of extensionless files out there like LICENSE, Readme, Makefile etc that cannot be associated with an application directly from Windows' UI; alas, the Always use the selected program to open this kind of file checkbox is simply denying us the obvious. Log in as admin and run this little reg file to associate all such files with UltraEdit. You can use any application you want of course, that's just my favourite editor there.



@="no extension"



@="\"C:\\Program Files\\UltraEdit\\uedit32.exe\" %1"


@="\"C:\\Program Files\\UltraEdit\\uedit32.exe\" /p \"%1\""

Tuesday, January 11, 2005

recover cvs pserver passwords

Being a very forgetful person, I relied upon my encoded cvs password too much lately and had never really bothered to keep a copy of the clear text; until I had to use Tortoise for some cvs operation. I've always meant to be sorting that little negligence on my part out but I never actually got round to it...

As I was waiting for the support people to reset my password, I did some research on cvs' pserver password scrambling algorithm and I found that all it does is a simple mapping, described in detail in section 6 of The CVS Client/Server Protocol. So, for example, '%' will be mapped to 'm' and 'm' can be decoded by getting the inverse mapping back to '%', as simple as that. Officially, only a subset of characters can be used for passwords and encoded passwords, see discussion in section 8. Based on that, I wrote a java class for encoding and decoding cvs passwords, using pserver authentication protocol's scrambling algorithm. I'd been too slow; by that time my password had already been reset by our support team.

 * A simple class for encoding and decoding passwords for cvs'
 * pserver protocol. Can be used to recover forgotten passwords.
public class CvsPassword {

    private static char[] aChars = {0, 0, 0, 0, 0, 0, 0, 0,
                                    0, 0, 0, 0, 0, 0, 0, 0,
                                    0, 0, 0, 0, 0, 0, 0, 0,
                                    0, 0, 0, 0, 0, 0, 0, 0,
                                    114, 120, 53, 79, 0, 109, 72, 108,
                                    70, 64, 76, 67, 116, 74, 68, 87,
                                    111, 52, 75, 119, 49, 34, 82, 81,
                                    95, 65, 112, 86, 118, 110, 122, 105,
                                    41, 57, 83, 43, 46, 102, 40, 89,
                                    38, 103, 45, 50, 42, 123, 91, 35,
                                    125, 55, 54, 66, 124, 126, 59, 47,
                                    92, 71, 115, 78, 88, 107, 106, 56,
                                    0, 121, 117, 104, 101, 100, 69, 73,
                                    99, 63, 94, 93, 39, 37, 61, 48,
                                    58, 113, 32, 90, 44, 98, 60, 51,
                                    33, 97, 62, 77, 84, 80, 85};

     * Encodes a cvs password to be used in .cvspass file. Throws an
     * exception if sClear is null, if a character is found outside
     * the 0 - 126 range, or if within the range, one of the
     * non-allowed characters.
     * @param sClear the password in clear to be encoded
     * @return the encoded cvs password
    public static String encode(String sClear) {
        char[] acScrambled = new char[sClear.length() + 1];

        acScrambled[0] = 'A';
        for (int i = 1; i < acScrambled.length; i++) {
            char c = sClear.charAt(i - 1);
            if (c == '`' || c == '$' || c < 32)
                throw new IllegalArgumentException(
                        "Illegal character was found in clear password.");
            acScrambled[i] = aChars[c];

        return String.valueOf(acScrambled);

     * Recovers an encoded via pserver protocol cvs password.
     * Throws an exception if passed a null input.
     * @param sScrambled the encoded password to be decoded
     * @return the decoded password
    public static String decode(String sScrambled) {
        if (sScrambled.equals(""))
            return "";
        return encode(sScrambled.substring(1)).substring(1);

    public static void main(String[] sArgs) {
        // Encode password and decode the result.
        System.out.println(CvsPassword.decode("A:yZZ30 e"));

        // Print the character mapping used for the
        // password scrambling.
        for (int i = 33; i < aChars.length; i++) {
            System.out.print(i + "(" + (char) i + ")->");
            System.out.print((int) aChars[i] + "(" + aChars[i] + ") ");

Saturday, January 08, 2005

AQA - any questions answered

If you happen to have a UK mobile number, then you can ask ANY question by text message to 63336 24 hours a day, 7 days a week. IssueBits, set up by Colly Myers, former CEO of Symbian and MD of Psion PLC, with Bill Batchelor and Paul Cockerton, launched the AQA (Any Question Answered) service back in April 2004, and has since then become so popular that some have asked over 300 questions and several others over 30 questions in one day! At one quid a pop, that's £300 and £30 respectively... Incredibly enough, the most popular question is: "Why do men have nipples?" and for the curious the answer given by AQA is: "Initially an embryo is female and develops to male after about 7 weeks. Nipples have already been formed at this stage and there is no reverse process.". A close runner up is: "What is the meaning of life?" which, according to Douglas Adams, is 42 of course! Other obsessive subjects include:
  • Which celebrities are ticklish
  • Sexual aids positions & techniques
  • What to do on a first date
  • How to chat up women in the office
Every question asked gets passed to AQA's growing band of researchers, students, housewives, retirees, from different time zones, who scurry for facts. Some of my favourites include:

Where will I meet my future wife? You will meet your future wife perusing the personal hygiene aisle in the Slough branch of Tesco, Wellington Street, SL1 1XW

What colour boxer shorts am I wearing? You are wearing green and purple polka dot boxer shorts, with the words "LOVE GOD" embroidered across the front in golden thread

Dude, where's my car? You've obviously partied too much last night. Beware of angry girlfriends, street gangs, transexual strippers and alien cults today. It's at your mum's.

Student exams and pub quizzes shall never be the same again indeed.

Tuesday, January 04, 2005

smash my phone

This is a site about "trampling, crushing and smashing telephones". You send them your phone you hate so much and "unforgiving technicians will crush it into small pieces". They will then send it back to you, or rather what's left of it, together with high quality pictures and video as testimony... There's hundreds of pictures and videos on the site that are updated regularly and they are even going to release the first DVD title this January! Amazing.

Monday, January 03, 2005


If you read the Linux Journal you might have already seen it. It's the Google Labs Aptitude Test and it's started appearing everywhere. It's meant to be a first screening test for people wanting to join Google. You can try it, it's only four pages long. Get your own copy from Google's site. The people at Mathworld (wolfram) have actually put together a nice page with answers to some of the test's problems. It's interesting to know that Sergey Brin, president of technology at Google, was himself an intern at Wolfram Research before cofounding Google.

Sunday, January 02, 2005

the subservient chicken

Crispin Porter & Bogusky is the company behind the bizarre chicken mascot for Burger King, the subservient chicken. I checked the site yesterday and the chicken - or rather, the man behind the costume - is still there, waiting for your perverse orders. One of the new buzz or viral ads, the subservient chicken was created to convey Burger King's "Have It Your Way" slogan in a more literal sense and, since its debut in April, it has recorded over 328 million hits from more than 100 countries. For a man dressed as a chicken, this is no mean feat.