It seems like every time I turn around I run in to class loading issues when working with Java. Trying to get something as simple as logging working for an application can turn in to a real chore. This is especially true of getting Apache Commons Logging (aka. clogging) to work on WebSphere Application Servier (WAS). Since I haven’t yet found that there was a single, straight forward, step-by-step guide to doing this I decided to write this article.

The Issue

The basic problem with clogging under WAS is that WAS in fact uses clogging for its own purposes under the covers. In doing so they’ve configured it to use their own logging class (the WsJDK14Logger I believe). By default this will dump any clogging activity out to the console and be recorded in the stdout log file. This is far from ideal if you wish to isolate the logging activity for a single application in its own log file.

The Bitter Taste of Defeat

Regarding myself as somewhat of a class loading expert (in a novice kind of way), I somewhat foolishly thought “I know I’ll just dump the log4j.jar file and the commons-logging.jar file into my WEB-INF/lib folder and put a log4j.properties file in my src folder. Then I’ll install the application on the application server and set the module class loader to application first”. Simplicity itself I thought! What could be easier? Bah-bow – WRONG! It crashed and burned in the worst way possible: it gave me nothing. Absolutely bloody nothing. The application just merrily went on its way happily dumping its logging information straight into stdout.

Feeling rather bitter about the resounding defeat I’d just been handed I resolved to see what was out there on the web – which led to even greater despair. This issue is the subject of much confusion and misunderstanding with very few good answers. Luckily I happend to stumble upon this forum thread and an IBM presentation which combined told me approximately what I needed to know.

Seven Steps to Success

In a nutshell this is what you need to do to get this working inside a web project.

1. Import your commons-logging.jar and log4j.jar files into the EAR project in which the module will be bundled. You can do this by right-clicking on the EAR project and selecting Import > J2EE Utility Jar if you’re using RAD or Eclipse. Otherwise you can just copy these JARs directly into your EAR project and it should have the same effect.

2. Create a folder called services inside the META-INF directory of your web project. Inside this folder create a file called org.apache.commons.logging.LogFactory and copy and past the following into the file:

org.apache.commons.logging.impl.Log4jFactory

3. Add both the commons-logging and log4j JAR file to the MANIFEST.MF file located in the META-INF folder of your web project. For example:

Manifest-Version: 1.0
Class-Path: commons-logging.jar
  log4j-1.2.15.jar

4. Next if you’re using RAD open the EAR deployment descriptor and click on the deployment tab at the bottom. Then scroll down to the Applications section at the bottom of the page and change the classloader mode from PARENT_FIRST to PARENT_LAST. Save the file and close it. Note: if you can also do this once the application is installed from the WAS admin console.

5. Now make sure that you have your log4j.properties file configured and available somewhere on the class path inside your web app. Putting it at the root of the src directory is usually your best bet.

6. Install the application and restart the application server.

7. Profit.

Sorry, that last point was a complete waste of time but I needed another one to round out the seven. Anyway there you have it! Commons Logging running blissfully inside a WebSphere web container.

Creating and running GWT projects from the command line isn’t all that hard, but it isn’t all that convenient either if you’re an Eclipse user. If you’ve read my previous post on Integrating Spring with GWT you would have seen that we still had to manually package and deploy the application to the app server before running up the hosted mode browser. This is quite different to a regular Eclipse Dynamic Web Project (part of the Eclipse Web Tools Platform) which allows you to automatically publish your project to the app server.

Creating a GWT module with Cypal Studio

Creating a GWT module with Cypal Studio

Thankfully there is a way to add a GWT facet to Dynamic Web Projects in Eclipse. It comes in the form of a third party plugin from development shop Cypal. Cypal Studio for GWT allows you to hook into your existing GWT SDK and add the GWT facet to your new/existing WTP project. From there you can go on developing your GWT application as you would a regular Dynamic Web Project in Eclipse and add the GWT stuff as you go. IMO this is a fantastic piece of work and really lowers the barrier to entry for developers new to GWT scene but who are already familiar with Eclipse.

To get started download Cypal Studio for GWT here, and then follow the instructions here.

