Archive for the ‘Tech’ Category

The Top 5 Things I Miss About Firefox in Chrome

Tuesday, February 23rd, 2010

I recently switched to Chrome as my primary web browser because I was becoming increasingly frustrated with how resource hungry Firefox is. FF would regularly consume more than 1GB of RAM and problems with one web page would occassionally take out the entire browser. Chrome’s unique process model ensures that this never happens, and it consumes considerably less RAM than Firefox.

chrome-v-firefox-002

That said, Chrome is feature-poor when compared to FF and it is not without its flaws. And so here I present a list of the things I miss most about Firefox:

  1. A wide selection of extensions/plugins. I rely heavily on Firefox plugins like FireBug, HttpFox, ElasticFox and S3Organiser for debugging websites and managing resources in the cloud. Chrome only introduced extensions at the end of last year and currently there are not many available, though thankfully this will change over time.
  2. RSS support. Chrome simply isn’t there yet. I was a bit surprised to learn that Chrome does not have a feature for auto-detecting and subscribing to RSS feeds, nor does it even display RSS content in an easily digestible format. It’s funny to think that Firefox is better integrated with Google Reader than Google’s own Chrome.
  3. A design consistent with Windows / manageable toolbars. Google has applied their own unchangeable design ethos to Chrome that is a departure from the typical Windows app. For one, tabs are where the title bar normally appears and there is no menu bar in Chrome. I can understand why Google did this, wanting to maximise space and put the most important information at the top, but I think this lack of consistency with other Windows apps makes Chrome appear a little cludgy and can lead to momentary confusion when working at rapid speed, switching through windows quickly. Ultimately, it would be nice to be able to customise the top-most toolbar area as you can with other browsers.
  4. Windows that size correctly. I’ve tried various fixes for this with no success under Windows 7. For the life of me I cannot get Chrome to open a new window in a maximised state after the initial start of Chrome. Instead, new windows after the first open at a greatly reduced width which results in me having to maximise them myself before any serious browsing.
  5. Comprehensive bookmark support. I am a serial bookmarker. I bookmark hundreds of web pages each month and thus require a fairly extensive system for managing them that consists of organising them into folders, tagging them and adding descriptions. Unfortunately Chrome at this point only allows you to organise bookmarks into folders, and this is going to make them difficult for me to recall in future. Particularly, I need tags so that I can apply more than one nested dimension of categorisation to my bookmarks. It would also help if Chrome’s Bookmark Manager had more sortable columns of data for bookmarks like FF does.

Firefox is clearly a much more mature browser and Chrome has a fair bit of catching up to do in terms of feature support, but Google is no doubt hard at work trying to pick up the slack. In the mean time, Chrome does perform infinitely better than FF and that is enough for me to continue to use it as my primary browser.

Why Google wins even when its search fails

Wednesday, February 3rd, 2010

W3 AR3 T3H GOOGLE BORG. W3 PWNZ J00.

For some time now I’ve been comparing my usual search queries using this Google vs Bing tool, and the frank truth is that for a lot of the things that I search for, Bing gives me more accurate results that are more relevant to me than Google. This is likely only to improve when Wolfram Alpha is incorporated into Bing, but even now I can’t deny that Bing is the best default search engine for many of my queries.

But I haven’t switched, and I won’t. Google is still my default home page in every browser I use. There’s one simple reason for it– my online behaviours have become so enmeshed with Google that any sort of divorce is quite simply not an option. So what serves as the ball-and-chain? iGoogle and Google Apps, which have become products that drive me continually back to Google’s economic engine: Search.

Many years ago I began using Google Apps as a matter of curiosity and convenience. It started with Gmail, and some time later followed with Google Reader, Google Maps, Google Calendar, and Google Docs. Now I have become so dependent on all of them that they effectively act as an impetus to continue to use good old iGoogle as my home page, even if better search results are out there to be had. Giving up easy and immediate access to my all-important iGoogle + Google Gadget-based Apps dashboard is simply unfathomable. The plain truth is that I am no longer simply a regular user of Google Search but rather a hooked user of the Google Platform, of which Search is only a part, and for me to give up my dependency on the platform would be a huge task.

The introduction of social features into Google products only tightened their grip on me. With the arrival of Google Talk/Chat in 2005 I was suddenly able to interact with my Gmail contacts in the immediate form of instant messages. Google almost overnight took on characteristics of a social network, and I found myself with yet another compelling reason to have Gmail and hence Google itself open on my desktop at all times. Even the fact that Google Talk uses open protocols and that I could use any XMPP client with it is not enough to dissuade me. And midway through last year Google introduced social features into Reader. The nefarious Google Grip tightened fruther. Social features tend to make products especially sticky for the simple reason that everyone wants to be where their friends are, and the cost of switching tends to be high (e.g. building up a whole new network of contacts in a new product).

