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.

Written on July 14th, 2009 , Dev & Test, Tech

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.

Written on June 17th, 2009 , Dev & Test, Tech

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.

Written on April 14th, 2009 , Dev & Test, Tech

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..

Written on February 26th, 2009 , All, Social Software, Tech

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.

Today marks Facebook’s 5th year of allowing us to get more digitally intimate with our friends, as sources across the web have noted (e.g. TechCrunch, ValleyWag, BBC). It has undoubtedly changed the way we interact with each other online, but for me and many others, one of the more resounding effects has been the way it encouraged us to move beyond the years of cultivating quasi-anonymous online personalities that reveal very little about ourselves.

My first taste of the internet came in 1993 when I used it primarily for chatting with others via Internet Relay Chat (IRC). At the time, the thought of revealing my identity to others was inconceivable. The IRC nick name restriction of 9 characters meant that we came up with all manner of short pseudonyms to represent ourselves. Over time one might let drop a detail or two about their “meatspace” existence, but certainly in my case, it was never much.

Because of a lack of trust, because there were sometimes nefarious things going on within these digital communities, because almost no one I knew in real life used the net, and because it was simply the digital norm, people didn’t reveal much about themselves unless it was for professional or academic purposes. Even then, it was common for this digital incarnation of someone to remain separate from the one used for day-to-day and personal net activities. For me, at least, my digital existence was almost entirely separate from my physical one, except for a limited set of personal data I kept online to act as my professional and academic web presence.

In the late 1990′s, web-based message forums were all the rage. These made it much easier to develop relationships with people online, as they allowed for a more media rich social experience than the text-based one of IRC. Still, it was not common for someone to use their real name instead of a dreamt up nick name, but it did become easier to trust people and eventually meet those on a local community forum than it had been previously. User profiles allowed one to indicate superficial data like age and gender. I still went to some effort to disassociate my real-world identity with my digital one, even if I did allow the two to intermingle.

As the 1990′s progressed into the noughties and blogging became more popular, the use of nick names began to diminish. But still, many people avoided revealing too much about themselves on social networks like MySpace. It was still fairly de rigeur to use a clever pseudonym or simply a first name on MySpace rather than your real name.

Not until Facebook arrived on the scene did I totally eschew using pseudonyms for my personal (vs professional) online existence and bother to input a detailed and accurate account of myself. I do remember feeling uncomfortable as I registered with Facebook and wondered if I would later come to regret exposing all this personal data. I haven’t, and in fact I’ve realised what a great joy can come from sharing so much online with my real world friends. Finally, my real world life and digital one are able to overlap in a way that is socially rewarding and fulfilling. Naturally, there comes some danger with opening up too deeply online, but as Facebook offers a plethora of privacy setting I feel pretty much at ease.

And now we are in an era where many new web applications don’t even ask for a nick name upon registration. Mobile, location-aware and proximity-aware technologies will only blur the divide between our digital and physical selves further, and Facebook will have played a key part in getting us there. Thanks FB! Happy Birthday.

Written on February 4th, 2009 , Ruminations, Social Software, Tech

Amazon Web Services has a great tutorial on how to get MySQL up and running on their persistent storage solution, Elastic Block Store. If you did follow this tutorial on a Fedora instance, however, you may have invalidated your MySQL client config and your PHP configuration.

In the case of the MySQL client, you may observe the following error when trying to access MySQL from the command line:

ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/var/lib/mysql/mysql.sock’

The cause is that everything in /var/lib/mysql was moved to /vol/lib/mysql in the tutorial, including the socket for the client to connect to, so this is easily remedied by adding the following to /etc/my.cnf:

[client]
/vol/lib/mysql/mysql.sock

In the case of PHP, you may find that connections can no longer be made to MySQL for the same reason. Simply ensure that the following is set in /etc/php.ini:

mysql.default_socket = /vol/lib/mysql/mysql.sock

Your HTTP daemon will now need to be restarted.

Another option later suggested in the article would involve using symbolic links from the old locations to new ones.