Some might claim that I’m rehashing a topic that has already been solved however I’m compelled to write this article as I personally struggled to connect all the disparate dots in order to make Google Web Toolkit (GWT) integrate with the Spring Framework. This is intended to be the article that I wished I’d stumbled upon in the first 10 minutes of looking for a solution to the problem. Before we start I’d also like to acknowledge that I’ve borrowed heavily from the concepts that people like George Georgovassilis pioneered. There’s nothing really new or groundbreaking here, I’ve simply combined all the knowledge that I’ve gained from all over the place into one convenient guide.

Update: Since publishing this article I’ve been contacted by Richard Bondi with regard to some great work that he’s also done on the matter of which I wish to also acknowledge his fantastic work. If you want to know more on this subject then I heartily recommend you check out his article on how to Integrate Spring with GWT and once you’ve done that, stubbing in hosted mode. Thanks again Richard.

Why would anyone want to integrate Spring and GWT?

If you’re familar with GWT (and I’m assuming you are) you may have marvelled, as I did, with how seamless and uncomplicated client-server interaction is. You are also probably aware that GWT RPC services are not web services. In fact they’re just plain old servlets that are endowed with an ability to serialize and deserialize information across the wire using a rather compact encoding developed by Google.

The RemoteServiceServlet class is great insofar as it handles all the grunt work of the RPC side of things whilst letting you get down to the business of writing your business logic for your services. The fact that you have to extend RemoteServiceServlet raises a few gnarly questions however:

1. What happens if I’ve already got my business logic implemented as an existing Java class with it’s own inheritance heirarchy?

2. What if you want to reuse that same class to implement a SOAP web service or any other RESTful interface for that matter?

3. What if I want to use the service class internally and don’t need all the RPC stuff?

4. What if something better than GWT comes out and I just want to replace the presentation layer technology?

Ouch! Suddenly extending RemoteServiceServlet starts to look a bit painful and far less useful than it did before. Now we could either try to imitate the ostrich and pretend that this isn’t an issue, or we could address the problem head on. We’re going to take the latter option.

Enter Spring

One answer to the above questions is to use a technique called Dependency Injection (DI). The Spring Framework happens to come with quite a good IoC container implementation and has become an industry standard. Without getting into the details about what DI is and how it works, Spring was designed with the intent of making your code as loosely coupled to its dependencies as possible and promoting POJO based development for enterprise applications.

So what does this look like in practice? Well currently out RPC model looks like this:

Standard GWT RPC plumbing

Standard GWT RPC plumbing (image courtesy of Google)

Ideally we want to look more like this:

New and improved GWT RPC plumbing with Spring integration

New and improved GWT RPC plumbing with Spring integration

Not too different really. With the exception of two new classes and two new interfaces you could be forgiven for thinking that I’d hardly done a thing, not to mention that three of them are Spring MVC classes! Well that’s actually the truth of it, I’ve done bugger all. It’s also worth noting that all the work is on the server-side with nothing new for the client.

Going back to our sample code, essentially all we need to do now is wire up our DispatcherServlet (a front-controller) and point it to our new GwtRpcController class for all RPC requests. We’ll also need to break the inheritance chain on the YourServiceImpl (a.k.a. QuoteServiceImpl) class to prove a point.

Getting down to business

In order to illustrate the point, I’m going to walk you through an adaptation of a random quote program from another GWT tutorial originally found on netbeans.org. I’ve adapted the original example to Eclipse as it’s my IDE of choice and I’m using Tomcat 6 as my test server.

For this tutorial you’ll require the following

If you’re impatient like me you might also want access to the project source code which can be found here. Please note that you’ll have to download the dependencies separately as I don’t want to inadvertently infringe on any copyright restrictions.

Okay so maybe I lied a little beforehand, there’s a bit more that we have to do in the way of re-jigging our project structure to make it all hang together and work. Anyway, time to cut some code!

Creating the project

Open the terminal/command line and go to the folder where you’ve unzipped the GWT SDK. And run the following command to create your eclipse project:

./projectCreator -ant gwt-wisdom -eclipse gwt-wisdom -out /home/dave/eclipse/workspace/gwt-wisdom

Note: replace the -out parameter argument with your own project destination. Also I’m using Linux, Windows users should just get rid of the preceeding “./” and change all forward slashes to back slashes and the commands will work just fine.

Now run this command to create your GWT project structure:

./applicationCreator -eclipse gwt-wisdom -out ~/eclipse/workspace/gwt-wisdom org.example.gwtwisdom.client.GwtWisdom

Again replace the -out parameter with the same location you used for the command above

Next import the new application into Eclipse using the File > Import menu option. Choose the Existing Projects option from under the General category and then browse to where ever you output the project files to.At this stage you should be able to hit run and test that the application skeleton is working.

Additional project setup

So that your application will compile once we start adding Spring into the mix add the the Spring framework and Spring Web MVC jars (spring.jar, spring-webmvc.jar) to your applications build path.

Now we need somewhere to put all our configuration files and deployment time dependencies. Create the following directory structure at the base of your project WebContent/WEB-INF/lib. This is almost identical to the Eclipse WTP project structure and will become useful later when we automate the project build with an Ant script.

In the WebContent/WEB-INF folder create a web.xml file an copy and paste the text below into it:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.5"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
        http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <display-name>GWT Wisdom</display-name>

    <!-- Initialise the Spring MVC DispatcherServlet -->
    <servlet>
        <servlet-name>spring</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <!-- Map the DispatcherServlet to only intercept RPC requests -->
    <servlet-mapping>
        <servlet-name>spring</servlet-name>
        <url-pattern>*.rpc</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>GwtWisdom.html</welcome-file>
    </welcome-file-list>

</web-app>

Now I’m aware that the integrated Tomcat instance that comes with GWT has a web.xml file but we can’t actually modify the Tomcat web.xml file as it is dynamically regenerated by the compiler every time we start hosted mode. Hence why we’re creating our own.

If you were paying attention in the last step you would have seen that we defined a servlet in the web.xml file. This is the Spring Web MVC DispatcherServlet which will intercept our RPC requests and route them to the correct service. Each DispatcherServlet instance requires a bean definition file of the same with a “-servlet.xml” suffix. So in the same folder create a file called spring-servlet.xml and copy and paste the following into it:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

    <!-- The application context definition for the DispatcherServlet -->

    <!-- Maps the request through to a concrete controller instance -->
    <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <value>
            /**/quote.rpc=quoteController
            </value>
        </property>
    </bean>

    <!-- GwtRpcController wraps our service in order to decode the incoming -->
    <!-- request then delegates processing of the call to the POJO service -->
    <!-- and then encodes the return value forwarding the response. -->
    <bean id="quoteController" class="org.example.gwtwisdom.server.GwtRpcController">
        <property name="remoteService">
            <bean class="org.example.gwtwisdom.server.QuoteServiceImpl" />
        </property>
    </bean>

</beans>

This will be used to configure the DispatcherServlet to route calls to our services. It does so via the SimpleUrlHandlerMapper which uses regular expression syntax to match the request url to a controller bean ID.

Now you’ll need to add the following jars to the WebContent\WEB-INF\lib folder: commons-logging.jar, gwt-servlet.jar, gwt-user.jar, spring.jar, spring-webmvc.jar. This is necessary for when it comes time to deploy the app.

Creating the RPC quote service

Next we’re going to create our RPC service. Start by creating a subpackage of the *.client package and call it “service”.

Create a new interface called QuoteService and make it look like the code below:

package org.example.gwtwisdom.client.service;

import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;

@RemoteServiceRelativePath("quote.rpc")
public interface QuoteService extends RemoteService {
    public String getQuote();
}

Those already familiar with GWT will know that the next step is to create an async service interface to pair with the QuoteService interface we just created. Create a new interface again in the *.client.service package called QuoteServiceAsync and modify it so it looks like the following:

package org.example.gwtwisdom.client.service;

import com.google.gwt.user.client.rpc.AsyncCallback;

public interface QuoteServiceAsync {
    public void getQuote(AsyncCallback<String> callback);
}

Enough of interfaces. Now it’s time to code up the actual service itself. Create a new package under the org.example.gwtwisdom package called server. Once that’s done create a new class and call it QuoteServiceImpl.

package org.example.gwtwisdom.server;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import org.example.gwtwisdom.client.service.QuoteService;

public class QuoteServiceImpl implements QuoteService {

    private Random randomizer = new Random();
    private static List<String> quotes = new ArrayList<String>();