Two things are set to draw my relationship with Google even closer. One is the emergence of Android. I have avoided adopting an Android handset for the same reason that I have shunned the iPhone: poor feature set. But this is set to change this year. Android will finally see handsets with good quality cameras, zippy processors and all the other high-end features we’ve come to expect. And because of Android’s fantastic integration with Google apps, these new devices will only serve to further the Google platform’s importance and dominance.

picardchromeborgThe other, of course, is the coming of Chrome OS. As Google Apps already acts as a sort of social and professional productivity platform, an operating system that supports and increasingly intregrates the products of the platform makes perfect sense, and yet will further indenture us to Google. Then, like the hive mind stretching its tentacles into the consciousnesses of all its Borg followers, so too will Google’s reach extend out to all of us via our mobile and desktop operating systems, with Search at its core.

So even if Google Search isn’t the stand-out it once was, ultimately Google and me look set to be partners for the longhaul. iGoogle & Google Apps have effectively bound me to using Google Search. Google’s operating systems will cement this relationship further. If Bing could match the ease and convenience of iGoogle + Google Apps with similar products, then they’d still have the enormous barriers of social software change to overcome. You’re fighting a tough battle, Microsoft.

PHP vs Java for Webapps- Quality & Maintainability of Code

Monday, January 18th, 2010

Whenever I revert to coding in PHP after an extended sprint in Java, I inevitably find myself somewhat frustrated by some of the shortcomings of PHP. Most of these have to do with how much less maintainable a large code-base becomes in PHP as opposed to Java. Recently, I wanted to quickly whip up a few webapps and decided to try working with the Symony PHP framework to see how quickly I could generate a webapp compared to using Struts 2 in Java.

java-v-php

I found Symfony to be a very effective and well-thought out framework. It was easy to learn and yes, it was not long before I had a functional web app online.

My issues are not with Symfony, but with PHP itself. First off is the plethora of static functions that PHP has on offer. Most of these would be encapsulated as methods of objects in Java (for instance instead of string.equals(otherString) in Java one would use in PHP the static method str_cmp(string, otherString)). This lack of encapsulation and the huge number of global methods makes for a very messy and expansive domain in which to work. Ultimately, I suppose this is a vestige of PHP’s procedural roots.

The lack of namespaces is another gripe, which further adds to the murky domain space of a PHP project. It’s not easy to see how objects relate to each other in terms of an organisational hierarchy in PHP, whereas this is a necessity in Java.

I also find awkward that in PHP you are in the postion of having to import files in order to gain additional functionality rather than importing classes. While technically these two things might not be so different, conceptually they are. An imported file can have functions and variables defined with no association to an object that effectively become global in scope on import. Static classes can have the same effect in Java, but I think most Java programmers have by now learned to avoid using static objects altogether. The default behavior in Java is to use instances of classes whereas in PHP the default behaviour for many still seems to be to use collections of functions and function libraries.

I also find that PHP feels really quite verbose. All my PHP templates look rather ugly with echo statements littered everywhere. It’s not nearly as elegant as Freemarker.

With all other factors such as scalability, support, and resilience aside, I think PHP works great for small- to mid-sized web apps where maintainability of the code base is not a top priority. But for large, complex, long-life webapps, It seems to me that using a Java framework may be more appropriate in no small part because the quality and maintainability of the code will be considerably higher. This is not to say that you can’t create quality, maintainable apps in PHP, but that it is easier and more natural to do so in Java, where types are static, code encapsulation is paramount, and namespaces rule the roost.

The Google Effect

Friday, December 4th, 2009

falling_share_price
It’s amazing how Google’s product announcements can instantaneously shake up the landscape of a market. When Google announced Google Maps Navigation at the end of October, the share prices of Garmin and TomTom crashed by 16% and 21% respectively. And since then they’ve only gotten worse.

Just yesterday, Google did it again by announcing high-level details of a new property service to be integrated into Google Maps. This would allow estate agents and private individuals to list properties for free, while companies like Rightmove continue to charge agents hundreds of pounds a month in fees. Furthermore, most of these services are closed to private home sellers. Needless to say, Rightmove’s share price tumbled 10% yesterday.

So what’s Google’s next target? It’s probably an industry you don’t want to be in.

Log4j + Multiple Web Apps + Common Lib Logging

Wednesday, September 2nd, 2009

I’m currently running several web apps from one Tomcat instance and they share several libraries that require log4j logging, Sitemesh, for instance. For this reason, I removed log4j.jar from each of my webapp’s “lib” folders and placed it instead in “${catalina.home}/lib” (note that I’m using Tomcat 6. This would be “${catalina.home}/common/lib” in earlier Tomcat versions)