Written on January 28th, 2009 , All, Amazon Web Services, Dev & Test, Tech

In July 2007 Vodafone rolled out its mobile internet service with much fanfare. One of its promises was to deliver mobile content formatted for mobile phones that conserves bandwidth and makes it more appropriate for the smaller screens of mobile devices relative to desktop computers. At that time Vodafone also began offering a reasonably priced flat rate data plan for this service.

Unfortunately the mechanism by which content is formatted for mobile devices presents challenges for mobile developers. Vodafone’s WTE (Web Translation Engine) uses a Novarra transcoder to reformat web pages, downsize & downgrade images, etc. The WTE system does this by intercepting HTTP requests from the mobile device, mangling the HTTP headers of the request and resubmitting the request. When it receives the response, it then performs several transformations on the data, including changing the HTTP headers of the HTTP response and then sends the response back to the mobile device.

Probably the most dire consequence for mobile developers is that the WTE system changes the “User-Agent” header of the request to dupe web servers into thinking that the request is not coming from a mobile device, but a desktop web browser (specifically the Mozilla desktop browser). Sites that have specially formatted their content for mobile devices often depend on the “User-Agent” header to determine whether they should return the mobile format or desktop format of their sites. The system has a few way to circumvent this, by hosting content at specifically formatted domain names or by setting a “Cache-Control: No-Transform” header on the request. These methods are discussed here.

This prevents HTTP responses from being transformed, but what it does not do is prevent HTTP requests from mobile devices being transformed. I’ve found that when I make HTTP requests from a mobile device with certain HTTP headers set for things like security, the WTE system strips these off and submits a request to my web servers without these headers. Naturally, this is frustrating. Vodafone UK are looking into this for me and hopefully I will get an answer soon. One thing they can do is put my domains on a white list so no requests or responses will be transformed at all, but Vodafone UK certainly aren’t the only company using Novarra transcoders and I don’t envy having to submit white list requests to all of them. I’m hoping there is another solution that is not yet publicly documented.

Issues relating to the WTE system are discussed on Betavine in this Betavine forum.

Written on January 16th, 2009 , Dev & Test, Mobile, Tech

Well I’ve been having such a good time back home on the West Coast of North America that I’ve decided to extend my stay by a couple weeks. I was originally due to leave tomorrow but now it’s going to be January 16th, by way of Seattle. The flights are half the price down there of what they are from here in Vancouver!

I’ve got my laptop and other essentials with me and should be to take of everything I need to from here. It’s a lot like working from home in London, but with more space and better views. :-)

Written on January 2nd, 2009 , Travel


I’ve been using my Nokia N95 for about 1.5 years now, and while there is much that I like about it, the camera is just not quite up to snuff. The camera is one of the features I use most in a mobile phone and so I’d decided that now my contract is up, I’d go far a serious camera phone at the cost of perhaps losing some of the smartphone features I’ve come to know and love.

The Sony Ericsson C905 fits the bill. With a brilliant Cybershot 8.1MP camera, it is almost as good quality as the ultracompact Cybershot that I own. The camera is good in low light but does have a propensity for red eye, I’ve found.

As for the rest of the phone, it’s been a bit of a let down. It’s not really a smartphone but more of a feature phone, and it shows. The screen is not huge and the RSS feeds I’ve set up on it take a huge amount of screen real estate. Furthermore, the processing power of the device is not great. J2ME apps take significantly longer to install and load on this device than my old N95. The menuing system is slightly convoluted, moreso than Symbian, with some features being nested deep within a huge number of clicks. And the phone book lookup and predictive text is not nearly as clever as Symbian’s implementation.

In light of all this I’m slightly regretting having picked up this phone, but every time I need to use the camera (i.e. often) it feels somewhat redeemed.

Written on December 2nd, 2008 , Gadgets, Mobile

richardrauser.com is proudly powered by WordPress and the Theme Adventure by Eric Schwarz
Entries (RSS) and Comments (RSS).

richardrauser.com