    static {
        quotes.add("No great thing is created suddenly - Epictetus");
        quotes.add("Well done is better than well said - Ben Franklin");
        quotes.add("No wind favors he who has no destined port - Montaigne");
        quotes.add("Sometimes even to live is an act of courage - Seneca");
        quotes.add("Know thyself - Socrates");
    }

    public String getQuote()
    {
        return quotes.get(randomizer.nextInt(quotes.size()));
    }

}

Now some of you might be saying to yourselves “hey wait a minute, don’t we have to extend RemoteServiceServlet?”. Well read on. I’m about to show you a magic trick straight out of the Gang of Four (GoF) playbook.

To cap it all off before we continue, we should probably update our module configuration file to include our new service mapping. Copy and paste the following into your GwtWisdom.gwt.xml file:

<!-- RPC service servlet declarations                             -->
<servlet path="/quote.rpc"
    class="org.example.gwtwisdom.server.QuoteServiceImpl"/>

All rise for the GwtRpcController

Here’s the fun part, now we’re going to create the GwtRpcController. In the org.example.gwtwisdom.server package create a class called, you guessed it GwtRpcController. Then copy and paste the following code into it:

package org.example.gwtwisdom.server;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.context.ServletContextAware;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException;
import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.SerializationException;
import com.google.gwt.user.server.rpc.RPC;
import com.google.gwt.user.server.rpc.RPCRequest;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

public class GwtRpcController extends RemoteServiceServlet implements
        Controller, ServletContextAware {

    private ServletContext servletContext;

    private RemoteService remoteService;

    private Class remoteServiceClass;

    public ModelAndView handleRequest(HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        super.doPost(request, response);
        return null;
    }

    @Override
    public String processCall(String payload) throws SerializationException {
        try {

            RPCRequest rpcRequest = RPC.decodeRequest(payload,
                    this.remoteServiceClass);

            // delegate work to the spring injected service
            return RPC.invokeAndEncodeResponse(this.remoteService, rpcRequest
                    .getMethod(), rpcRequest.getParameters());
        } catch (IncompatibleRemoteServiceException ex) {
            getServletContext()
                    .log(
                            "An IncompatibleRemoteServiceException was thrown while processing this call.",
                            ex);
            return RPC.encodeResponseForFailure(null, ex);
        }
    }

    @Override
    public ServletContext getServletContext() {
        return servletContext;
    }

    public void setServletContext(ServletContext servletContext) {
        this.servletContext = servletContext;
    }

    public void setRemoteService(RemoteService remoteService) {
        this.remoteService = remoteService;
        this.remoteServiceClass = this.remoteService.getClass();
    }

}

This class works on the principle that it is both a RemoteServiceServlet AND a Spring MVC Controller (don’t you just love polymorphism?) meaning that it can not only be used as a target by the DispatcherServlet for handling incoming RPC requests, but also to decode the incoming RPC requests. Remember I previously mentioned the Gang of Four? Well you’re looking right at the strategy pattern baby. Pretty cool huh?

Upon receiving a request we delegate handling of this to the Controller’s superclass (the RemoteServiceServlet) to handle the unmarshalling of the request. We then intercept the processing of the message by overriding RemoteServiceServlet.processCall method and delegate the processing to the RemoteService POJO.

Where did we get this magical POJO from you ask? Well we injected it into the class via the setRemoteService setter back in the spring-servlet.xml bean definition file earlier.

Okay one last thing before we continue on to preparing the app for deployment. We need to tie all of this together by doing some work to display our quotes in the GWT entry point class and fixing up some of the HTML.

In the GwtWisdom.html file copy and paste the following in below the body tag:

<p>
This is an AJAX application that retrieves a random quote from
the Random Quote service every three seconds. The data is retrieved
and the quote updated without refreshing the page!
</p>

Once you’ve done that, replace the method body of the GwtWisdom classes onModuleLoad method with the following:

    public void onModuleLoad() {
        final Label quoteText = new Label();

        Timer timer = new Timer() {

            public void run() {
                // create an async callback to handle the result:
                AsyncCallback<String> callback = new AsyncCallback<String>() {

                    public void onFailure(Throwable t) {
                        // display error text if we can't get the quote:
                        quoteText.setText("Failed to get a quote");
                    }

                    public void onSuccess(String result) {
                        // display the retrieved quote in the label:
                        quoteText.setText(result);
                    }
                };
                QuoteServiceAsync service = (QuoteServiceAsync) GWT
                        .create(QuoteService.class);
                service.getQuote(callback);
            }
        };

        timer.scheduleRepeating(3000);
        RootPanel.get().add(quoteText);
    }