I didn’t realise that this would create a a myriad of problems. What I found was that in my test environment, logging for all webapps ended up going to the log file for one particular webapp, while in my staging environment logging for all webapps went to the log file for a totally different webapp.

It took some time, but ultimately I got to the bottom of it. Apparently log4j does not play nice when the same log4j.jar is being used by multiple webapps. Configuring the rootLogger for one webapp appears to overwrite rootLogger settings for another webapp if log4j.jar is shared. Since each of my webapps was configuring the rootLogger to append to a different particular file, this meant that all logging ended up in only one file.

To circumvent the issue, log4j.jar must be place in each individual webapp’s “lib” folder in addition to Tomcat’s common library folder. Additionally, your web apps must be configured to use their own class loaders before using the parent class loader. This was my stumbling block. Your Tomcat context containers need to be set up something like:

<Context>
     <loader delegate=“false”/>
</Context>

If delegate is set to true then each webapp loads the common log4j.jar in favour of its own log4j.jar, giving rise to the problem.

Struts 2 + Sitemesh + FreeMarker + Multiple Web Apps

Tuesday, July 14th, 2009

Matt Raible has a post here discussing how to use Sitemesh to decorate multiple webapps. When applying this to various Struts 2 webapps that use Freemarker, I found the process required a little further fine tuning. I’ve outlined the steps I’ve taken to get this working here.

One key issue to keep in mind is that the struts 2 sitemesh filter that comes with Struts 2 cannot refer to decorators in other webapps. This isn’t documented anywhere and certainly tripped me up.

  1. Configure a web app to host the decorators. This should have a web.xml that includes something like the following:
    <filter>
        <filter-name>sitemesh</filter-name>
        <filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>sitemesh</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping>
           
    <servlet>
        <servlet-name>sitemesh-freemarker</servlet-name>
        <servlet-class>com.opensymphony.module.sitemesh.freemarker.FreemarkerDecoratorServlet</servlet-class>
            <init-param>
                    <param-name>TemplatePath</param-name>
                    <param-value>/</param-value>
            </init-param>
            <init-param>
                    <param-name>default_encoding</param-name>
                    <param-value>ISO-8859-1</param-value>
            </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
           
    <servlet-mapping>
        <servlet-name>sitemesh-freemarker</servlet-name>
        <url-pattern>*.ftl</url-pattern>
    </servlet-mapping>

    Note that this webapp is thus set up basically just to use Freemarker and Sitemesh together as outlined here.

  2. Struts 2 web apps that will use the shared decorators in some other webapp must NOT use the struts2-sitemesh PageFilter that comes with Struts 2, but instead use the PageFilter that comes with the regular sitemesh distribution:
  3. <filter>
        <filter-name>sitemesh</filter-name>
        <filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class>
    </filter>
    <filter-name>sitemesh</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping>
  4. Struts 2 web apps point to decorators in the host webapp, as outlined in MR’s post:
    <decorators>
        <excludes>
            <pattern>/styles/*</pattern>
            <pattern>/scripts/*</pattern>
            <pattern>/images/*</pattern>
            <pattern>/index.html</pattern>
            <pattern>/admBase/*</pattern>
            <pattern>/jforum.page?module=admBase*</pattern>
        </excludes>
     
        <!– load decorator from a different web-app deployed in the server –>
        <decorator name=“layout” webapp=“yourWebApp” page=“/WEB-INF/decorators/YourDecorator.ftl”>
            <pattern>/*</pattern>
        </decorator>

    </decorators>

  5. crossContext must be set to true for all your webapps. (Your context elements will no doubt look considerably different, especially if you’re loading webapps from server.xml rather than individual context files)
  6. <Context reloadable=“false” crossContext=“true”>
            <Loader delegate=“true”/>
    </Context>

    And you should be good to go.

Spring + Struts 2: “Unable to Intantiate Action!”

Wednesday, June 17th, 2009

I’ve been using Spring with Struts 2 for some time now– I love how it saves me from worrying about object creation and makes my code so much more testable. One recent problem I’ve encountered, though, has led to a bit of a “gotcha” that I hadn’t foreseen.

In general, I’m autowiring my Struts 2 actions by type so that I don’t have to configure beans for actions within my Spring applicationContext.xml. I tried doing this for an action that had two dependencies that I wanted to pass in through the constructor:

public UsersAction (IDeviceService deviceService, IFacebookFacade fbFacade) {
        this.deviceService = deviceService;
        this.fbFacade = fbFacade;
}

Upon executing the action I encountered the following cryptic exception (note spelling mistake):

javax.servlet.ServletException: Unable to intantiate Action! - action

Not terribly informative. Unfortunately Google searches yielded nothing despite that unique, improperly spelled exception message. I soon learned that any action where I wanted to pass in an IFacebookFacade suffered the same fate. After much investigation I discovered the source of my error: I had another bean defined for a class that was a subclass of an IFacebookFacade implementation in my applicationContext.xml. Thus, Spring found two objects that corresponded to the same interface and wasn’t sure how to autowire by type. It would be helpful if the error message was a little more informative..

Anyhow, the solution I used was to pass the fbFacade into UsersAction by setter injection:

public UsersAction (IDeviceService deviceService) {
        this.deviceService = deviceService;
}

public void setFbFacade(IFacebookFacade fbFacade) {
        this.fbFacade = fbFacade;
}

This way, Spring will autowire by name and look for a bean with the same name as the property addressed by the setter. Job done.

Note that you could also resolve this issue by explicity defining a bean for the action in applicationContext.xml, but it is recommended to use declarative ways of specifying dependencies so as to minimise the amount of config in your applicationContext.xml. See this link for more info.

Tomcat Container Managed Security- What a Pain

Tuesday, April 14th, 2009

For a number of reasons, some time ago I decided to move away from using a programmatic authorization solution in a Struts 2 web app towards using Tomcat Container Managed Security (CMA). I now regret that decision as it’s caused me all sorts of issues. The three things that bother most, though, are the following:

  1. When logging in directly from the login page without first requesting a protected resource, Tomcat throws up an error. Tomcat CMA mandates that you navigate directly to a protected resource before logging in, in which case it will display the login page instead. This seems awkward and is not the case with other servlet containers like JBoss.
  2. I can’t specify a Struts 2 action as the login page. This means I have to have a separate JSP that contains all the relevant login markup, which is inconsistent with the use of the framework everywhere else in the application.
  3. As far as I can tell, CMA does not play nice with my configuration of Sitemesh, Freemarker and Struts 2 across multiple webapps. I wasn’t able to get to the root cause of the problem. I have multiple webapps, some Struts 2, some not, that all use Freemarker and use the same Sitemesh decorators. The CMA login page would not display correctly for some of these.

Ultimately item 3 was the straw that broke the camel’s back. I’ve since moved to Spring Security, which I’ve found easy to configure and resolved all of the issues listed above.

Facebook Hosting Scam Adverts

Thursday, February 26th, 2009

facebookscam

Recognize adverts from Facebook like the one at right? The Sydney Morning Herald reported earlier today that they are in fact a scam. Victims are first asked to pay $1.95 shipping for information on how to earn thousands monthly or weekly while working for Google, and are later charged much more than this. Facebook claims to have eliminated all such ads, but they clearly haven’t as I captured this one just 10 minutes ago. That Lamborghini may prove to be as elusive as you first imagined..

Thoughts on GSMA Mobile World Congress

Friday, February 20th, 2009

I’ve been following events at the MWC over the past several days and it shaped up to be a fairly interesting conference. Here I’ve summarised my thoughts on some topics of interest:

  • Mobile broadband, as ever, is a hot topic. The promise of high-speed data over 3G has floundered a bit given that there can still be fairly high latency even if transfer speeds are reasonable (though I can’t say I’ve ever achieved even close to the 3.6MBit promised by Three anywhere in London on Three’s HSDPA network). The 4G networks due to roll out in 2012 that promise bit rates in the 1 GBit/sec (!) range certainly capture interest, particularly LTE Advanced, which seems to be the front-running contender for adoption by carriers.
  • Green issues are being talked up quite a lot. Apparently a year of average mobile phone use generates 25kg of greenhouse gases.
  • Mobile advertising is on everyone’s agenda, given that conversion rates are in the 7% - 12% range vs the pitiful rates offered by internet advertising.
  • Product announcements were a bit lackluster. We have a new touchscreen Android phone, the HTC Magic from Vodafone, a new 12MP shooter from Sony Ericsson (which will run Symbian, thankfully), Nokia’s first 8MP shooter, the N86, and two new handsets from HTC: the Touch Pro 2 and TouchDiamond 2
  • The INQ1 won best mobile handset, largely on the back of their deep integration with Facebook and other social software. It certainly wasn’t the mid-tier hardware.
  • Verizon was demo’ing it’s new Novarra content adaptation system. I’m a little disappointed to see that the biggest carrier in the US is now using Novarra transcoders because they do pose real difficulties for mobile development, as I’ve blogged about previously
  • Attendance numbers were down around 15%, from 55,000 in 2008 to 47,000 this year.