Note: since this is client-side code be careful that you use the google timer implementation as opposed to the stock Java one otherwise it won’t work like you expect.

That should take care of the display side of things. If you want you can also jazz it up a bit by putting some styles in the GwtWisdom.css file.

Ditching the GWT tomcat server

Remember that earlier on we created our own custom web.xml to initialise the Spring context via a DispatcherServler? Well because of this we can no longer rely upon the integrated tomcat server that comes with GWT to run our app. Fortunately the hosted mode browser comes with a -noserver switch which allows us to configure it to use the server of our choice during development.

There’s a bit of a knack to getting this running all running nice and seamlessly within Eclipse. First we’re going to have to compile the application then package it up and deploy it to the server just this once just so the server has knowledge of your app. Don’t worry, once it’s running in hosted mode the app will use your workspace code, but trust me we need to do this just once.

I’m actually going to use Ant to build and package the app. Conveniently, this is going to work out great in future when I need to bundle the app up into a war file and deploy it elsewhere.

First create a file called build.xml in the root of your project and copy and paste the script below into the build file.

<?xml version="1.0" encoding="utf-8"?>
<project name="gwt-wisdom" default="compile" basedir=".">
    <description>
        Build file. This is used to package up your project as a war, if you
        want to distribute/deploy it. This isn't needed for normal operation.
    </description>

    <property file="build.number"/>

    <!-- GWT properties - change these to suit your distribution (i.e. windows, mac or linux) -->
    <property name="platform" value="linux"/>
    <property name="gwt.home" value="/home/dave/eclipse/lib/gwt/linux/1.5.1"/>

    <!-- Build properties - shouldn't need changing -->
    <property name="name" value="GwtWisdom"/>
    <property name="module" value="org.example.gwtwisdom.GwtWisdom"/>
    <property name="src.dir" value="src"/>
    <property name="web.dir" value="WebContent"/>
    <property name="lib.dir" value="${web.dir}/WEB-INF/lib"/>
    <property name="bin.dir" value="${web.dir}/WEB-INF/classes"/>
    <property name="test.dir" value="test"/>
    <property name="out.dir" value="build"/>
    <property name="dist.dir" value="dist"/>

    <!-- set classpath -->
    <path id="project.class.path">
        <pathelement path="${java.class.path}/"/>
        <pathelement path="${lib.dir}/gwt-user.jar"/>

        <!-- Additional dependencies go here -->
        <pathelement path="${lib.dir}/spring.jar"/>
        <pathelement path="${lib.dir}/spring-webmvc.jar"/>
        <pathelement path="${lib.dir}/commons-logging.jar"/>
    </path>

    <target name="clean">
        <delete file="${dist.dir}/${name}.war"/>
        <!-- Delete the bin directory tree -->
        <delete>
            <fileset dir="${bin.dir}" includes="**/*.class"/>
        </delete>
    </target>

    <target name="compile" description="Compile both client &amp; server code">
        <!-- cross-compile client-side java classes -->
        <mkdir dir="${out.dir}"/>
        <java classname="com.google.gwt.dev.GWTCompiler" dir="${basedir}" fork="true">
            <jvmarg value="-Xmx256M"/>
            <classpath>
                <pathelement path="${java.class.path}"/>
                <pathelement location="${src.dir}"/>
                <pathelement location="${bin.dir}"/>
                <pathelement path="${gwt.home}/gwt-user.jar"/>
                <pathelement path="${gwt.home}/gwt-dev-${platform}.jar"/>
            </classpath>
            <arg line="-out ${basedir}/${out.dir}"/>
            <arg value="%*"/>
            <arg value="${module}"/>
        </java>
        <copy todir="${web.dir}">
            <fileset dir="${out.dir}/${module}"/>
        </copy>

        <!-- compile server-side java classes -->
        <mkdir dir="${web.dir}/WEB-INF/classes"/>
        <javac srcdir="${src.dir}:${test.dir}" destdir="${bin.dir}" includes="**" debug="on" debuglevel="lines,vars,source" source="1.5">
            <classpath refid="project.class.path"/>
        </javac>
    </target>

    <target name="package" depends="compile" description="Package up the project as a war">
        <mkdir dir="${dist.dir}"/>
        <war destfile="${dist.dir}/${name}.war" webxml="${web.dir}/WEB-INF/web.xml">
            <fileset dir="${out.dir}/${module}">
                <include name="**/*.*"/>
            </fileset>
            <fileset dir="${web.dir}">
                <include name="**/*.*"/>
                <exclude name="WEB-INF/web.xml"/>
            </fileset>
        </war>
    </target>

    <target name="all" depends="package"/>

</project>

Run the build script using the package target (Alt+Shift+X then Q). Alternatively if you’re using Ant from the command line then running “ant package” from the project directory should do the trick. This should compile and package the app automatically for you into a war file.

If the build fails for any reason you might have to edit some of the property elements listed at the top of the file depending on your platform (windows, mac or linux) and where you unzipped your GWT libs. Just change these as appropriate and everything should work fine.

From here you can just go ahead and fire up Tomcat and deploy the war file onto the app server either via the admin console or the autodeploy directory. At this point you should be able to test your application by opening your web browser and navigating to http://localhost:8080/GwtWisdom/GwtWisdom.html. If this works then we’re all good to proceed to the next stage.

Getting hosted mode to run with -noserver

Okay we’re getting close now. This step isn’t essential really, what I’ve shown you so far should be more than enough to demonstrate the application in action. If however you want to continue debugging and testing your app in hosted mode for development like I do then read on.

We’re going to need to edit the launch configuration in order to run the app in hosted mode using our own Tomcat instance as opposed to the integrated Tomcat server. You can do this one of two ways, either edit the GwtWisdom.launch file directly or you edit them via the Eclipse run configuration manager. We’re going to do it via the run configuration manager.

You can open the manager by right-clicking on the project Run As > Run Configurations. Once there, you should see in the left-hand tree view under Java Applications the GwtWisdom launch configuration. Select it and then click the Arguments tab over on the right hand side. Check that the program arguments resemble those below. Your configuration may differ slightly as far as the port is concerned but should read something like:

-out www GwtWisdom/GwtWisdom.html
-noserver
-port 8080

This configuration tells the hosted mode browser to use an external server on the given port and where it should find your applications home page on the server.

You might also have to add the contents of your WebContent/WEB-INF/lib folder to the classpath tab in order to get it working but try it first by clicking apply and then run.

Sweet sweet success!

All that’s left to do is run the project. If you’ve configured it correctly it should fire up the app in all its hosted glory. Your services are now free from the tyranny of RemoteServiceServlet!

Now if only we could figure out a way to remove the dependency on the QuoteService interface from the service. Then it really would be a bona-fide POJO…another day, another challenge.

The Wisdom of Juan

August 21, 2008

Over the past few weeks I’ve been blessed with the opportunity to work with an awesome guy by the name of Juan Ruiz of Hyro. He’s an exceedingly wise man and has taught me a lot about his trade as a user experience architect. Amongst the many gems that he’s enlightened me with lately, 3 in particular have stood out:

#1

“When presenting/unveiling new designs for review never create an atmosphere that suggests the design is final. Make a point that it is unfinished and invite suggestion. This way rather than criticise, your audience is more likely to buy in and take ownership of the design and thus aid in improving it”

#2

“When taking notes in a meeting always confine them to or collate them into a single list. This way you can succinctly wrap up the meeting with a clear summary of what was discussed and perform a final check that everyone is clear on any decisions made. It also has the added bonus of making the people in the room feel like they were truly heard.”

#3

“You can more easily convince a person of your argument and debunk theirs through the asking of questions rather than simply stating your point of view. Questions have the ability to expose the holes in ones arguments without mounting a direct assault upon the person. Carefully chosen questions will allow the opposing party to convince themselves of the soundness of your own position without causing them to lose face. Furthermore, a person convinced of themselves will thereafter champion your cause their own, as you have created the illusion that they arrived at that conclusion of their own violition.”

    For some time now I’ve been looking for a RSS feed reader that suits me. I’ve tried a couple out there; Blog Bridge, firefox and IE’s inbuilt feed reader, Feed Demon, Yahoo Mail. I’ve even built my own in Adobe AIR porting an old Ext JS example across and tweaking it. Still I’m not happy.

    The problem is that they all seem to do a part of what I want, but none of them seems to do everything all in one place. If I had to lay out the criteria of what I want in a feed reader it would look something like this:

    1. Cross-platform

      I use Linux at home so this is an absolute must. I’ve been pretty impressed by Feed Demon but it’s not available for Linux.

    2. Work online and offline

      I often wish I could read my feeds on the bus or somewhere else where I don’t have connectivity.

    3. Notify me when new posts are available

      I absolutely loath having to log in every time, or open the application to check my stuff. I want timely delivery of information dammit!

    4. Keep track of read and unread posts

      Sounds simple but you’d be surprised how many don’t offer this.

    5. Allow me to organise my post into some logical structure

      Again, simple but loads of readers out there are really inflexible when it comes to managing your feeds.

    6. Provide some sort of stats on what I tend to read and what I dont seem all that interested in

      This is great as it allows me to recognise when I need to prune my feeds and tidy up, or conversely when I’ve been neglecting things I really should be in the know about.

    7. Provide some sort of distributed subscription model

      To clarify, I don’t want to have to maintain two lists of subscriptions; one on my laptop and one on my workstation. This is where most of the desktop readers fall down (bar Feed Demon which uses the News Gator subscription service).

    Fussy I know. But a man wants what he wants and well that’s the way it is right?

    Anyway Feed Demon was mightly close. It had many of the features I’m after but a few critical shortcomings. So I continued my search. Recently I’ve been having a bit of a play with Google Reader and I have to say that I’m impressed.

    Looks can be deceiving, and this is definitely the case with Google Reader. When I first looked at it I thought it was rather plain and uninteresting, but once I started digging a bit deeper and getting the hang of it I found that it offers nearly everything I want and more besides. The only thing lacking is the notifications bit (MSN style desktop popups and such), but I’ve got a google widget on my iGoogle page that keeps me up to date quite nicely. If anything it’s nice to not have the distraction like Feed Demon whirring away.

    The best feature by far IMO is the Google Gears integration that allows me to view my feeds offline. All you need to do is click a button and it will sync your feeds with the Gears DB and viola! Your feeds are available whenever you are.

    Check it out if you’re interested: http://www.google.com/reader/

    The weirdest thing happened tonight. I was just cruising along minding my own business when Ubuntu or Compiz or whatever just suddenly decided that I no longer required title bars on my windows. They were there one second, and gone the next. All my windows were still open, I just couldn’t drag them anywhere, minimize, maximise or close them. Kind of a big deal.

    Being rather put out about this new development I immediately set about trying to find a cure. Here’s how I fixed it:

    1. Turn off extra visual effects in the System -> Appearance -> Visual Effects [tab]
    2. Turn visual effects back on
    3. Open a terminal session
    4. Run emerald –replace

    I can only imagine that something went drastically wrong with Compiz because after doing that, everything is back to normal. Other than that little hiccup I have to say I’m still not missing Windows.

    Python is something that I’ve been looking into lately, mainly because I use Jython a lot at work in administering our Websphere Application Servers (their admin shell makes extensive use of it). More recently though I’ve been thinking that maybe I should be looking more seriously at it. It wasn’t that long ago that Google released their App Engine which currently only runs Python apps. This is really exciting stuff for anyone interested in cloud computing.

    Anyway in my travels I stumbled upon what is possibly the smallest application server implementation I’ve seen in my life, written by Pierre Quentel. Admittedly it’s pretty limited in functionality, but I thought it was quite a nice demonstration by Pierre of the power of Python as a language and the breadth and depth of the standard libraries. Amazingly it even handles sessions!

    You can check out the full post at: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/392879

    I’d be interested to see if anyone has come across anything smaller, that demonstrates the relative ease and elegance of implementation in one language versus another (I’m sure that some of your Perl guys have something amazing up your sleeves).

    Follow

    Get every new post delivered to your Inbox.